# Data Plane Resilience

API7 Gateway data plane nodes cache configuration in memory and can continue processing traffic during brief control plane (CP) outages. However, for extended outages, such as a database failure, control plane upgrade, or disaster recovery scenario, nodes that restart without a CP connection cannot load configuration.

Use this guide after you have already planned for scaling and high availability of traffic-serving nodes:

* [Scale Data Plane](https://docs.api7.ai/api7-gateway/configure-and-manage/scale-data-plane.md) covers capacity growth.
* [Data Plane High Availability](https://docs.api7.ai/api7-gateway/configure-and-manage/high-availability-data-plane.md) covers multi-node deployments, load balancers, and health checks.

**Fallback CP** stores gateway configuration in AWS S3, S3-compatible storage, or Azure Blob Storage. During an outage, restart or redeploy a traffic node in fallback read mode so it uses the stored snapshot as its configuration source.

Fallback CP does not switch a running node automatically when its control-plane connection fails. A node that remains running continues with its in-memory configuration. Use fallback read mode when a node must start while the control plane is unavailable, and restore its original deployment configuration after the control plane recovers.

## How It Works[​](#how-it-works "Direct link to How It Works")

Fallback CP snapshots can be produced by either a **backup gateway node** or the scheduled **Control Plane pusher**. The backup gateway runs alongside your traffic-handling nodes but does not serve API traffic. Its sole purpose is to receive configuration from the control plane and export it to external storage on a schedule. The following diagram shows this option.

### Normal Operation[​](#normal-operation "Direct link to Normal Operation")

During normal operation, every data plane node, including the backup node, watches the control plane's etcd-compatible API on mTLS port `7943`. See [Architecture](https://docs.api7.ai/api7-gateway/key-concepts/architecture.md) for details on the pull/watch model. The backup node also writes the configuration it receives to external storage on a schedule.

<!-- -->

### Fallback Operation[​](#fallback-operation "Direct link to Fallback Operation")

When the control plane is unavailable, an operator redeploys or restarts a traffic node in fallback read mode. At startup, the node loads the resource and data plane configuration objects for its gateway-group short ID from external storage.

<!-- -->

### What Gets Exported[​](#what-gets-exported "Direct link to What Gets Exported")

The backup node or Control Plane pusher exports two categories of data per gateway group:

| Category          | Contents                                                                                                                                                                               |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Resource data** | Routes, services, upstreams, consumers, credentials, SSL certificates, global rules, plugin metadata, plugin configs, stream routes, secrets, custom plugins, and protobuf definitions |
| **Config data**   | Data plane configuration including keyring and service discovery settings                                                                                                              |

Each gateway group's data is stored as a separate object, keyed by the gateway group's short ID. Recovery nodes must use the same `API7_GATEWAY_GROUP_SHORT_ID` as the snapshot they load.

info

The chart still creates a gateway Service and publishes its configured ports for a backup release. However, the gateway recognizes write mode at startup and omits its HTTP/HTTPS and stream traffic server blocks. Keep the backup Service out of load balancers, Ingress routes, DNS records, and client configuration. The backup node is not counted toward the license quota.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

* A running API7 Gateway deployment with at least one gateway group.

* An external storage backend:

  <!-- -->

  * **AWS S3 or S3-compatible storage**: Two buckets (one for resource data, one for config data) with appropriate access permissions. For another S3-compatible service, prepare the custom endpoint URL.
  * **Azure Blob Storage**: Two Blob containers (one for resource data, one for config data) with appropriate access credentials.

### AWS S3 Permissions[​](#aws-s3-permissions "Direct link to AWS S3 Permissions")

The IAM policy for a backup node or Dashboard pusher must include:

```
{

  "Version": "2012-10-17",

  "Statement": [

    {

      "Effect": "Allow",

      "Action": ["s3:PutObject"],

      "Resource": [

        "arn:aws:s3:::fallback-cp-data/*",

        "arn:aws:s3:::fallback-cp-config/*"

      ]

    }

  ]

}
```

Traffic nodes in fallback mode need `s3:GetObject` on the same buckets.

For S3-compatible storage, grant equivalent object read/write permissions in your storage provider.

### Azure Blob Storage Permissions[​](#azure-blob-storage-permissions "Direct link to Azure Blob Storage Permissions")

Grant `Storage Blob Data Contributor` on both containers to a backup gateway that uses Workload Identity. A recovery identity only needs `Storage Blob Data Reader`. The Control Plane pusher requires a storage account access key; an account access key authorizes access directly and is not assigned an Azure RBAC role.

### Static Credentials[​](#static-credentials "Direct link to Static Credentials")

The Kubernetes static-key examples expect an existing Secret named `fallback-storage-credentials` in every namespace that contains a backup gateway, recovery gateway, or Dashboard pusher that consumes it.

| Provider           | Required Secret keys                         |
| ------------------ | -------------------------------------------- |
| AWS S3             | `aws-access-key-id`, `aws-secret-access-key` |
| Azure Blob Storage | `azure-storage-account-key`                  |

Create and populate this Secret through your approved secret-management workflow before installing or upgrading a release. Kubernetes Secrets are namespace-scoped, so create the Secret separately when gateway and control-plane releases use different namespaces. The Docker examples expect the equivalent `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, or `AZURE_STORAGE_ACCOUNT_KEY` variables to contain non-empty values in the host environment or secret-injection system before the container starts.

## Configure the Backup Node[​](#configure-the-backup-node "Direct link to Configure the Backup Node")

The backup node is a gateway instance configured with `mode: write` under `fallback_cp`. It connects to the control plane like a regular data plane node but writes configuration to external storage instead of serving traffic.

* Kubernetes (Helm)
* Docker

Deploy one backup node per gateway group as a separate Helm release. Start with the values generated by the Dashboard for that gateway group. This preserves its DP Manager endpoints, mTLS Secret, gateway-group environment variable, image, and other connection settings. Add the fallback values below to that complete values file.

The chart reads fallback settings from the top-level `deployment.fallback_cp` value. In `write` mode, it keeps the DP Manager connection and renders `node_listen`, container ports, and gateway Service ports. It disables readiness and liveness probes and HTTP and stream access logs. At startup, the gateway reports itself as a backup node and omits the NGINX traffic server blocks. Keep the published gateway Service out of traffic paths so the release remains explicitly isolated.

* AWS S3
* Azure Blob Storage

**Using IAM Roles for Service Accounts (IRSA)**:

backup-node-values.yaml

```
apisix:

  kind: Deployment

  replicaCount: 1



deployment:

  fallback_cp:

    interval: 60

    mode: write

    aws_s3:

      region: "us-east-1"

      resource_bucket: "fallback-cp-data"

      config_bucket: "fallback-cp-config"



serviceAccount:

  create: true

  annotations:

    eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/fallback-cp-role"
```

❶ The interval (in seconds) between configuration exports.<br /><!-- -->❷ `write` mode enables storage export. The chart retains port declarations, while the gateway omits its traffic server blocks.<br />❸ The AWS region where the S3 buckets are located.<br /><!-- -->❹ ❺ Separate buckets for resource data and configuration data.

**Using IAM Access Keys**:

Keep the Dashboard-generated `apisix.extraEnvVars` entries and append the storage credentials to that list. The complete list must retain `API7_GATEWAY_GROUP_SHORT_ID` and any other generated entries:

backup-node-values.yaml

```
apisix:

  kind: Deployment

  replicaCount: 1

  extraEnvVars:

    - name: API7_GATEWAY_GROUP_SHORT_ID

      value: "YOUR_GATEWAY_GROUP_SHORT_ID"

    - name: AWS_ACCESS_KEY_ID

      valueFrom:

        secretKeyRef:

          name: fallback-storage-credentials

          key: aws-access-key-id

    - name: AWS_SECRET_ACCESS_KEY

      valueFrom:

        secretKeyRef:

          name: fallback-storage-credentials

          key: aws-secret-access-key



deployment:

  fallback_cp:

    interval: 60

    mode: write

    aws_s3:

      access_key: '${{AWS_ACCESS_KEY_ID}}'

      secret_key: '${{AWS_SECRET_ACCESS_KEY}}'

      region: "us-east-1"

      resource_bucket: "fallback-cp-data"

      config_bucket: "fallback-cp-config"
```

For S3-compatible storage, use the provider's access key and secret key, and add `endpoint` to the `aws_s3` block:

```
deployment:

  fallback_cp:

    aws_s3:

      endpoint: "https://s3-compatible.example.com"

      use_path_style: true
```

Enable `use_path_style` only when the storage provider requires path-style bucket URLs.

**Using Workload Identity**:

backup-node-values.yaml

```
serviceAccount:

  create: true

  annotations:

    azure.workload.identity/client-id: "<your-managed-identity-client-id>"



apisix:

  kind: Deployment

  replicaCount: 1

  podLabels:

    azure.workload.identity/use: "true"



deployment:

  fallback_cp:

    interval: 60

    mode: write

    azure_blob:

      account_name: "youraccount"

      resource_container: "fallback-cp-data"

      config_container: "fallback-cp-config"
```

**Using Storage Account Access Key**:

Keep the Dashboard-generated `apisix.extraEnvVars` entries and append the storage credential to that list. The complete list must retain `API7_GATEWAY_GROUP_SHORT_ID` and any other generated entries:

backup-node-values.yaml

```
apisix:

  kind: Deployment

  replicaCount: 1

  extraEnvVars:

    - name: API7_GATEWAY_GROUP_SHORT_ID

      value: "YOUR_GATEWAY_GROUP_SHORT_ID"

    - name: AZURE_STORAGE_ACCOUNT_KEY

      valueFrom:

        secretKeyRef:

          name: fallback-storage-credentials

          key: azure-storage-account-key



deployment:

  fallback_cp:

    interval: 60

    mode: write

    azure_blob:

      account_name: "youraccount"

      account_key: '${{AZURE_STORAGE_ACCOUNT_KEY}}'

      resource_container: "fallback-cp-data"

      config_container: "fallback-cp-config"
```

Start with the Docker command generated by the Dashboard for the gateway group. Keep every generated `API7_DP_MANAGER_*`, `API7_CONTROL_PLANE_CA`, and `API7_GATEWAY_GROUP_SHORT_ID` environment variable. The endpoint and certificate variables preserve the normal DP Manager connection; the short ID selects the object name in storage.

Populate the required storage variables through the host's approved secret-injection mechanism before running the generated command. A Docker option such as `--env AWS_SECRET_ACCESS_KEY` forwards an existing host variable; it does not assign a value.

* AWS S3
* Azure Blob Storage

config.yaml

```
deployment:

  role: traditional

  role_traditional:

    config_provider: etcd

  fallback_cp:

    interval: 60

    mode: write

    aws_s3:

      access_key: '${{AWS_ACCESS_KEY_ID}}'

      secret_key: '${{AWS_SECRET_ACCESS_KEY}}'

      region: "us-east-1"

      resource_bucket: "fallback-cp-data"

      config_bucket: "fallback-cp-config"
```

For S3-compatible storage, use the provider's access key and secret key, and add `endpoint` to the `aws_s3` block:

```
deployment:

  fallback_cp:

    aws_s3:

      endpoint: "https://s3-compatible.example.com"

      use_path_style: true
```

Enable `use_path_style` only when the storage provider requires path-style bucket URLs.

Add these options to the generated command and keep its explicit gateway image version:

```
--env AWS_ACCESS_KEY_ID \

--env AWS_SECRET_ACCESS_KEY \

--mount type=bind,src="$(pwd)/config.yaml",dst=/usr/local/apisix/conf/config.yaml,readonly
```

config.yaml

```
deployment:

  role: traditional

  role_traditional:

    config_provider: etcd

  fallback_cp:

    interval: 60

    mode: write

    azure_blob:

      account_name: "youraccount"

      account_key: '${{AZURE_STORAGE_ACCOUNT_KEY}}'

      resource_container: "fallback-cp-data"

      config_container: "fallback-cp-config"
```

Add these options to the generated command and keep its explicit gateway image version:

```
--env AZURE_STORAGE_ACCOUNT_KEY \

--mount type=bind,src="$(pwd)/config.yaml",dst=/usr/local/apisix/conf/config.yaml,readonly
```

## Configure the Control Plane Pusher[​](#configure-the-control-plane-pusher "Direct link to Configure the Control Plane Pusher")

As an alternative to a backup gateway, the Dashboard process can export every gateway group on a schedule. This path does not require one backup node per group, but it depends on a running Dashboard and database when each snapshot is created.

### Helm[​](#helm "Direct link to Helm")

Configure the pusher under `dashboard_configuration.fallback_cp`. Merge the credential entries into the complete existing `dashboard.extraEnvVars` list. Helm replaces lists, so a credential-only overlay can remove required entries such as a Secret-backed database DSN.

For AWS S3:

cp-values.yaml (AWS S3)

```
dashboard:

  extraEnvVars:

    # Keep every existing Dashboard environment variable above or below these entries.

    - name: AWS_ACCESS_KEY_ID

      valueFrom:

        secretKeyRef:

          name: fallback-storage-credentials

          key: aws-access-key-id

    - name: AWS_SECRET_ACCESS_KEY

      valueFrom:

        secretKeyRef:

          name: fallback-storage-credentials

          key: aws-secret-access-key



dashboard_configuration:

  fallback_cp:

    cron_spec: "@every 1m"

    aws_s3:

      access_key: '${AWS_ACCESS_KEY_ID}'

      secret_key: '${AWS_SECRET_ACCESS_KEY}'

      region: "us-east-1"

      resource_bucket: "fallback-cp-data"

      config_bucket: "fallback-cp-config"

      use_path_style: false
```

For S3-compatible storage, add `custom_endpoint` to the same block. Change `use_path_style` to `true` only when the provider requires path-style bucket URLs:

```
dashboard_configuration:

  fallback_cp:

    aws_s3:

      custom_endpoint: "https://s3-compatible.example.com"

      use_path_style: true
```

For Azure Blob Storage:

cp-values.yaml (Azure Blob Storage)

```
dashboard:

  extraEnvVars:

    # Keep every existing Dashboard environment variable above or below this entry.

    - name: AZURE_STORAGE_ACCOUNT_KEY

      valueFrom:

        secretKeyRef:

          name: fallback-storage-credentials

          key: azure-storage-account-key



dashboard_configuration:

  fallback_cp:

    cron_spec: "@every 1m"

    azure_blob:

      account_name: "youraccount"

      account_key: '${AZURE_STORAGE_ACCOUNT_KEY}'

      resource_container: "fallback-cp-data"

      config_container: "fallback-cp-config"
```

The Control Plane pusher requires explicit access keys. It does not use the gateway image's IAM or Workload Identity credential chain.

### Docker or Packages[​](#docker-or-packages "Direct link to Docker or Packages")

Configure the same producer in the Dashboard configuration file. Populate the referenced environment variables through the process supervisor or approved secret-injection mechanism before starting every Dashboard replica:

dashboard-config.yaml

```
fallback_cp:

  cron_spec: "@every 1m"

  aws_s3:

    access_key: "${AWS_ACCESS_KEY_ID}"

    secret_key: "${AWS_SECRET_ACCESS_KEY}"

    region: "us-east-1"

    resource_bucket: "fallback-cp-data"

    config_bucket: "fallback-cp-config"

    use_path_style: false

  azure_blob:

    account_name: "youraccount"

    account_key: "${AZURE_STORAGE_ACCOUNT_KEY}"

    resource_container: "fallback-cp-data"

    config_container: "fallback-cp-config"
```

❶ A schedule expression that controls how often the Dashboard pushes configuration. Common values include `@every 1m` and `@every 5m`. ❷ ❸ Configure one or both storage backends. The Dashboard pushes to every configured backend.

For S3-compatible storage, add `custom_endpoint` to the Dashboard-side `aws_s3` block. Change `use_path_style` to `true` only when the provider requires path-style bucket URLs:

```
fallback_cp:

  aws_s3:

    custom_endpoint: "https://s3-compatible.example.com"

    use_path_style: true
```

info

When multiple Dashboard instances are running, a distributed lock ensures that only one instance performs the push at any given time.

## Recover Traffic Nodes from Fallback Storage[​](#recover-traffic-nodes-from-fallback-storage "Direct link to Recover Traffic Nodes from Fallback Storage")

Before an outage, keep the complete normal deployment values or generated Docker command for every gateway group. Confirm that the selected backup method has written one object named with the gateway-group short ID to both the resource and configuration locations.

When the control plane is unavailable and a traffic node must restart, start that node in fallback read mode. The gateway loads the stored snapshot during startup and uses it as its configuration source.

* Kubernetes (Helm)
* Docker

Copy the saved `normal-values.yaml` to `recovery-base-values.yaml`. Keep the Dashboard-generated `API7_GATEWAY_GROUP_SHORT_ID` environment variable and any storage identity or credential configuration in the copy.

Use probes that work while DP Manager is unavailable. The `/status/ready` endpoint still checks DP Manager in fallback read mode. If your readiness probe uses that endpoint or otherwise depends on DP Manager, replace the entire `gateway.readinessProbe` block in the recovery copy. Use a TCP probe on an enabled traffic container port. The example below uses the chart's default timing fields and the default HTTP port, `9080`:

recovery-base-values.yaml (probe excerpt)

```
gateway:

  readinessProbe:

    failureThreshold: 6

    initialDelaySeconds: 10

    periodSeconds: 10

    successThreshold: 1

    tcpSocket:

      port: 9080

    timeoutSeconds: 1
```

Use this port only when the HTTP listener is enabled. For an HTTPS-only gateway, set `tcpSocket.port` to its configured HTTPS container port, which defaults to `9443`. For a stream-only gateway, use one of its configured TCP stream container ports.

If your liveness probe also uses `/status/ready`, switch it to `/status` on the configured status listener in the recovery copy. A TCP probe checks that the proxy listener accepts connections. Test a route from the snapshot to verify that the gateway can handle requests.

Create a separate fallback values file for your storage provider.

* AWS S3
* Azure Blob Storage

fallback-read-values.yaml

```
serviceAccount:

  create: true

  annotations:

    eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/fallback-cp-reader-role"



deployment:

  fallback_cp:

    mode: read

    aws_s3:

      region: "us-east-1"

      resource_bucket: "fallback-cp-data"

      config_bucket: "fallback-cp-config"
```

For S3-compatible storage, add `endpoint` to the `aws_s3` block. Set `use_path_style` to `true` only when the provider requires path-style bucket URLs:

```
deployment:

  fallback_cp:

    aws_s3:

      endpoint: "https://s3-compatible.example.com"

      use_path_style: true
```

fallback-read-values.yaml

```
serviceAccount:

  create: true

  annotations:

    azure.workload.identity/client-id: "<your-reader-managed-identity-client-id>"



apisix:

  podLabels:

    azure.workload.identity/use: "true"



deployment:

  fallback_cp:

    mode: read

    azure_blob:

      account_name: "youraccount"

      resource_container: "fallback-cp-data"

      config_container: "fallback-cp-config"
```

The examples above create provider-specific service accounts for recovery. Grant the AWS role `s3:GetObject` on both buckets, or grant the Azure identity `Storage Blob Data Reader` on both containers. If your normal values already select a service account, merge the required annotations and Azure pod label into that existing identity instead of replacing it.

If traffic nodes use access keys, append the storage credential entries to the existing `apisix.extraEnvVars` list in `recovery-base-values.yaml` and add the corresponding `${{...}}` fields to `fallback-read-values.yaml`. Keep the entire environment variable list in the recovery copy so Helm preserves generated entries such as `API7_GATEWAY_GROUP_SHORT_ID`.

Apply the fallback file over the recovery copy using the same chart version as the normal release:

```
helm upgrade YOUR_GATEWAY_RELEASE api7/gateway \

  --version YOUR_GATEWAY_CHART_VERSION \

  -n YOUR_NAMESPACE \

  -f recovery-base-values.yaml \

  -f fallback-read-values.yaml \

  --wait
```

The upgrade applies to the whole selected release. Plan for a rollout of its gateway pods. The chart sets `role_data_plane.config_provider` to `json`, and each replacement pod uses the gateway-group short ID to fetch the resource and data plane configuration objects at startup. When the pods are ready, send a request through the gateway Service to a route in the snapshot.

Stop the normal gateway container before starting a replacement in fallback mode. Use the same gateway-group short ID and image version as the normal container.

If the fallback node is behind a load balancer, use a health check on a published traffic port. For example, the commands below publish the default HTTP port, `9080`, which you can use for a TCP health check. Test a route from the snapshot on the replacement before returning it to service, then verify the same route through the load balancer.

* AWS S3
* Azure Blob Storage

config.yaml

```
deployment:

  role: data_plane

  role_data_plane:

    config_provider: json

  fallback_cp:

    aws_s3:

      access_key: '${{AWS_ACCESS_KEY_ID}}'

      secret_key: '${{AWS_SECRET_ACCESS_KEY}}'

      region: "us-east-1"

      resource_bucket: "fallback-cp-data"

      config_bucket: "fallback-cp-config"

      use_path_style: false
```

❶ Set `config_provider: json` to use the stored snapshot as the gateway's configuration source.

For S3-compatible storage, add `endpoint` to the Docker recovery `aws_s3` block. Change `use_path_style` to `true` only when the provider requires path-style bucket URLs:

```
deployment:

  fallback_cp:

    aws_s3:

      endpoint: "https://s3-compatible.example.com"

      use_path_style: true
```

Start the fallback container with the saved gateway-group short ID and storage credentials:

```
docker run -d --name api7-gateway-fallback \

  -e API7_GATEWAY_GROUP_SHORT_ID="YOUR_GATEWAY_GROUP_SHORT_ID" \

  -e AWS_ACCESS_KEY_ID \

  -e AWS_SECRET_ACCESS_KEY \

  -p 9080:9080 \

  -p 9443:9443 \

  --mount type=bind,src="$(pwd)/config.yaml",dst=/usr/local/apisix/conf/config.yaml,readonly \

  api7/api7-ee-3-gateway:YOUR_GATEWAY_VERSION
```

config.yaml

```
deployment:

  role: data_plane

  role_data_plane:

    config_provider: json

  fallback_cp:

    azure_blob:

      account_name: "youraccount"

      account_key: '${{AZURE_STORAGE_ACCOUNT_KEY}}'

      resource_container: "fallback-cp-data"

      config_container: "fallback-cp-config"
```

Start the fallback container with the saved gateway-group short ID and storage credential:

```
docker run -d --name api7-gateway-fallback \

  -e API7_GATEWAY_GROUP_SHORT_ID="YOUR_GATEWAY_GROUP_SHORT_ID" \

  -e AZURE_STORAGE_ACCOUNT_KEY \

  -p 9080:9080 \

  -p 9443:9443 \

  --mount type=bind,src="$(pwd)/config.yaml",dst=/usr/local/apisix/conf/config.yaml,readonly \

  api7/api7-ee-3-gateway:YOUR_GATEWAY_VERSION
```

caution

Fallback mode serves the stored snapshot and does not receive later control-plane changes.

* For Helm, run the upgrade command again with `--reset-values -f normal-values.yaml` in place of the two recovery values files. This restores the normal configuration and probes. Wait for the replacement pods to report **Healthy** in the Dashboard, then verify current configuration and traffic through the Service.
* For Docker, keep other HA nodes serving traffic, drain the fallback node from the load balancer, and remove the fallback container so it releases ports `9080` and `9443`. Start the original pinned Dashboard-generated command, wait for the new instance to report **Healthy**, and verify current configuration and traffic. Restore the node's normal load-balancer check before returning it to service.

## Verify Backup and Recovery[​](#verify-backup-and-recovery "Direct link to Verify Backup and Recovery")

Test the complete workflow in a non-production gateway group before relying on fallback storage:

1. Create a distinctive test route and wait for the next backup interval or scheduled Dashboard run.
2. Inspect the backup gateway or Dashboard logs and confirm that the resource object and data plane configuration object were both written successfully during the same run. Do not recover from a run where either write failed.
3. Confirm that both storage locations contain an object named with the gateway-group short ID. The resource object should contain the test route; the configuration object should contain the data plane configuration for the same group. Compare their last-modified times or version IDs with the successful run. Enable object versioning where the storage provider supports it, and retain the matching pair needed for recovery.
4. Save the normal deployment values or Docker command and the probe settings, then make the control plane unavailable to the test node.
5. Start that node in fallback read mode. Verify the test route directly, then send the same request through the Service or load balancer with the recovery probe in place. Confirm that the request reaches the recovered node and that authentication, plugins, upstreams, and service discovery used by the group behave as expected.
6. Restore the normal deployment configuration after the control plane recovers. Wait for the instance to report **Healthy**, apply a small configuration change, and confirm that the node receives it before returning the node to production traffic.

caution

Fallback objects contain gateway resources and data plane configuration, including credential-bearing plugin fields, private keys, and the gateway-group keyring in a form the gateway can consume. Encrypt the storage backend, restrict read and write access, audit access, and apply a retention policy appropriate for configuration backups.

## Configuration Reference[​](#configuration-reference "Direct link to Configuration Reference")

### Backup Node / Traffic Node (`config.yaml`)[​](#backup-node--traffic-node-configyaml "Direct link to backup-node--traffic-node-configyaml")

| Field                                                  | Type    | Description                                                                                                   |
| ------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------- |
| `deployment.fallback_cp.mode`                          | string  | `write` for backup nodes or `read` for traffic nodes that start from fallback storage. The default is `read`. |
| `deployment.fallback_cp.interval`                      | integer | Export interval in seconds (backup node only).                                                                |
| `deployment.fallback_cp.aws_s3.access_key`             | string  | AWS access key ID. Not required when using IRSA.                                                              |
| `deployment.fallback_cp.aws_s3.secret_key`             | string  | AWS secret access key. Not required when using IRSA.                                                          |
| `deployment.fallback_cp.aws_s3.region`                 | string  | AWS region for the S3 buckets.                                                                                |
| `deployment.fallback_cp.aws_s3.resource_bucket`        | string  | S3 bucket for resource data.                                                                                  |
| `deployment.fallback_cp.aws_s3.config_bucket`          | string  | S3 bucket for configuration data.                                                                             |
| `deployment.fallback_cp.aws_s3.endpoint`               | string  | Custom S3 endpoint (for S3-compatible storage).                                                               |
| `deployment.fallback_cp.aws_s3.use_path_style`         | boolean | Whether to use path-style S3 bucket URLs. The default is `false`.                                             |
| `deployment.fallback_cp.azure_blob.account_name`       | string  | Azure storage account name.                                                                                   |
| `deployment.fallback_cp.azure_blob.account_key`        | string  | Azure storage account key. Not required when using Workload Identity.                                         |
| `deployment.fallback_cp.azure_blob.resource_container` | string  | Blob container for resource data.                                                                             |
| `deployment.fallback_cp.azure_blob.config_container`   | string  | Blob container for configuration data.                                                                        |
| `deployment.fallback_cp.azure_blob.endpoint`           | string  | Custom Azure Blob endpoint. Defaults to `https://<account_name>.blob.core.windows.net`.                       |

### Dashboard (`dashboard-config.yaml`)[​](#dashboard-dashboard-configyaml "Direct link to dashboard-dashboard-configyaml")

| Field                                | Type    | Description                                                                                                                                                                                                                                            |
| ------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `fallback_cp.cron_spec`              | string  | Schedule expression for configuration pushes (for example, `@every 1m`).                                                                                                                                                                               |
| `fallback_cp.aws_s3.access_key`      | string  | AWS access key ID.                                                                                                                                                                                                                                     |
| `fallback_cp.aws_s3.secret_key`      | string  | AWS secret access key.                                                                                                                                                                                                                                 |
| `fallback_cp.aws_s3.region`          | string  | AWS region for the S3 buckets.                                                                                                                                                                                                                         |
| `fallback_cp.aws_s3.resource_bucket` | string  | S3 bucket for resource data.                                                                                                                                                                                                                           |
| `fallback_cp.aws_s3.config_bucket`   | string  | S3 bucket for configuration data.                                                                                                                                                                                                                      |
| `fallback_cp.aws_s3.custom_endpoint` | string  | Custom S3 endpoint for S3-compatible storage. In the API7 control plane Helm chart, configure this as `dashboard_configuration.fallback_cp.aws_s3.custom_endpoint`.                                                                                    |
| `fallback_cp.aws_s3.use_path_style`  | boolean | Whether to use path-style bucket URLs. The default is `false`; enable it only when the storage provider requires path-style URLs. In the API7 control plane Helm chart, configure this as `dashboard_configuration.fallback_cp.aws_s3.use_path_style`. |
| `fallback_cp.azure_blob.*`           | —       | Same fields as the gateway-side `azure_blob` configuration.                                                                                                                                                                                            |

## Next Steps[​](#next-steps "Direct link to Next Steps")

* [Deploy for High Availability](https://docs.api7.ai/api7-gateway/install/deploy-high-availability.md): Set up HA for both the control plane and data plane.
* [Data Plane High Availability](https://docs.api7.ai/api7-gateway/configure-and-manage/high-availability-data-plane.md): Learn about health checks and multi-node DP architecture.
* [Scale Data Plane](https://docs.api7.ai/api7-gateway/configure-and-manage/scale-data-plane.md): Add or remove traffic-serving nodes as traffic changes.
* [Production Best Practices](https://docs.api7.ai/api7-gateway/configure-and-manage/production-best-practices.md): Harden your deployment for production.
