堆栈重构
通过堆栈重构,可以重新组织 CloudFormation 堆栈中的资源,同时保留现有资源属性和数据。您可以在堆栈之间移动资源,将大堆栈拆分为小堆栈,或将多个堆栈合并为一个堆栈。
堆栈重构的工作原理
重构堆栈涉及下列阶段:
-
评估当前基础设施 – 检查现有 CloudFormation 堆栈和资源,以确定堆栈重构的机会。
-
规划重构 – 定义应如何组织资源。应注意相关依赖项、命名惯例和操作限制。这些因素可能会影响 CloudFormation 稍后进行的验证。
-
确定目标堆栈 – 决定要将资源重构到哪些堆栈。您可以在至少 2 个堆栈和最多 5 个堆栈之间移动资源。资源可以在嵌套堆栈之间移动。
-
更新模板 – 更改 CloudFormation 模板以反映计划的更改,例如在模板之间移动资源定义。在此过程中,您可以重命名逻辑 ID。
-
创建堆栈重构 – 提供要重构的堆栈名称和模板列表。
-
检查重构影响并解决任何冲突 – CloudFormation 验证您提供的模板并检查跨堆栈依赖项、存在标签更新问题的资源类型以及资源逻辑 ID 冲突。
如果验证成功,CloudFormation 将生成执行期间发生的重构操作的预览。
如果验证失败,请解决已发现的问题并重试。对于冲突,请提供资源逻辑 ID 映射,显示冲突资源的源和目标。
-
执行重构 – 确认更改符合重构目标后,完成堆栈重构。
-
监控 – 跟踪执行状态以确保操作成功完成。
堆栈重构注意事项
在重构堆栈时,请记住以下几点:
-
重构操作不允许创建新资源、删除资源或更改资源配置。
-
在堆栈重构期间,您不能更改或添加新的参数、条件或映射。一种可能的解决方法是在执行重构之前更新堆栈。
-
您不能将同一资源重构到多个堆栈。
-
您无法重构引用源堆栈和目标堆栈之间的值不同的伪参数的资源,例如
AWS::StackName。 -
CloudFormation 不支持空堆栈。如果重构会导致堆栈没有资源,则必须先向堆栈添加至少一个资源,然后再运行 create-stack-refactor。这可以是像
AWS::SNS::Topic或AWS::CloudFormation::WaitCondition这样的简单资源。例如:Resources: MySimpleSNSTopic: Type: AWS::SNS::Topic Properties: DisplayName: MySimpleTopic -
无论策略允许或拒绝什么,堆栈重构都不支持附加了堆栈策略的堆栈。
用于堆栈重构的 Amazon CLI 命令
用于堆栈重构的 Amazon CLI 命令包括:
-
create-stack-refactory,验证和生成计划更改的预览。
-
describe-stack-refactor,检索堆栈重构操作的状态和详细信息。
-
execute-stack-refactor,完成经过验证的堆栈重构操作。
-
get-template,检索现有堆栈的模板。
-
list-stack-refactors,列出您账户中的所有堆栈重构操作及其当前状态和基本信息。
-
list-stack-refactor-actions,显示重构执行期间 CloudFormation 将对每个堆栈和资源执行的特定操作的预览。
使用 Amazon CLI重构堆栈
使用以下过程通过 Amazon CLI 重构堆栈。
-
使用 get-template 命令检索要重构的堆栈的 CloudFormation 模板。
aws cloudformation get-template --stack-nameStack1拥有模板后,请使用您选择的集成式开发环境 (IDE) 对其进行更新,以便使用所需的结构和资源组织。
-
使用 create-stack-refactor 命令,为要重构的堆栈提供堆栈名称和更新的模板。包括
--enable-stack-creation选项以允许 CloudFormation 创建新堆栈(如果它们尚不存在)。aws cloudformation create-stack-refactor \ --stack-definitions \ StackName=Stack1,TemplateBody@=file://template1-updated.yaml\ StackName=Stack2,TemplateBody@=file://template2-updated.yaml\ --enable-stack-creation该命令会返回
StackRefactorId,您将在后续步骤中使用它。{ "StackRefactorId": "9c384f70-4e07-4ed7-a65d-fee5eb430841" }如果在模板验证期间检测到冲突(您可以在下一步中确认),请使用带有
--resource-mappings选项的 create-stack-refactor 命令。aws cloudformation create-stack-refactor \ --stack-definitions \ StackName=Stack1,TemplateBody@=file://template1-updated.yaml\ StackName=Stack2,TemplateBody@=file://template2-updated.yaml\ --enable-stack-creation \ --resource-mappingsfile://resource-mapping.json下面是一个
resource-mapping.json示例文件。[ { "Source": { "StackName": "Stack1", "LogicalResourceId": "MySNSTopic" }, "Destination": { "StackName": "Stack2", "LogicalResourceId": "MyLambdaSNSTopic" } } ] -
使用 describe-stack-refactor 命令确保
Status为CREATE_COMPLETE。这确认验证是否已完成。aws cloudformation describe-stack-refactor \ --stack-refactor-id9c384f70-4e07-4ed7-a65d-fee5eb430841输出示例:
{ "StackRefactorId": "9c384f70-4e07-4ed7-a65d-fee5eb430841", "StackIds": [ "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf", "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b" ], "ExecutionStatus": "AVAILABLE", "Status": "CREATE_COMPLETE" } -
使用 list-stack-refactor-actions 命令预览将执行的特定操作。
aws cloudformation list-stack-refactor-actions \ --stack-refactor-id9c384f70-4e07-4ed7-a65d-fee5eb430841输出示例:
{ "StackRefactorActions": [ { "Action": "MOVE", "Entity": "RESOURCE", "PhysicalResourceId": "MyTestLambdaRole", "Description": "No configuration changes detected.", "Detection": "AUTO", "TagResources": [], "UntagResources": [], "ResourceMapping": { "Source": { "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf", "LogicalResourceId": "MyLambdaRole" }, "Destination": { "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b", "LogicalResourceId": "MyLambdaRole" } } }, { "Action": "MOVE", "Entity": "RESOURCE", "PhysicalResourceId": "MyTestFunction", "Description": "Resource configuration changes will be validated during refactor execution.", "Detection": "AUTO", "TagResources": [ { "Key": "aws:cloudformation:stack-name", "Value": "Stack2" }, { "Key": "aws:cloudformation:logical-id", "Value": "MyFunction" }, { "Key": "aws:cloudformation:stack-id", "Value": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b" } ], "UntagResources": [ "aws:cloudformation:stack-name", "aws:cloudformation:logical-id", "aws:cloudformation:stack-id" ], "ResourceMapping": { "Source": { "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf", "LogicalResourceId": "MyFunction" }, "Destination": { "StackName": "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b", "LogicalResourceId": "MyFunction" } } } ] } -
检查并确认更改后,使用 execute-stack-refactor 命令完成堆栈重构操作。
aws cloudformation execute-stack-refactor \ --stack-refactor-id9c384f70-4e07-4ed7-a65d-fee5eb430841 -
使用 describe-stack-refactor 命令监视执行状态。
aws cloudformation describe-stack-refactor \ --stack-refactor-id9c384f70-4e07-4ed7-a65d-fee5eb430841输出示例:
{ "StackRefactorId": "9c384f70-4e07-4ed7-a65d-fee5eb430841", "StackIds": [ "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack1/3e6a1ff0-94b1-11f0-aa6f-0a88d2e03acf", "arn:aws:cloudformation:us-east-1:123456789012:stack/Stack2/5da91650-94b1-11f0-81cf-0a23500e151b" ], "ExecutionStatus": "SUCCEEDED", "Status": "COMPLETE" }
资源限制
-
堆栈重构仅支持
provisioningType为FULLY_MUTABLE的资源类型,您可以使用 describe-type 命令进行检查。 -
CloudFormation 将在重构创建期间验证资源资格,并在 describe-stack-refactor 命令的输出中报告任何不受支持的资源。
-
以下资源不支持堆栈重构:
AWS::ACMPCA::CertificateAWS::ACMPCA::CertificateAuthorityAWS::ACMPCA::CertificateAuthorityActivationAWS::ApiGateway::BasePathMappingAWS::ApiGateway::MethodAWS::AppConfig::ConfigurationProfileAWS::AppConfig::DeploymentAWS::AppConfig::EnvironmentAWS::AppConfig::ExtensionAWS::AppConfig::ExtensionAssociationAWS::AppStream::DirectoryConfigAWS::AppStream::StackFleetAssociationAWS::AppStream::StackUserAssociationAWS::AppStream::UserAWS::BackupGateway::HypervisorAWS::CertificateManager::CertificateAWS::CloudFormation::CustomResourceAWS::CloudFormation::MacroAWS::CloudFormation::WaitConditionAWS::CloudFormation::WaitConditionHandleAWS::CodeDeploy::DeploymentGroupAWS::CodePipeline::CustomActionTypeAWS::Cognito::UserPoolRiskConfigurationAttachmentAWS::Cognito::UserPoolUICustomizationAttachmentAWS::Cognito::UserPoolUserToGroupAttachmentAWS::Config::ConfigRuleAWS::Config::ConfigurationRecorderAWS::Config::DeliveryChannelAWS::DataBrew::DatasetAWS::DataBrew::JobAWS::DataBrew::ProjectAWS::DataBrew::RecipeAWS::DataBrew::RulesetAWS::DataBrew::ScheduleAWS::DataZone::DataSourceAWS::DataZone::EnvironmentAWS::DataZone::EnvironmentBlueprintConfigurationAWS::DataZone::EnvironmentProfileAWS::DataZone::ProjectAWS::DataZone::SubscriptionTargetAWS::DirectoryService::MicrosoftADAWS::DynamoDB::GlobalTableAWS::EC2::LaunchTemplateAWS::EC2::NetworkInterfacePermissionAWS::EC2::SpotFleetAWS::EC2::VPCDHCPOptionsAssociationAWS::EC2::VolumeAttachmentAWS::EMR::ClusterAWS::EMR::InstanceFleetConfigAWS::EMR::InstanceGroupConfigAWS::ElastiCache::CacheClusterAWS::ElastiCache::ReplicationGroupAWS::ElastiCache::SecurityGroupAWS::ElastiCache::SecurityGroupIngressAWS::ElasticBeanstalk::ConfigurationTemplateAWS::ElasticLoadBalancing::LoadBalancerAWS::ElasticLoadBalancingV2::ListenerCertificateAWS::Elasticsearch::DomainAWS::FIS::ExperimentTemplateAWS::Glue::SchemaAWS::GuardDuty::IPSetAWS::GuardDuty::PublishingDestinationAWS::GuardDuty::ThreatIntelSetAWS::IAM::AccessKeyAWS::IAM::UserToGroupAdditionAWS::ImageBuilder::ComponentAWS::IoT::PolicyPrincipalAttachmentAWS::IoT::ThingPrincipalAttachmentAWS::IoTFleetWise::CampaignAWS::IoTWireless::WirelessDeviceImportTaskAWS::Lambda::EventInvokeConfigAWS::Lex::BotVersionAWS::M2::ApplicationAWS::MSK::ConfigurationAWS::MSK::ServerlessClusterAWS::Maester::DocumentTypeAWS::MediaTailor::ChannelAWS::NeptuneGraph::PrivateGraphEndpointAWS::Omics::AnnotationStoreAWS::Omics::ReferenceStoreAWS::Omics::SequenceStoreAWS::OpenSearchServerless::CollectionAWS::OpsWorks::AppAWS::OpsWorks::ElasticLoadBalancerAttachmentAWS::OpsWorks::InstanceAWS::OpsWorks::LayerAWS::OpsWorks::StackAWS::OpsWorks::UserProfileAWS::OpsWorks::VolumeAWS::PCAConnectorAD::ConnectorAWS::PCAConnectorAD::DirectoryRegistrationAWS::PCAConnectorAD::TemplateAWS::PCAConnectorAD::TemplateGroupAccessControlEntryAWS::Panorama::PackageVersionAWS::QuickSight::ThemeAWS::RDS::DBSecurityGroupAWS::RDS::DBSecurityGroupIngressAWS::Redshift::ClusterSecurityGroupAWS::Redshift::ClusterSecurityGroupIngressAWS::RefactorSpaces::EnvironmentAWS::RefactorSpaces::RouteAWS::RefactorSpaces::ServiceAWS::RoboMaker::RobotApplicationAWS::RoboMaker::SimulationApplicationAWS::Route53::RecordSetAWS::Route53::RecordSetGroupAWS::SDB::DomainAWS::SageMaker::InferenceComponenAWS::ServiceCatalog::PortfolioPrincipalAssociationAWS::ServiceCatalog::PortfolioProductAssociationAWS::ServiceCatalog::PortfolioShareAWS::ServiceCatalog::TagOptionAssociationAWS::ServiceCatalogAppRegistry::AttributeGroupAssociationAWS::ServiceCatalogAppRegistry::ResourceAssociationAWS::StepFunctions::StateMachineVersionAWS::Synthetics::CanaryAWS::VoiceID::DomainAWS::WAF::ByteMatchSetAWS::WAF::IPSetAWS::WAF::RuleAWS::WAF::SizeConstraintSetAWS::WAF::SqlInjectionMatchSetAWS::WAF::WebACLAWS::WAF::XssMatchSetAWS::WAFv2::IPSetAWS::WAFv2::RegexPatternSetAWS::WAFv2::RuleGroupAWS::WAFv2::WebACLAWS::WorkSpaces::Workspace