问题
I have a rather complex set of CloudFormation templates that I use for provisioning the different environments of our infrastructure. However I recently got the request to tag the created resources with a rather extensive list of tags (like 15).
Hardcoding the tags into each of the template file doesn't seem like a good idea to me. I would rather create the list of tags once and refer to them for every taggeable resource. Problem is: I am not even sure this is possible. Do you know of any way that a reusable list of tags can be achieved?
I want to write this:
ECSAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
...
Tags: !Ref ElTags
rather than
ECSAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
...
Tags: !Ref ElTags
- Key: Name
Value: !Join ["-", [!Ref EnvironmentName, 'ecs-as-group'] ]
PropagateAtLaunch: true
- Key: TEAM
Value: !Ref TeamName
PropagateAtLaunch: true
回答1:
This is possible using Fn::Transform function and AWS macro AWS::Include.
Fn::Transformspecifies a macro to perform custom processing on part of a stack template
More about Fn::Transform on https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-transform.html
AWS::Include is an AWS CloudFormation macro which inserts a code snippet anywhere in your template.
More about AWS::Include on https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/create-reusable-transform-function-snippets-and-add-to-your-template-with-aws-include-transform.html
You can reuse your tags that way:
Resources:
TestSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'SG for testing'
GroupName: testSG
SecurityGroupIngress:
- CidrIp: '0.0.0.0/0'
FromPort: 80
IpProtocol: tcp
ToPort: 80
'Fn::Transform':
Name: AWS::Include
Parameters:
Location: 's3://bucket-name/tags.yaml'
TestRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess'
RoleName: testRole
'Fn::Transform':
Name: AWS::Include
Parameters:
Location: 's3://bucket-name/tags.yaml'
Your tags will be in a different template which will be placed on an S3 Bucket. This is the content of the file tags.yaml:
Tags:
- Key: tag1
Value: value1
- Key: tag2
Value: value2
- Key: tag3
Value: value3
- Key: tag4
Value: value4
- Key: tag5
Value: value5
- Key: tag6
Value: value6
- Key: tag7
Value: value7
- Key: tag8
Value: value8
- Key: tag19
Value: value9
- Key: tag10
Value: value10
回答2:
You can easily reuse tags if you don't pass them to the template but instead reference them during deployment. The tags will be propagated to all ressources of the stack. A command similar to the one below might meet your needs:
aws cloudformation create-stack --stack-name mystack \
--template-body file://my_template.yaml --tags file://my_tags.json
The file my_tags.json is of the format
[
{"Key": "mytag", "Value": "val"},
...
]
Alternatively, you could deploy your stack through CodePipeline and define the tags in the template configuration
来源:https://stackoverflow.com/questions/46425305/reuse-list-of-cloudformation-tags