能否在引用预定义标签的AWS CloudFormation模板中追加标签?
在CloudFormation模板中结合S3引用标签与自定义追加标签的方法
问题背景
我有一个创建EC2安全组的CloudFormation模板,模板通过AWS::Include引用S3桶中存储的预定义标签文件tags.yaml,模板内容如下:
Resources: EC2SecurityGroup: Type: "AWS::EC2::SecurityGroup" DeletionPolicy: Delete Properties: GroupDescription: Test Security Group. GroupName: !Ref SecurityGroupName SecurityGroupEgress: - Description: Direct traffic to all destinations. CidrIp: "0.0.0.0/0" IpProtocol: -1 SecurityGroupIngress: - Description: Sec. group of LB. FromPort: 80 IpProtocol: tcp SourceSecurityGroupId: sg-xxxxxxxx ToPort: 80 VpcId: !Ref VPCId "Fn::Transform": Name: AWS::Include Parameters: Location: "s3://{bucket-name}/tags.yaml"
尝试直接在模板中添加自定义Tags属性来追加标签时失败,示例如下:
"Fn::Transform": Name: AWS::Include Parameters: Location: "s3://{bucket-name}/tags.yaml" Tags: - Key: TestName Value: DummyVal
问题原因
直接在Properties层级同时放置AWS::Transform和Tags会触发冲突:
- 如果
tags.yaml文件本身包含Tags:键(即外层是完整的Tags属性结构),导入后会和手动添加的Tags:属性重复,CloudFormation不允许同一层级出现重复属性键。 - 如果
tags.yaml是纯标签数组,直接放在Properties下会导致结构错误,因为Properties下的Tags是一个数组属性,而导入的数组会被当作独立属性处理。
解决方案
前提确认
首先确保tags.yaml的内容是纯标签数组(不含外层Tags:键),示例如下:
- Key: Environment Value: Production - Key: Owner Value: DevTeam
修改模板合并标签
在Tags属性内部,使用!Merge(或完整语法Fn::Merge)将导入的标签数组和自定义标签数组合并,这样就能同时包含S3中的预定义标签和自定义追加标签:
Resources: EC2SecurityGroup: Type: "AWS::EC2::SecurityGroup" DeletionPolicy: Delete Properties: GroupDescription: Test Security Group. GroupName: !Ref SecurityGroupName SecurityGroupEgress: - Description: Direct traffic to all destinations. CidrIp: "0.0.0.0/0" IpProtocol: -1 SecurityGroupIngress: - Description: Sec. group of LB. FromPort: 80 IpProtocol: tcp SourceSecurityGroupId: sg-xxxxxxxx ToPort: 80 VpcId: !Ref VPCId Tags: !Merge - !Transform Name: AWS::Include Parameters: Location: "s3://{bucket-name}/tags.yaml" - - Key: TestName Value: DummyVal
若无法修改tags.yaml结构
如果tags.yaml必须保留外层Tags:键(如下所示):
Tags: - Key: Environment Value: Production - Key: Owner Value: DevTeam
可以通过嵌套栈导入标签文件,再提取标签数组合并自定义标签:
Resources: EC2SecurityGroup: Type: "AWS::EC2::SecurityGroup" DeletionPolicy: Delete Properties: GroupDescription: Test Security Group. GroupName: !Ref SecurityGroupName SecurityGroupEgress: - Description: Direct traffic to all destinations. CidrIp: "0.0.0.0/0" IpProtocol: -1 SecurityGroupIngress: - Description: Sec. group of LB. FromPort: 80 IpProtocol: tcp SourceSecurityGroupId: sg-xxxxxxxx ToPort: 80 VpcId: !Ref VPCId Tags: !Merge - !GetAtt [ImportedTags, Tags] - - Key: TestName Value: DummyVal ImportedTags: Type: AWS::CloudFormation::Stack Properties: TemplateURL: "s3://{bucket-name}/tags.yaml"
内容的提问来源于stack exchange,提问作者quldude
相关产品推荐
相关产品推荐

