当我尝试更新一个导出变量(该变量被另一个 AWS CloudFormation 堆栈使用)时,我收到一条错误消息。这个错误是: “无法更新导出变量,原因是另一个堆栈正在使用该变量。”
简述
要解决此错误,请使用 AWS Systems Manager Parameter Store 中的 SSM 参数在 CloudFormation 堆栈之间共享值。SSM 参数在一个堆栈(stackA)中存储另一个堆栈(stackB)可以使用的值。
当您使用 SSM 参数时,两个 CloudFormation 堆栈之间没有依赖关系。这是因为 AWS Systems Manager Parameter Store 存储变量。
**注意:**CloudFormation 支持多种 SSM 参数类型。
解决方法
1. 创建基于以下模板的 CloudFormation 堆栈(stackA):
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"AvailabilityZone": {
"Description": "Amazon EC2 instance Availability Zone",
"Type": "String"
},
"AMIId": {
"Description": "The Amazon Machine Image id",
"Type": "String"
},
"InstanceType": {
"Description": "The Type of instance",
"Type": "String"
}
},
"Resources": {
"myinstance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": {
"Fn::GetAtt": ["BasicParameter", "Value"]
},
"ImageId": {
"Ref": "AMIId"
},
"InstanceType": {
"Ref": "InstanceType"
}
}
},
"BasicParameter": {
"Type": "AWS::SSM::Parameter",
"Properties": {
"Name": "AvailabilityZone",
"Type": "String",
"Value": {
"Ref": "AvailabilityZone"
}
}
}
}
}
前面的模板创建了一个实例和一个 SSM 参数。SSM 参数的值设置为所创建实例的可用区。stackA 创建一个 SSM Parameter Store,名称设置为 AvailabilityZone,值设置为 us-east-2a。
**注意:**您必须为 SSM 参数设置一个唯一的名称。
2. 创建另一个基于以下模板的 CloudFormation 堆栈(stackB)。
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"AMIId": {
"Description": "The Amazon Machine Image id",
"Type": "String"
},
"InstanceType": {
"Description": "The Type of instance",
"Type": "String"
},
"AvailabilityZone": {
"Description": "Amazon EC2 instance Availablity Zone",
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "AvailabilityZone"
}
},
"Mappings": {},
"Conditions": {},
"Resources": {
"myinstance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": {
"Ref": "AvailabilityZone"
},
"ImageId": {
"Ref": "AMIId"
},
"InstanceType": {
"Ref": "InstanceType"
}
}
}
}
}
此模板使用 stackA 在步骤 1 中创建的 SSM 参数。
注意:要使用此参数,必须在 stackB 中声明一个参数。将类型设置为 AWS::SSM::Parameter::Value<String>。然后,从 stackB 创建的实例将在 us-east-2a 可用区启动。
3. 要更新 stackA,请将 AvailabilityZone 参数从 us-east-2a 更改为 us-east-2b。
4. 从 stackA 启动该实例,该实例位于与 stackB 相同的更新可用区中。实例将会被替换,然后在 us-east-2b 可用区启动。