CloudFormation cannot update a stack when a custom-named resource requires replacing

I have the following error.

Serverless: Operation failed!

Serverless Error ---------------------------------------

An error occurred: phoneNumberTable - CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename mysite-api-phonenumber-dev and update the stack again…

I tried deleting the database to see if it could re-create it then but it still gives the same error and doesn’t remake the database? What do I do here?

I put more info here in my stackoverflow question as well. https://stackoverflow.com/questions/47567549/serverless-error-cloudformation-cannot-update-a-stack-whena-custom-named-resour

1 Like

I hate this error too. I think it is a security feature of AWS. You are forced to change the name of phoneNumberTable to something like phoneNumberTable1. Then the next time you get the error change it back to phoneNumberTable. Deleting the resource will not work.

Maybe someone can enlighten us on a way around it.

The AWS recommended solution is to rename:
https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-custom-name/

I wasn’t aware you could change the name then change it back, that is an interesting tactic also. This way I don’t have to delete all the others tables, just the one I messed up on. You could add this as an answer on stackoverflow also if you wanted.

Be aware that changing the name of the table creates a new table with the new name and drops the original table(unless it has DeletionPolicy: Retain). So be sure to backup your data first if you wish to keep it.

My process for these situations has been:

  1. copy the original table and data to mysite-api-phonenumber-dev-bak
  2. rename the table in serverless.yml to mysite-api-phonenumber-devX
    2a) sls deploy
  3. rename the table in serverless.yml to mysite-api-phonenumber-dev <== remove the X
    2a) sls deploy
  4. restore the data
  5. drop the backup table mysite-api-phonenumber-dev-bak
1 Like

Did you use the backup tool in the DynamoDB dashboard? If not, how did you do it?

I have a fairly simple node.js script to copy table to table.:

const AWS = require('aws-sdk')

let dynamodb = new AWS.DynamoDB({ region: 'us-west-2' })

let stage = 'dev' // dev|prod|whatever

var srcParams = {
  TableName: `${stage}-table-to-move`
}
var dstParams = {
  TableName: `${srcParams.TableName}-bak`
}
dynamodb.scan(srcParams, onScan)

function onScan (err, data) {
  if (err) {
    console.error(`Unable to scan ${srcParams.TableName}. Error JSON: `, JSON.stringify(err, null, 2))
  } else {
    console.log('Scan succeeded')
    data.Items.forEach(function (item) {
      dstParams.Item = item
      dynamodb.putItem(dstParams, function (err, data) {
        if (err) console.error(`Unable to add item to ${dstParams.TableName}. Error JSON: `, JSON.stringify(err))
        else console.log('Item ', item, ' written.')
      })
    })

    // continue scanning if we have more items, because
    // scan retrieves a maximum of 1MB of data
    if (typeof data.LastEvaluatedKey !== 'undefined') {
      console.log('Scanning for more...')
      srcParams.ExclusiveStartKey = data.LastEvaluatedKey
      dynamodb.scan(srcParams, onScan)
    }
  }
}

3 Likes

That looks useful! Thanks!