0 votes
1 view
in AWS by (19.2k points)

We have a CloudFormation template that creates an EC2 instance and a security group (among many other resources), but we need to be able to add some additional pre-existing security groups to that same EC2 instance.

The issue we have is that the number of pre-existing security groups won't always be the same, and we want to have a single template that will handle all cases.

Currently, we have an input parameter that looks like this:

"WebTierSgAdditional": {

  "Type": "String",

  "Default": "",

  "Description": ""

}

We pass into this parameter a comma-delimited string of pre-existing security groups, such as 'sg-abc123,sg-abc456'.

The SecurityGroup tag of the EC2 instance looks like this:

"SecurityGroups": [

  {

    "Ref": "WebSg"

  },

  {

    "Ref": "WebTierSgAdditional"

  }

]

With this code, when the instance gets created, we get this error in the AWS console:

Must use either use group-id or group-name for all the security groups, not both at the same time

The 'WebSg' ref above is one of the security groups being created elsewhere in the template. This same error appears if we pass in a list of group names rather than a list of group Ids through the input parameter.

When we change the "Type" field of the input parameter to be 'CommaDelimitedList', we get an error saying:

Value of property SecurityGroups must be of type List of String

It obviously can't join a list with a string to make it a new list.

When the parameter only contains a single sg id, everything gets created successfully, however, we need to have the capability to add more than just one sg id.

We have tried many different combinations of using Fn::Join within the SecurityGroups tag, but nothing seems to work. What we really need is some sort of 'Explode' function to extract the individual id's from the parameter string.

Does anyone know of a nice way to get this to work?

1 Answer

0 votes
by (44.6k points)

As of now, Fn::Spilt is available and it is possible. Convert two lists into strings with Fn::Join, and then converting the strings back to a list with Fn::Split. Use this:

Parameters:

    WebTierSgAdditional:

        Type: CommaDelimitedList

        Default: ''

        Description: ''

Conditions:

    HasWebTierSgAdditional: !Not [ !Equals [ '', !Select [ 0, !Ref WebTierSgAdditional ] ] ]

Resources:

    WebSg:

        Type: AWS::EC2::SecurityGroup

        Properties:

            # ...

    Ec2Instance:

        Type: AWS::EC2::Instance

        Properties:

            # ...

            SecurityGroupIds: !Split

                  - ','

                  - !Join

                      - ','

                      -   - !Ref WebSg

                          - !If [ HasWebTierSgAdditional, !Join [ ',', !Ref WebTierSgAdditional ], !Ref 'AWS::NoValue' ]

!Split will take a string and split items into a list as separated by a comma.

Welcome to Intellipaat Community. Get your technical queries answered by top developers !


Categories

...