AWS CloudFormation: Appending elements to lists

AWS CloudFormation: Appending elements to lists

Short reference on manipulating CloudFormation lists.

In order to add individual elements to a list, we will need to make use of the functions !Split, !Sub and !Join.

First, !Split: takes a string and makes a list out of it, by placing each element separated by the specified delimiter. It takes two parameters: A delimiter (in our case, a single comma, and a source string (for which we make use of the !Sub function). In the above case, we are using this function to pass a list of SecurityGroups, that we make by creating a comma-separated string.

The !Sub function will substitute variables in an input string with specified values. We use this to construct a comma-separated string of elements. It takes two parameters: a string to output, and the substitution to apply. In this case, the output we will get is a,b, where a is a string that we will construct by splitting a list using !Join, using the CloudFormation parameters, and b is the security group built within the CloudFormation template itself.

Lastly, the !Join function does the opposite of !Split: It takes a list of elements, and outputs a string with the specified delimiter.

Example template:

AWSTemplateFormatVersion: "2010-09-09"
Description: "Appending elements to a list in CloudFormation"

Parameters:
  MyVPC:
    Type: "AWS::EC2::VPC::Id"
  MySubnetList:
    Type: "List<AWS::EC2::Subnet::Id>"
  ExistingSG:
    Type: "List<AWS::EC2::SecurityGroup::Id>"

Resources:
  NewALB:
    Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
    Properties:
      Name: "My new ALB"
      Scheme: "internal"
      SecurityGroups: !Split
        - ","
        - !Sub
          - "${existingSgToString},${NewSG}"
          - existingSgToString: !Join [",",!Ref "ExistingSG"]
      Subnets: !Ref "MySubnetList"
  NewSG:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      GroupDescription: "My new security group"
      SecurityGroupIngress:
        - CidrIp: "0.0.0.0/0"
          FromPort: 22
          IpProtocol: "tcp"
          ToPort: 22
      VpcId: !Ref "MyVPC"

In our case, the list is the existing security groups, which is then turned into a string, appended to the new security group, and then converted back into a list again.