使用DeletionPolicy创建的无服务器服务更新Dynamodb表保留

时间:2017-11-28 16:34:52

标签: amazon-web-services amazon-dynamodb amazon-cloudformation serverless-framework serverless

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

An error occurred: tableX - TableX already exists.

假设我有两个" serverless.yml "文件,都具有相同的服务名称。其中一个(让我们称之为" test1 ")拥有资源(DynamoDB表),另一个没有#(" TEST2 &#34)。像下面的片段一样:

测试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

的Test2

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 deploy" test2 "有其他功能但没有任何资源(DynamoDB表),他做了预期的事情:跳过删除表。

但是,当我部署" test1 "再一次,他没有认识到桌子,他开始创造"创造"现有的表而不是更新它们,并且无法部署。

我需要删除的表格,并且需要服务上的功能。看起来Cloud Formation从第一次部署中失去了创建表的跟踪。

我没有像在github thread上所说的那样分开服务(仅限资源)。 我需要运行的表,它有大量数据,而且备份和恢复到另一个表的成本太高,很多用户可能会受到影响。

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

这个案例的最佳解决方案是什么?希望我的问题清楚明白。

3 个答案:

答案 0 :(得分:6)

没有与test2相关的问题。

对于test1,您可以多次sls deploy

但是如果你运行sls remove,当Retain中的dynamodb设置为serverless.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

答案 1 :(得分:1)

为了澄清这一点,尽管您有2个serverless.yml文件,因为 test1 test2 的部署(沙盒核心)的服务名称是相同的strong>将影响相同云形成模板。

这意味着当您部署 test2 时,您故意从模板中删除了Dynamo Tables的轨迹,并且在随后的 test1 部署中,Cloud Formation将无法创建一个具有相同名称的资源(就像您已经从模板中删除的一样)

如果要避免数据丢失,可以将策略设置为保留应该可以,但是您需要将两个serverless.yml合并为一个。这样DynamoDB表将永远不会从模板中删除。

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

答案 2 :(得分:0)

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

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

  2. 使用参数(sls package 等)运行 --stage $stage,以便为项目的主版本获取生成的 .serverless/cloudformation_template_update_stack.json

  3. 找到“已经存在”的缺失资源(简单的方法,使用 DELETE_SKIPPED 过滤事件) RETAINED DATABASE RESOURCES

  4. 将资源从 .serverless/cloudformation_template_update_stack.json 复制到在点 1

    中找到的模板
  5. 堆栈操作 >> 将资源导入堆栈

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

  7. 验证要执行的操作只是将缺失的表导入堆栈并按 Enter import resource validation actions

  8. 看到带有导入的事件 import resource events