【问题标题】:Serverless Service update Dynamodb table created with DeletionPolicy retain使用 DeletionPolicy 保留创建的无服务器服务更新 Dynamodb 表
【发布时间】:2018-05-12 04:52:52
【问题描述】:

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

An error occurred: tableX - TableX already exists.

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

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

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    没有与test2相关的问题。

    对于test1,你可以多次sls deploy

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

    【讨论】:

    • 但我不想再次创建它,我想更新表和函数。当我 sls 部署“test2”时,“test1”不再存在,当我再次尝试 sls 部署“test1”时,我无法做到,因为“表已经存在”。试试我放在这里的代码,看看会发生什么。
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

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

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

      7. 确认要执行的操作只是将缺少的表导入堆栈并按 Enter

      8. 查看带有导入的事件

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-09
        • 2018-07-27
        • 1970-01-01
        • 2019-06-30
        • 2020-10-28
        • 2011-02-16
        • 1970-01-01
        相关资源
        最近更新 更多