{
  "schema_version": 2,
  "id": "integrate/redis-data-integration/installation/disaster-recovery/dynamodb",
  "title": "Configure a DynamoDB lease",
  "url": "https://redis.io/docs/latest/integrate/redis-data-integration/installation/disaster-recovery/dynamodb/",
  "summary": "Create and configure a strongly consistent DynamoDB lease for RDI disaster recovery.",
  "tags": [
    "docs",
    "integrate",
    "rs",
    "rdi"
  ],
  "last_updated": "2026-11-13T11:28:40+02:00",
  "page_type": "content",
  "content_hash": "ffb73a835ee02e804d0fb3a67b573b83c958343514cc47572325410ca000c131",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Use an Amazon DynamoDB global table with multi-Region strong consistency (MRSC) to coordinate\nleader election between Redis Data Integration (RDI) disaster recovery (DR) sites. All sites\nmust use the same table and key name, with each site using a replica Region it can reach.\n\nBefore you begin, [create the RDI database at both sites](https://redis.io/docs/latest/integrate/redis-data-integration/installation/disaster-recovery#prepare-both-sites).\nThe commands use the Amazon Web Services (AWS) command-line interface (CLI), authenticated\nas an identity that can create an MRSC global table. Use a current AWS CLI version 2 that\nsupports `--global-table-witness-updates` and `--multi-region-consistency`. If either option\nis unknown, [update the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).\nThe RDI operator needs separate runtime permissions.\n\nTo prepare the lease store with Terraform, use the\n[DynamoDB lease Terraform example](https://github.com/redis/rdi-cloud-automation/tree/main/modules/aws-rdi-dynamodb-lease).\nIt creates the MRSC global table and operator access policy, and outputs lease settings for\neach replica Region. After applying it, complete\n[Prepare both sites](https://redis.io/docs/latest/integrate/redis-data-integration/installation/disaster-recovery#prepare-both-sites),\nthen continue with [Configure both instances](#configure-both-instances)."
    },
    {
      "id": "create-the-table",
      "title": "Create the table",
      "role": "content",
      "text": "The table must have a single string partition key named `id`, with no sort key. Do not enable\nTime to Live (TTL), which MRSC tables do not support. See\n[DynamoDB consistency modes](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/V2globaltables_HowItWorks.html).\n\n1. Choose three supported AWS Regions: two for replicas and one for a witness. Each RDI site\n   uses a replica endpoint it can reach. The witness cannot serve reads or writes. For\n   example, you can use `us-east-1` and `us-east-2` for replicas and `us-west-2` for the witness.\n   Check [MRSC Region availability](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/V2globaltables_HowItWorks.html)\n   before choosing your Regions.\n\n1. Set the table name and Regions in your shell:\n\n   [code example]\n\n1. Create the first replica table:\n\n   [code example]\n\n1. Convert the empty table to an MRSC global table with a second replica and a witness:\n\n   [code example]\n\n   Keep the table empty until the conversion finishes. Do not start RDI against it yet.\n   You choose the consistency mode when creating the global table; you cannot change it on\n   an existing global table. See [Create an MRSC global table](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/V2globaltables.tutorial.html).\n\n1. Check readiness from both replica Regions:\n\n   [code example]\n\n   Wait until the output shows `ACTIVE` for the table, replicas, and witness, and `STRONG` for\n   the consistency. Confirm the single `id` partition key with string type `S`. A newly created\n   replica can take time to become visible."
    },
    {
      "id": "grant-the-operator-access",
      "title": "Grant the operator access",
      "role": "content",
      "text": "Give each operator's AWS identity the `dynamodb:DescribeTable`, `dynamodb:PutItem`, and\n`dynamodb:DeleteItem` permissions on the replica it uses. The operator does not need access\nto the witness. Creating the table requires separate permissions.\n\nFor an identity used at both sites, the following Identity and Access Management (IAM)\npolicy grants runtime access to the two replica table Amazon Resource Names (ARNs):\n\n[code example]\n\nAttach this policy to the operator's role or user using your IAM administration process.\nIf the sites use different identities, restrict each identity to the replica it uses. Don't\nrestrict `dynamodb:ReturnValues` to `NONE` for these actions. The operator reads the current\nlease owner from a failed conditional write.\n\nAllow outbound Hypertext Transfer Protocol Secure (HTTPS) access from each operator to\n`dynamodb.<aws-replica-region>.amazonaws.com`.\n\nChoose one of these identity options for each operator."
    },
    {
      "id": "default-credential-provider-chain",
      "title": "Default credential provider chain",
      "role": "content",
      "text": "RDI uses the AWS default credential provider chain when you omit a credentials file.\nConfigure the identity in the operator's environment, not only in your local shell. On Amazon\nElastic Kubernetes Service (EKS), use\n[IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)\nor [EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html).\nThe operator runs as the Kubernetes service account `rdi-operator` in the RDI namespace. For\nIAM roles for service accounts, set the role annotation with\n`operator.serviceAccount.annotations` in each values file:\n\n[code example]"
    },
    {
      "id": "configure-both-instances",
      "title": "Configure both instances",
      "role": "configuration",
      "text": "Merge the following settings into the `operator.leaderElection` section of each site's\nvalues file. Keep the local RDI database connection and other installation settings from\n[Configure each site's values file](https://redis.io/docs/latest/integrate/redis-data-integration/installation/disaster-recovery#configure-each-sites-values-file).\n\nIn `rdi-values-site-a.yaml`:\n\n[code example]\n\nIn `rdi-values-site-b.yaml`:\n\n[code example]\n\nUse identical `tableName` and `keyName` values at both sites, distinct `instanceID` values,\nand each site's selected replica Region. `keyName` defaults to `rdi-lease`. To use one table\nfor several DR setups, see\n[Share a lease store between DR setups](https://redis.io/docs/latest/integrate/redis-data-integration/installation/disaster-recovery#share-a-lease-store-between-dr-setups).\nRDI creates the lease item."
    },
    {
      "id": "install-rdi",
      "title": "Install RDI",
      "role": "setup",
      "text": "With the AWS identity configured for both operators, install RDI in each Kubernetes cluster:\n\n[code example]\n\nAn operator running outside AWS can use an AWS shared credentials file.\nIf you use a shared credentials file, you must pass it to the `helm upgrade`\ncommands shown above using the `--set-file` option:\n\n[code example]\n\nFor example, the file can contain:\n\n[code example]\n\nDon't use temporary credentials in this file. RDI reads it only at startup, so they stop\nworking when they expire.\n\nAfter creating the lease resource and granting access, return to\n[Prepare both sites](https://redis.io/docs/latest/integrate/redis-data-integration/installation/disaster-recovery#prepare-both-sites)\nto complete the source, target, and network preparation.\n\nContinue with [Deploy pipelines and secrets](https://redis.io/docs/latest/integrate/redis-data-integration/installation/disaster-recovery#deploy-pipelines-and-secrets)\nto configure RDI CLI contexts. One leader, one follower, and no access errors in the operator\nlogs confirm that both operators can access the table."
    }
  ],
  "examples": [
    {
      "id": "create-the-table-ex0",
      "language": "bash",
      "code": "DR_LEASE_TABLE=\"<lease-table>\"\n   DR_LEASE_REGION_A=\"<aws-replica-region-a>\"\n   DR_LEASE_REGION_B=\"<aws-replica-region-b>\"\n   DR_LEASE_WITNESS_REGION=\"<aws-witness-region>\"",
      "section_id": "create-the-table"
    },
    {
      "id": "create-the-table-ex1",
      "language": "bash",
      "code": "aws dynamodb create-table --region \"$DR_LEASE_REGION_A\" \\\n     --table-name \"$DR_LEASE_TABLE\" \\\n     --attribute-definitions AttributeName=id,AttributeType=S \\\n     --key-schema AttributeName=id,KeyType=HASH \\\n     --billing-mode PAY_PER_REQUEST\n\n   aws dynamodb wait table-exists --region \"$DR_LEASE_REGION_A\" \\\n     --table-name \"$DR_LEASE_TABLE\"",
      "section_id": "create-the-table"
    },
    {
      "id": "create-the-table-ex2",
      "language": "bash",
      "code": "aws dynamodb update-table --region \"$DR_LEASE_REGION_A\" \\\n     --table-name \"$DR_LEASE_TABLE\" \\\n     --replica-updates \"[{\\\"Create\\\":{\\\"RegionName\\\":\\\"$DR_LEASE_REGION_B\\\"}}]\" \\\n     --global-table-witness-updates \"[{\\\"Create\\\":{\\\"RegionName\\\":\\\"$DR_LEASE_WITNESS_REGION\\\"}}]\" \\\n     --multi-region-consistency STRONG",
      "section_id": "create-the-table"
    },
    {
      "id": "create-the-table-ex3",
      "language": "bash",
      "code": "for DR_LEASE_REGION in \"$DR_LEASE_REGION_A\" \"$DR_LEASE_REGION_B\"; do\n     aws dynamodb describe-table --region \"$DR_LEASE_REGION\" \\\n       --table-name \"$DR_LEASE_TABLE\" \\\n       --query 'Table.{Status:TableStatus,Consistency:MultiRegionConsistency,KeySchema:KeySchema,Attributes:AttributeDefinitions,Replicas:Replicas[*].[RegionName,ReplicaStatus],Witnesses:GlobalTableWitnesses[*].[RegionName,WitnessStatus]}'\n   done",
      "section_id": "create-the-table"
    },
    {
      "id": "grant-the-operator-access-ex0",
      "language": "json",
      "code": "{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"dynamodb:DescribeTable\",\n        \"dynamodb:PutItem\",\n        \"dynamodb:DeleteItem\"\n      ],\n      \"Resource\": [\n        \"arn:aws:dynamodb:<aws-replica-region-a>:<aws-account-id>:table/<lease-table>\",\n        \"arn:aws:dynamodb:<aws-replica-region-b>:<aws-account-id>:table/<lease-table>\"\n      ]\n    }\n  ]\n}",
      "section_id": "grant-the-operator-access"
    },
    {
      "id": "default-credential-provider-chain-ex0",
      "language": "yaml",
      "code": "operator:\n  serviceAccount:\n    annotations:\n      eks.amazonaws.com/role-arn: arn:aws:iam::<aws-account-id>:role/<operator-role>",
      "section_id": "default-credential-provider-chain"
    },
    {
      "id": "configure-both-instances-ex0",
      "language": "yaml",
      "code": "operator:\n  leaderElection:\n    enabled: true\n    instanceID: site-a\n    leaseType: dynamodb\n    dynamoDBLease:\n      region: <aws-replica-region-a>\n      tableName: <lease-table>\n      keyName: <lease-item-key>",
      "section_id": "configure-both-instances"
    },
    {
      "id": "configure-both-instances-ex1",
      "language": "yaml",
      "code": "operator:\n  leaderElection:\n    enabled: true\n    instanceID: site-b\n    leaseType: dynamodb\n    dynamoDBLease:\n      region: <aws-replica-region-b>\n      tableName: <lease-table>\n      keyName: <lease-item-key>",
      "section_id": "configure-both-instances"
    },
    {
      "id": "install-rdi-ex0",
      "language": "bash",
      "code": "helm upgrade --install rdi \"rdi-<tag>.tgz\" \\\n  --kube-context \"<site-a-kube-context>\" --namespace rdi --create-namespace \\\n  --values rdi-values-site-a.yaml\n\nhelm upgrade --install rdi \"rdi-<tag>.tgz\" \\\n  --kube-context \"<site-b-kube-context>\" --namespace rdi --create-namespace \\\n  --values rdi-values-site-b.yaml",
      "section_id": "install-rdi"
    },
    {
      "id": "install-rdi-ex1",
      "language": "text",
      "code": "--set-file operator.leaderElection.dynamoDBLease.credentials=\"<aws-creds-file>\"",
      "section_id": "install-rdi"
    },
    {
      "id": "install-rdi-ex2",
      "language": "ini",
      "code": "[default]\naws_access_key_id = <access-key-id>\naws_secret_access_key = <secret-access-key>",
      "section_id": "install-rdi"
    }
  ]
}
