无服务器错误,当自定义命名的资源需要替换时,CloudFormation无法更新堆栈。

25
我遇到了以下错误。
无服务器:操作失败!
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…

我尝试删除数据库以查看是否可以重新创建它,但仍然出现相同的错误且无法重新创建数据库?在这种情况下该怎么办?

我的做法是最近在serverless.yml文件中更改了以下资源。

phoneNumberTable: #This table is used to track phone numbers used in the system
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:custom.phoneNumberTable}
        AttributeDefinitions: #UserID in this case will be created once and constantly updated as it changes with status regarding the user.
          - AttributeName: phoneNumber
            AttributeType: S
        KeySchema:
          - AttributeName: phoneNumber
            KeyType: HASH
        ProvisionedThroughput:
            ReadCapacityUnits: ${self:custom.dynamoDbCapacityUnits.${self:custom.pstage}}
            WriteCapacityUnits: ${self:custom.dynamoDbCapacityUnits.${self:custom.pstage}}

我在复制和粘贴时不小心用了userId创建了它,现在我已将其更改为phoneNumber作为哈希键,但更改不会立即生效!

编辑:

我找到了一个解决方案,但它很糟糕。如果我运行“sls remove --stage dev”,它将删除我的阶段的所有内容,但真的是全部...然后我必须运行“sls deploy --stage dev”重新开始部署,在此期间,我的数据库将清除所有数据...肯定有更好的方法吧。


你的解决方案对我很好用... 当时阶段是“开发”,丢失的数据在我的情况下并不是问题。谢谢! - kord
5个回答

14

6
你能解释一下问题的原因吗?我无法理解你提供的AWS页面中提到的解释。 - Mohammed Noureldin
@MohammedNoureldin 我认为问题在于当资源在更新过程中需要替换时,CloudFormation会先创建新资源,然后再删除旧资源,这样如果发生意外情况,CF需要回滚堆栈更新,您的原始资源(带有原始名称)仍然存在。如果无法为资源自动生成名称,因为用户已指定自定义名称,它就无法做到这一点。 - undefined

3

我发现需要插入一些变量才能使它正常工作。

环境变量: USERS_TABLE:"users-${opt:stage,self:provider.stage}-${self:provider.environment.BUILD_NUMBER}"

表名: TableName:${self:provider.environment.USERS_TABLE}

在我的代码中: const existingUser = await dynamoDb.get({ TableName: process.env.USERS_TABLE, Key: { email, }, }).promise();


您的情况下变量总是相同吗?如果更改变量会发生什么? - Joseph Astrahan
1
我最终不得不添加一个变量,每次都会改变BUILD_NUMBER。我已经更新了我的答案。然而,我实际上决定在我正在处理的项目中切换到MySQL而不是Dynamo。 - Alex K
有趣的是你提到了这个,我也切换到了MySQL。我还有一些关于如何使用无服务器自动化的其他帖子。 - Joseph Astrahan
不错。是的,我发现Dynamo太过受限制了。我正在构建一个SaaS,我习惯于能够轻松地查询不同字段并创建索引等等。 - Alex K
3
这并不是一个完美的解决方案,虽然从某种意义上来说可以算作是,但实际上这会删除你现有的表格并导致数据丢失,如果我理解正确的话。 - Ali

3

将您的资源重命名为其他名称,部署它,如果需要,将其重新命名并再次部署。


1

这个问题通常发生在您修改 DynamoDB 表的分区键时。DynamoDB 无法为您进行更改。您必须删除数据库,确保备份并重新创建它。一旦新的数据库被创建,您就可以执行迁移操作。


1
根据https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-custom-name/
这个错误通常发生在堆栈更新尝试替换具有自定义名称属性的资源时。除非将自定义名称更改为不同名称,否则AWS CloudFormation不会替换具有自定义名称的资源。为了防止堆栈失败并避免错误消息,在更新堆栈之前,请将任何具有自定义名称的资源更改为使用不同的名称。
解决此问题,您需要将TableName更改为其他字符串。这样做的效果是:Serverless将删除您的表格(因为它不再是堆栈的一部分),并创建一个新表格,具有新名称和键。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接