Bram Vandewalle
Bram Vandewalle

Reputation: 1654

Reuse list of CloudFormation tags

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

Upvotes: 15

Views: 3933

Answers (2)

Michael Panchenko
Michael Panchenko

Reputation: 461

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

Upvotes: 8

Fagner Fonseca
Fagner Fonseca

Reputation: 293

This is possible using Fn::Transform function and AWS macro AWS::Include.

Fn::Transform specifies 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

Upvotes: 4

Related Questions