3

我在使用无服务器框架时遇到了一些问题,因为我不小心在另一个服务上使用了相同的服务名称。

An error occurred: tableX - TableX already exists.

假设我有两个“ serverless.yml ”文件,两者都具有相同的服务名称。其中一个(我们称之为“ test1 ”)有资源(DynamoDB 表),另一个没有(“ test2 ”)。就像下面的片段:

测试1

service: sandbox-core
provider:
  name: aws
  stage: core
  runtime: nodejs6.10
  region: sa-east-1
  memorySize: 128
  timeout: 300

resources:
  Resources:

    table3:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: SandboxTable3
        AttributeDefinitions:
          -
            AttributeName: provider
            AttributeType: S
          -
            AttributeName: appId
            AttributeType: S
        KeySchema:
          -
            AttributeName: provider
            KeyType: HASH
          -
            AttributeName: appId
            KeyType: RANGE

        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

    table4:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: SandboxTable4
        AttributeDefinitions:
          -
            AttributeName: session
            AttributeType: S
        KeySchema:
          -
            AttributeName: session
            KeyType: HASH

        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 1

functions:
  auth:
    handler: handler.auth
    events:
      - http:
          path: auth/{session}/{provider}/{appId}
          method: get
          cors: true

测试2

service: sandbox-core

provider:
  name: aws
  stage: core
  runtime: nodejs6.10
  region: sa-east-1
  memorySize: 128
  timeout: 300

functions:
  createCustomData:
    handler: handler.createCustomData
    events:
      - http:
          path: teste2
          method: post
          cors: true

当我sls deploy是“ test1 ”时,他会根据我的需要创建表,使用DeletionPolicy: Retain, 为具有非常敏感数据的表。然后我sls deploytest2 ”有其他功能但没有任何资源(DynamoDB 表),他做了预期的事情:跳过表的删除。

但是,当我再次部署“ test1 ”时,他无法识别这些表,他开始“创建”现有表而不是更新它们,并且无法部署。

我需要没有被删除的表,并且需要服务上的功能。看起来 Cloud Formation 在第一次部署时丢失了创建表的跟踪。

我不想像在这个github 线程上所说的那样分离服务(一个仅用于资源) 。我需要正在运行的表,它有很多数据,备份和恢复到另一个表的成本太高,很多用户可能会受到影响。

那么,我如何告诉 Cloud Formation Stack 我正在更新该表,而不是尝试创建它?如何跟踪 Cloud Formation Stack 上的服务?而且,我如何防止在没有资源的情况下部署具有资源的服务?

这种情况的最佳解决方案是什么?希望我的问题足够清楚,可以理解。

4

3 回答 3

7

没有相关的问题test2

因为test1,你可以好sls deploy很多次。

但是如果你运行sls remove,当 dynamodb 设置为 Retain inserverless.yml时,dynamodb 表不会被删除。所以你不能用 再次创建它sls deploy,因为同名的资源是存在的。这是 aws cloudformation 中的设计。

您已经找到了跳过资源的新功能的开放票。我们必须等待该功能被开发和合并。我也在等待同样的解决方案。去那里投票吧!

在当前情况下,您必须备份 dynamodb,将其销毁,然后运行sls deploy,如果真的很重要,则将其恢复。

我通常使用变量进行管理,例如

DeletionPolicy: ${self:custom.${self:custom.stage}.deletion_policy}

为不同环境定制:

custom
  dev:
    deletion_policy: Delete
  prod:
    deletion_policy: Retain
于 2017-11-28T19:39:10.783 回答
1

只是为了澄清一点,尽管您有 2 个 serverless.yml 文件,但由于两者(沙盒核心)的服务名称相同,test1test2的部署将影响相同的云形成模板。

这意味着当您部署test2时,您会故意从模板中删除 Dynamo Tables 的轨道,并且在test1的后续部署中, Cloud Formation 将无法创建具有相同名称的资源(因为您已经从模板中删除了)

如果您想避免数据丢失,将策略设置为Retain应该可以解决问题,但您需要将两个 serverless.yml 合并为一个。然后 DynamoDB 表将永远不会从模板中删除。

可以帮助您解决问题的方法(因为已经使用数据创建了表)是创建表的备份,将联合 serverless.yml 文件部署为包含表的唯一服务,从控制台手动删除表,并使用与Cloud Formation 创建的备份完全相同的名称恢复备份。这将确保您的模板仍然具有对表的 ARN 的引用。

于 2018-07-16T10:33:13.027 回答
0

修复 cloudformation + dynamodb 保留表的正确方法: 您可以将现有资源导入AWS/cloudformation/stacks/my-stack

  1. 复制您在堆栈中部署的模板(模板选项卡)

  2. sls package使用 args ( etc)运行,--stage $stage这样您就可以获得项目主版本生成的 .serverless/cloudformation_template_update_stack.json

  3. 找到“已经存在”的缺失资源(简单的方法,使用 DELETE_SKIPPED 过滤事件) 保留的数据库资源

  4. 将 .serverless/cloudformation_template_update_stack.json 中的资源复制到第1点中找到的模板

  5. 堆栈操作 >> 将资源导入堆栈

  6. 上传模板文件/在空白处添加表名(它们只是在资源本身中)

  7. 验证要执行的操作只是将缺少的表导入堆栈并按 Enter 导入资源验证操作

  8. 看到带有导入的事件 导入资源事件

于 2021-06-30T19:55:04.477 回答