title: Unable to add GSI to DynamoDB table using CloudFormation
body: <p>I have an existing DynamoDB table that is defined as part of a CloudFormation stack.  According the the <a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html" rel="noreferrer">CFN AWS::DynamoDB::Table documentation</a> the GlobalSecondaryIndexes attribute does not require replacement.  It even goes into details with the following caveats.</p>
  
  <blockquote>
    <p>You can delete or add one global secondary index without interruption.</p>
  </blockquote>
  
  <p>As well as the following...</p>
  
  <blockquote>
    <p>If you update a table to include a new global secondary index, AWS
    CloudFormation initiates the index creation and then proceeds with the
    stack update. AWS CloudFormation doesn't wait for the index to
    complete creation because the backfilling phase can take a long time,
    depending on the size of the table.</p>
  </blockquote>
  
  <p>However, in practice when I attempt to perform an update I get the following error message:</p>
  
  <pre><code>CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename mytablename and update the stack again.
  </code></pre>
  
  <p>Since I'm adding a GSI that uses a new attribute I'm forced to modify AttributeDefinitions which says it does require replacement.  However, even when I try to add a GSI with only existing attributes defined in the AttributeDefinitions I still get the same error message.</p>
  
  <p>Here is the snippet from my original CFN definition for my table:</p>
  
  <pre><code>{
    "myTable": {
      "Type": "AWS::DynamoDB::Table",
      "Properties": {
        "TableName": "mytablename",
        "AttributeDefinitions": [
          {
            "AttributeName": "entryId",
            "AttributeType": "S"
          },
          {
            "AttributeName": "entryName",
            "AttributeType": "S"
          },
          {
            "AttributeName": "appId",
            "AttributeType": "S"
          }
        ],
        "KeySchema": [
          {
            "KeyType": "HASH",
            "AttributeName": "entryId"
          },
          {
            "KeyType": "RANGE",
            "AttributeName": "entryName"
          }
        ],
        "ProvisionedThroughput": {
          "ReadCapacityUnits": {
            "Ref": "readThroughput"
          },
          "WriteCapacityUnits": {
            "Ref": "writeThroughput"
          }
        },
        "GlobalSecondaryIndexes": [
          {
              "IndexName": "appId-index",
            "KeySchema": [
              {
                "KeyType": "HASH",
                "AttributeName": "appId"
              }
            ],
            "Projection": {
              "ProjectionType": "KEYS_ONLY"
            },
            "ProvisionedThroughput": {
              "ReadCapacityUnits": {
                "Ref": "readThroughput"
              },
              "WriteCapacityUnits": {
                "Ref": "writeThroughput"
              }
            }
          }
        ]
      }
    }
  }
  </code></pre>
  
  <p>Here is what I want to update it to:</p>
  
  <pre><code>{
    "myTable": {
      "Type": "AWS::DynamoDB::Table",
      "Properties": {
        "TableName": "mytablename",
        "AttributeDefinitions": [
          {
            "AttributeName": "entryId",
            "AttributeType": "S"
          },
          {
            "AttributeName": "entryName",
            "AttributeType": "S"
          },
          {
            "AttributeName": "appId",
            "AttributeType": "S"
          },
          {
            "AttributeName": "userId",
            "AttributeType": "S"
          }
        ],
        "KeySchema": [
          {
            "KeyType": "HASH",
            "AttributeName": "entryId"
          },
          {
            "KeyType": "RANGE",
            "AttributeName": "entryName"
          }
        ],
        "ProvisionedThroughput": {
          "ReadCapacityUnits": {
            "Ref": "readThroughput"
          },
          "WriteCapacityUnits": {
            "Ref": "writeThroughput"
          }
        },
        "GlobalSecondaryIndexes": [
          {
              "IndexName": "appId-index",
            "KeySchema": [
              {
                "KeyType": "HASH",
                "AttributeName": "appId"
              }
            ],
            "Projection": {
              "ProjectionType": "KEYS_ONLY"
            },
            "ProvisionedThroughput": {
              "ReadCapacityUnits": {
                "Ref": "readThroughput"
              },
              "WriteCapacityUnits": {
                "Ref": "writeThroughput"
              }
            }
          },
          {
            "IndexName": "userId-index",
            "KeySchema": [
              {
                "KeyType": "HASH",
                "AttributeName": "userId"
              }
            ],
            "Projection": {
              "ProjectionType": "KEYS_ONLY"
            },
            "ProvisionedThroughput": {
              "ReadCapacityUnits": {
                "Ref": "readThroughput"
              },
              "WriteCapacityUnits": {
                "Ref": "writeThroughput"
              }
            }
          }
        ]
      }
    }
  }
  </code></pre>
  
  <p>However, like I mentioned before even if I do not define userId in the AttributeDefinitions and use an existing attribute in a new GSI definition it does not work and fails with the same error message.</p>