我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
介绍 Amazon CloudFormation 堆栈重构
导言
随着您的云基础设施的发展和发展,您可能会发现需要重新组织您的 Amazon CloudFormation 堆栈以改善管理、提高模块化程度或适应不断变化的业务需求。CloudFormation 现在提供了一项强大的功能,允许您在堆栈之间移动资源。在这篇文章中,我们将探讨堆栈重构的过程以及它如何帮助您维护组织良好、高效的云基础架构。
了解堆栈重构
堆栈重构是通过将资源从一个堆栈移动到另一个堆栈或在同一堆栈中使用新的逻辑 ID 重命名资源来重组 CloudFormation 堆栈的过程。当你想做以下事情时,此功能特别有用:
- 将大型单片堆栈拆分成更小、更易于管理的堆栈
- 重新组织资源以更好地与您的应用程序架构或组织结构保持一致
- 重命名资源的逻辑 ID 以提高模板的可读性
示例场景
为了演示这种能力,你将创建一个堆栈,然后将它的一些资源移动到一个新的堆栈中。您将评估需要利用的新 CLI 命令来实现这一点。在本示例中,您将拥有一个 SNS 主题,其中包含一个 lambda 函数订阅您的 SNS 主题。随着您对 SNS 主题的使用范围的扩展,您希望将订阅拆分为不同的堆栈。
- 使用您的起始模板创建一个
before.yaml名为的新模板:AWSTemplateFormatVersion: "2010-09-09" Resources: Topic: Type: AWS::SNS::Topic MyFunction: Type: AWS::Lambda::Function Properties: FunctionName: my-function Handler: index.handler Runtime: python3.12 Code: ZipFile: | import json def handler(event, context): print(json.dumps(event)) return event Role: !GetAtt FunctionRole.Arn Timeout: 30 Subscription: Type: AWS::SNS::Subscription Properties: Endpoint: !GetAtt MyFunction.Arn Protocol: lambda TopicArn: !Ref Topic FunctionInvokePermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction Principal: sns.amazonaws.com FunctionName: !GetAtt MyFunction.Arn SourceArn: !Ref Topic FunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Condition: StringEquals: aws:SourceAccount: !Ref AWS::AccountId ArnLike: aws:SourceArn: !Sub "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:my-function" Policies: - PolicyName: LambdaPolicy PolicyDocument: Version: "2012-10-17" Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - arn:aws:logs:*:*:* Effect: Allow - 使用
before.yaml模板创建新堆栈。aws cloudformation create-stack --stack-name MySns --template-body file://before.yaml --capabilities CAPABILITY_IAM - 使用以下内容创建一个名
afterSns.yaml为的新模板。此模板包含您的 SNS 主题,其中还有一个新的导出内容,用于导出 SNS 主题 ARN。您的其他模板将使用此导出内容来获取所需的 SNS 主题 ARN。AWSTemplateFormatVersion: "2010-09-09" Resources: Topic: Type: AWS::SNS::Topic Outputs: TopicArn: Value: !Ref Topic Export: Name: TopicArn - 使用以下内容创建一个名
afterLambda.yaml为的新模板。此模板包含创建 SNS 主题的 Lambda 订阅所需的所有资源。此模板将切换!Ref Topic为使用通过使用的导出值!ImportValue TopicArn。AWSTemplateFormatVersion: "2010-09-09" Resources: Function: Type: AWS::Lambda::Function Properties: FunctionName: my-function Handler: index.handler Runtime: python3.12 Code: ZipFile: | import json def handler(event, context): print(json.dumps(event)) return event Role: !GetAtt FunctionRole.Arn Timeout: 30 Subscription: Type: AWS::SNS::Subscription Properties: Endpoint: !GetAtt Function.Arn Protocol: lambda TopicArn: !ImportValue TopicArn FunctionInvokePermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction Principal: sns.amazonaws.com FunctionName: !GetAtt Function.Arn SourceArn: !ImportValue TopicArn FunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Condition: StringEquals: aws:SourceAccount: !Ref AWS::AccountId ArnLike: aws:SourceArn: !Sub "arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:my-function" Policies: - PolicyName: LambdaPolicy PolicyDocument: Version: "2012-10-17" Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - arn:aws:logs:*:*:* Effect: Allow - 创建一个名为的资源映射文件
refactor.json来重命名资源的逻辑 ID。此文件定义了重构资源的源和目标堆栈名称以及逻辑 ID。如果逻辑 ID 未更改,则无需指定此文件。[ { "Source": { "StackName": "MySns", "LogicalResourceId": "MyFunction" }, "Destination": { "StackName": "MyLambdaSubscription", "LogicalResourceId": "Function" } } ] - 创建堆栈重构任务。您正在使用 enable-stack-creation 来告知重构能力为我们创建目标堆栈。如果目标堆栈已经存在,则无需提供此选项。
aws cloudformation create-stack-refactor --stack-definitions StackName=MySns,TemplateBody@=file://afterSns.yaml StackName=MyLambdaSubscription,TemplateBody@=file://afterLambda.yaml --enable-stack-creation --resource-mappings file://refactor.json结果:
{ "StackRefactorId": "56b06a9a-72ff-4f87-8205-32111bff83f9" }为以下步骤捕获堆栈重构 ID。
- 评估堆栈重构任务。
aws cloudformation describe-stack-refactor --stack-refactor-id 56b06a9a-72ff-4f87-8205-32111bff83f9结果:
{ "StackRefactorId": "56b06a9a-72ff-4f87-8205-32111bff83f9", "StackIds": [ "arn:aws:cloudformation:<<AWS::Region>>:<<AWS::AccountId>>:stack/MySns/a10bfd30-cc67-11ef-877a-023cc5780193", "arn:aws:cloudformation:<<AWS::Region>>:<<AWS::AccountId>>:stack/MyLambdaSubscription/6d117360-cc68-11ef-ba33-06338dcc9d39" ], "ExecutionStatus": "AVAILABLE", "Status": "CREATE_COMPLETE" }如果你忘记捕获堆栈重构 ID,你可以运行:
aws cloudformation list-stack-refactors你可以列出重构通过运行所做的堆栈操作:
aws cloudformation list-stack-refactor-actions —stack-refactor-id 56b06a9a-72ff-4f87-8205-32111bff83f9您将看到重构将创建一个新的堆栈以及正在移动哪些资源。
{ "StackRefactorActions": [ { "Action": "Move", "Entity": "Resource", "PhysicalResourceId": "MySns-FunctionRole-BMO7ohLu4S6a", "Description": "No configuration changes detected.", "Detection": "Auto", "TagResources": [], "UntagResources": [], "ResourceMapping": { "Source": { "StackName": "arn:aws:cloudformation:<<AWS::Region>>:<<AWS::AccountId>>:stack/MySns/a10bfd30-cc67-11ef-877a-023cc5780193", "LogicalResourceId": "FunctionRole" }, "Destination": { "StackName": "arn:aws:cloudformation:<<AWS::Region>>:<<AWS::AccountId>>:stack/MyLambdaSubscription/6d117360-cc68-11ef-ba33-06338dcc9d39", "LogicalResourceId": "FunctionRole" } } }, { "Action": "Create", "Entity": "Stack", "Description": "Stack arn:aws:cloudformation:<<AWS::Region>>:<<AWS::AccountId>>:stack/MyLambdaSubscription/6d117360-cc68-11ef-ba33-06338dcc9d39 created.", "Detection": "Manual", "TagResources": [], "UntagResources": [], "ResourceMapping": { "Source": {}, "Destination": {} } }, ... - 执行堆栈重构
aws cloudformation execute-stack-refactor --stack-refactor-id 56b06a9a-72ff-4f87-8205-32111bff83f9 - 等待堆栈重构完成。通过执行以下命令来评估堆栈重构状态:
aws cloudformation describe-stack-refactor --stack-refactor-id 56b06a9a-72ff-4f87-8205-32111bff83f9{ "StackRefactorId": "56b06a9a-72ff-4f87-8205-32111bff83f9", "StackIds": [ "arn:aws:cloudformation:<<AWS::Region>>:<<AWS::AccountId>>:stack/MySns/a10bfd30-cc67-11ef-877a-023cc5780193", "arn:aws:cloudformation:<<AWS::Region>>:<<AWS::AccountId>>:stack/MyLambdaSubscription/6d117360-cc68-11ef-ba33-06338dcc9d39" ], "ExecutionStatus": "EXECUTE_COMPLETE", "Status": "CREATE_COMPLETE" }
结论
Amazon CloudFormation 中的堆栈重构代表了基础设施管理的重大进步,为无中断地重组云资源提供了一种更安全、更有效的方式。此功能消除了通过保留策略删除资源然后在重组堆栈时导入资源的传统需求,从而帮助您降低配置错误风险并节省时间。通过这篇文章中演示的示例,你已经了解了如何将单一堆栈拆分成更小的、有针对性的堆栈,同时使用导出和导入来维护堆栈之间的依赖关系。您还探索了新的 CloudFormation CLI 命令,这些命令使堆栈重构成为可能,同时在重组期间保持资源稳定性。
随着基础设施的发展,堆栈重构提供了必要的灵活性,使您的 CloudFormation 堆栈组织适应不断变化的需求,同时保持云资源的完整性。对于希望提高基础架构可维护性并使其资源组织与不断变化的架构模式保持一致的团队而言,这种能力尤其有价值。请记住首先在非生产环境中全面测试您的重构计划,并始终确保您的新堆栈结构保持必要的安全性和访问控制。
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。