我正在通过 CloudFormation 创建一些 dynamodb 表,这些表将由 Python lambdas 访问。看起来我有两个选择来命名这些表 - 让 CF 来做,因此在名称上放一堆随机字符,或者明确指定名称,这给了我一个易于访问的名称,但意味着我无法通过 CF 进行更改,除非替换表。
我认为没有简单名称的缺点是,我要么必须有一个对于我运行 CF 的每个帐户都不同的配置文件(因为它们会有不同的随机名称),要么我必须编写代码来检测每次调用 lambda 时的名称。
那么你们都怎么做呢?明确名称,然后处理更改的替换,还是让 CF 来做,并在代码中处理 DB 名称发现?或者其他我没有想到的?
答案1
CloudFormation 允许您为堆栈配置创建模板,因此我建议将其视为模板。您可能不希望在模板中使用硬编码值。
有几种方法可以使名称动态化,其中一种是 - 不指定名称,AWS 将为您生成一个唯一的名称。其他 - 使用!Sub
或!ImportValue
/!Ref
内部函数来构建动态值。即:TableName: !Sub "${AWS::StackName}-my-unique-content"
每个堆栈始终是唯一的,但也将包含有关内部内容的一些描述性信息。
如果你的 Python lambdas 在同一个堆栈中,请将表名作为环境变量传入(在我看来这是最简单的方法)
PythonFunction:
Type: "AWS::Serverless::Function"
Properties:
Environment:
Variables:
TABLE_NAME: !Ref DynamoTableResource
如果它们是在另一个堆栈中创建的,但在同一个帐户中 - 最好的机会是将表名导出为Output
,然后通过调用!ImportValue
函数引用它。例如:
dynamostack.yaml
Outputs:
DynamoDBResource:
Description: "DynamoDB table"
Value: !Ref DynamoTableResource
Export:
Name: !Sub "${AWS::StackName}-exported-dynamo-table-name"
在另一个堆栈中:
functionstack.yaml
PythonFunction:
Type: "AWS::Serverless::Function"
Properties:
Environment:
Variables:
TABLE_NAME: !ImportValue "dynamostack-exported-dynamo-table-name"
但是要小心堆栈间的引用,否则最终可能会出现到处都是循环依赖的情况。
另一种选择是利用 CloudFormation 模板中的参数并通过它们传递 DynamoDB 表名,然后!Ref
在 lambda 函数中引用它们(通过使用)。