Duplicate DynamoDB table using CLI

I had to duplicate the DynamoDB table a few times recently. Here is the quick way to do this using CLI (AWS Console). I assumed that you have your AWS Console already configured and the permissions are set properly to be able to access DynamoDB.

The first step is to obtain current table details. Here is how:

aws dynamodb describe-table --table-name your-source-table-name

The above will produce the JSON output describing the table data, such as this one:

{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "address",
                "AttributeType": "S"
            },
            {
                "AttributeName": "id",
                "AttributeType": "S"
            },
            {
                "AttributeName": "account",
                "AttributeType": "S"
            },
            {
                "AttributeName": "timestamp",
                "AttributeType": "S"
            }
        ],
        "TableName": "your-source-table-name",
        "KeySchema": [
            {
                "AttributeName": "id",
                "KeyType": "HASH"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1548770926.377,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 1548770926.377,
            "LastDecreaseDateTime": 1548770926.377,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 9723,
        "ItemCount": 46,
        "TableArn": "arn:aws:dynamodb:us-east-1:210010000000:table/your-source-table-name",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST",
            "LastUpdateToPayPerRequestDateTime": 1548770926.377
        },
        "GlobalSecondaryIndexes": [
            {
                "IndexName": "address-timestamp-index",
                "KeySchema": [
                    {
                        "AttributeName": "address",
                        "KeyType": "HASH"
                    },
                    {
                        "AttributeName": "timestamp",
                        "KeyType": "RANGE"
                    }
                ],
                "Projection": {
                    "ProjectionType": "ALL"
                },
                "IndexStatus": "ACTIVE",
                "ProvisionedThroughput": {
                    "LastIncreaseDateTime": 1548770926.377,
                    "LastDecreaseDateTime": 1548770926.377,
                    "NumberOfDecreasesToday": 0,
                    "ReadCapacityUnits": 0,
                    "WriteCapacityUnits": 0
                },
                "IndexSizeBytes": 9723,
                "ItemCount": 46,
                "IndexArn": "arn:aws:dynamodb:us-east-1:210010000000:table/your-source-table-name/index/address-timestamp-index"
            }
        ]
    }
}

From the above, you should produce three files, containing particular elements of the table. First, take the contents of AttributeDefinitions and save them to the attribute-definitions.json file:

[
    {
        "AttributeName": "address",
        "AttributeType": "S"
    },
    {
        "AttributeName": "id",
        "AttributeType": "S"
    },
    {
        "AttributeName": "account",
        "AttributeType": "S"
    },
    {
        "AttributeName": "timestamp",
        "AttributeType": "S"
    }
]

Next, the key schema (save to the key-schema.json file):

[
    {
        "AttributeName": "id",
        "KeyType": "HASH"
    }
]

You may have Local or Global indexes or both. Save them to appropriate files, but you also have to remove the information that is not required. In my case, the single global index visible above ended up in the global-secondary-indexes.json file like this:

[
    {
        "IndexName": "address-timestamp-index",
        "KeySchema": [
            {
                "AttributeName": "address",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "timestamp",
                "KeyType": "RANGE"
            }
        ],
        "Projection": {
            "ProjectionType": "ALL"
        }
    }
]

Please note that there is only name, schema and projection left. Once you have your files ready, you can call this:

aws dynamodb create-table --table-name new-table-name \ 
 --attribute-definitions file://attribute-definitions.json \
 --key-schema file://key-schema.json --global-secondary-indexes \ 
 file://global-secondary-indexes.json --billing-mode PAY_PER_REQUEST

As you can see, it is called with the new table name and the files created above. There is the same parameter as --global-secondary-indexes for local indexes, it is --local-secondary-indexes. Please also note that in my case, the billing mode is PAY_PER_REQUEST – you may want to set it by configuring proper limits for your use case.