我将根据AWS CloudFormation最佳实践来决定Use Cross-Stack References to Export Shared Resources或Use Nested Stacks to Reuse Common Template Patterns。
但是,除了一些区别外,它们对我来说似乎是相同的:
Fn::ImportValue
,模板位于一个文件夹中。AWS::CloudFormation::Stack
和TemplateURL
。据我搜索,它们之间没有明确的利弊。
我的目标是创建一个父堆栈,该父堆栈将一些stackName
之类的核心变量传递给子堆栈,然后是子堆栈使用ARN
来命名它们的资源,例如Policies
,从而创建共享诸如stackName
或stackNameDynamoDBTable
之类的变量的资源。
答案 0 :(得分:1)
您应该使用跨堆栈引用,因为它是为在堆栈之间传递的用例而创建的。
虽然嵌套堆栈可以工作,但其主要目的是重用模块化组件,例如您在大量堆栈中使用的资源模板,以保存复制粘贴并独立更新堆栈。
答案 1 :(得分:0)
有一种方法可以同时兼顾两个方面。诀窍是使用跨堆栈资源共享,但要使其依赖于使用嵌套堆栈传递的参数。
这是我如何使用此示例,请考虑两个堆栈IAMRoleStack
和ComputeStack
。前者包含所有必需的IAM角色,而后者包含将这些角色应用到的Lambda函数。
Resources:
IAMCustomAdminRoleForLambda:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Policies:
Output:
IAMRoleArnForLambda:
Description: Returns the Amazon Resource Name for the newly created IAM Custom
Role for Lambda function
Value: !GetAtt 'IAMCustomAdminRoleForLambda.Arn'
Export:
Name: !Sub '${AWS::StackName}-IAMRoleArnForLambda'
StackName:
Description: Returns name of stack after deployment
Value: !Sub ${AWS::StackName}
如您所见,我已经导出了IAM角色,但是Name
取决于部署堆栈后计算出的堆栈名称。您可以在docs中了解有关导出输出的更多信息。
在ComputeStack
中,我通过导入来使用此角色。
Resources:
LambdaForCompute:
Type: AWS::Lambda::Function
Properties:
Role: !ImportValue
Fn::Sub: ${StackNameOfIAMRole}-IAMRoleArnForLambda
“嵌套” ComputeStack
和IAMRoleStack
的父堆栈精心安排传递堆栈名称参数。
Resources:
IAMRoleStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Ref IAMRoleStackURL
ComputeStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: !Ref ComputeStackURL
Parameters:
StackNameOfIAMRole: !GetAtt IAMRoleStack.Outputs.StackName
我无法证明最佳实践,但是这种风格使我可以选择要在何处进行协调部署以及要在何处进行单独部署。
我还想指出,这种基于资源类型的模块化对于嵌套堆栈来说不太可行。例如在这种情况下,如果我对10个不同的Lambda函数具有10个不同的角色,则必须通过参数传递这10个角色中的每个角色。使用这种混合样式,我只需要将一个参数传递给堆栈名称。