如何为每个 ElasticBeanstalk 环境唯一的 DynamoDB table 名称添加前缀

How to prefix DynamoDB table names unique to each ElasticBeanstalk environment

使用 DynamoDB 的标准模式是通过在 table 名称前加上任何特定于环境的字符串来分隔每个环境使用的数据。

我认为使用 ElasticBeanstalk 和 .ebextensions 中的 CloudFormation 配置可以轻松做到这一点。但是 - 至少对于我的平台(Java 8 运行 on 64bit Amazon Linux) - 至少 - 情况似乎并非如此。

我天真的实现是为每个环境添加一个环境 属性 (DB_PREFIX),然后在 .ebextensions 中调整我的 table 创建配置,如下所示:

Resources:
  UserTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName:
        Fn::Join:
          - '_'
          - - ${env:DB_PREFIX}
            - 'User'
      KeySchema:
        HashKeyElement: {AttributeName: id, AttributeType: S}
      ProvisionedThroughput: {ReadCapacityUnits: 1, WriteCapacityUnits: 1}

这行不通,可能是因为至少对于我的平台而言,环境属性未作为 OS 环境变量提供(参见 )。

我也考虑过根据环境名称有条件地设置 AWS 环境 属性(不是一个很好的解决方案,因为它不能很好地扩展)它可能是 acceptable.

有没有人已经使用了解决此类问题的模式?

可能不是您要找的东西,但我不是依靠 cloudformation 来处理环境差异,而是使用一个非常简单的构建系统来做到这一点。假设您有两个环境,一个 dev 和一个 prod。我的构建系统将输出两个完全不同的 dists:

/dev 
   .ebextensions
/prod
   .ebextensions

在 /dev .ebextensions 文件中,当然所有内容都带有前缀 dev-。在 /prod .ebextensions 中,所有内容都以 prod- 为前缀。我使用 gulp 和 nunjucks 来执行此操作,但那里有很多选项。所以我不必担心 cloudformation 如何处理事情,我知道我的输出正是我想要的。我什至可以通过一些简单的测试来验证 /dev 和 /prod 的内容。

在你的例子中,你会在 /dev 输出文件夹中得到这个:

Fn::Join:
      - '_'
      - - dev
        - 'User'

这在 /prod 中:

Fn::Join:
      - '_'
      - - prod
        - 'User'

关于我如何做的更多细节:

干脆不要设置名称。 CloudFormation 将为您 select 一个包含堆栈名称的唯一名称。另一种选择是自己使用 ${AWS::StackName}

Resources:
  UserTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName:
        Fn::Sub: ${AWS::StackName}_User
      KeySchema:
        HashKeyElement: {AttributeName: id, AttributeType: S}
      ProvisionedThroughput: {ReadCapacityUnits: 1, WriteCapacityUnits: 1}