I want to pass CommaDelimitedList parameters to nested stacks in AWS CloudFormation.
Short description
You can't pass values of type CommaDelimitedList to a nested stack. Instead, use the Fn::Join intrinsic function in your parent stack to convert type CommaDelimitedList to type String.
Resolution
The following example shows you how to pass a list of SecurityGroupIds from a parent stack to a nested stack.
1. Open the JSON or YAML file of your parent stack, and then set the Type of SecurityGroupIds to CommaDelimitedList.
In the Resources section of the JSON file, the Fn::Join function returns the combined string. In the Resources section of the YAML file, the !Join function returns the combined string. In both JSON and YAML files, the combined string converts the SecurityGroupIds parameter type from CommaDelimitedList to String.
Example parent JSON file:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"SubnetId": {
"Type": "AWS::EC2::Subnet::Id"
},
"SecurityGroupIds": {
"Type": "List<AWS::EC2::SecurityGroup::Id>"
},
"KeyName": {
"Type": "AWS::EC2::KeyPair::KeyName"
},
"ImageId": {
"Type": "String"
}
},
"Resources": {
"Instance": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"TemplateURL": "https://s3.amazonaws.com/cloudformation-templates-us-east-2/nested.yml",
"Parameters": {
"SubnetId": {
"Ref": "SubnetId"
},
"SecurityGroupIds": {
"Fn::Join": [
",",
{
"Ref": "SecurityGroupIds"
}
]
},
"KeyName": {
"Ref": "KeyName"
},
"ImageId": {
"Ref": "ImageId"
}
}
}
}
}
}
Example parent YAML file:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
SubnetId:
Type: 'AWS::EC2::Subnet::Id'
SecurityGroupIds:
Type: 'List<AWS::EC2::SecurityGroup::Id>'
KeyName:
Type: 'AWS::EC2::KeyPair::KeyName'
ImageId:
Type: String
Resources:
Instance:
Type: 'AWS::CloudFormation::Stack'
Properties:
TemplateURL: 'https://s3.amazonaws.com/cloudformation-templates-us-east-2/nested.yml'
Parameters:
SubnetId: !Ref SubnetId
SecurityGroupIds: !Join
- ','
- !Ref SecurityGroupIds
KeyName: !Ref KeyName
ImageId: !Ref ImageId
Note: If you pass two subnets, such as ["subnet-aaaa, subnet-bbbb"], the output of Fn::Join is {"subnet-aaaa, subnet-bbbb"}.
2. In the JSON or YAML file of your nested stack, set the Type of SecurityGroupIds to CommaDelimitedList.
Example nested JSON file:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"SubnetId": {
"Type": "String"
},
"SecurityGroupIds": {
"Type": "CommaDelimitedList"
},
"KeyName": {
"Type": "String"
},
"ImageId": {
"Type": "String"
}
},
"Resources": {
"Ec2instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": {
"Ref": "ImageId"
},
"KeyName": {
"Ref": "KeyName"
},
"SecurityGroupIds": {
"Ref": "SecurityGroupIds"
},
"SubnetId": {
"Ref": "SubnetId"
}
}
}
}
}
Example nested YAML file:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
SubnetId:
Type: String
SecurityGroupIds:
Type: CommaDelimitedList
KeyName:
Type: String
ImageId:
Type: String
Resources:
Ec2instance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: !Ref ImageId
KeyName: !Ref KeyName
SecurityGroupIds: !Ref SecurityGroupIds
SubnetId: !Ref SubnetId
Note: In the nested stack, the combined string from the parent stack is passed to SecurityGroupIds as CommaDelimitedList. For example, the value {"sg-aaaaa, sg-bbbbb"} is converted back to ["sg-aaaaa", "sg-bbbbb"]. Therefore, SecurityGroupIds must be directly referenced by SecurityGroupIds: !Ref SecurityGroupIds and not as a list of strings.
Related information
Working with nested stacks
AWS::CloudFormation::Stack