Reputation: 445
I am trying to pass a list of comma separated parameters in an AWS CloudFormation template and create multiple Amazon S3 buckets based on those values.
I have a requirement where I will be passing a comma separated- list of country names and then the CloudFormation template would build that many S3 buckets (based on the names of countries passed in parameters).
For example, if I pass fr,us,gb
in a parameter, the stack should create fr_myprod_bucket
, us_myprod_bucket
, gb_myprod_bucket
.
I know there is no for loop in CloudFormation, so not sure how I can achieve this?
Upvotes: 20
Views: 40370
Reputation: 4638
https://palletsprojects.com/p/jinja/ is another option for for-loops in CloudFormation templates. Render Jinja templates before passing them to CloudFormation, as CloudFormation itself cannot currently process Jinja.
{% for country in ["fr", "us", "gb"] %}
{{country}}_myprod_bucket:
Type: AWS::S3::Bucket
{% endfor %}
That Jinja snippet produces:
fr_myprod_bucket:
Type: AWS::S3::Bucket
us_myprod_bucket:
Type: AWS::S3::Bucket
gb_myprod_bucket:
Type: AWS::S3::Bucket
Upvotes: 6
Reputation: 373
AWS now supports For loop in cloudformation for resources
AWSTemplateFormatVersion: 2010-09-09
Transform: 'AWS::LanguageExtensions'
Resources:
'Fn::ForEach::Bucket':
- BucketName
- - 'fr'
- 'gb'
- 'us'
- 'MyBucket${BucketName}': ##resource name
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Sub ${BucketName}_myprod_bucket
# Require CAPABILITY_AUTO_EXPAND, IAM with custom resources capability
Upvotes: 1
Reputation: 2257
This is now possible using Fn::ForEach
. See the announcement and documentation for details.
You could do something like below:
AWSTemplateFormatVersion: 2010-09-09
Description: Create multiple Amazon S3 buckets using prefix from a comma delimited list
Transform: AWS::LanguageExtensions
Parameters:
CountryNames:
Description: Country prefix names
Default: "fr,gb,us"
Type: CommaDelimitedList
Resources:
'Fn::ForEach::S3Buckets':
- ParamName
- !Ref CountryNames
- 'Bucket${ParamName}':
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub '${ParamName}-my-prod-bucket-${AWS::Region}-${AWS::AccountId}'
## Add more configuration parameters for the buckets here...
Upvotes: 13
Reputation: 1575
An alternative would be to use CDK, which wraps CloudFormation in Typescript, Python, Java, .NET or Golang.
Upvotes: 4
Reputation: 4825
Use the Count macro!
The Count macro provides a template-wide Count property for CloudFormation resources. It allows you to specify multiple resources of the same type without having to cut and paste.
Thus, the the following:
AWSTemplateFormatVersion: "2010-09-09"
Transform: Count
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
Tags:
- Key: TestKey
Value: my bucket %d
Count: 3
Would be equivalent to:
AWSTemplateFormatVersion: "2010-09-09"
Resources:
Bucket1:
Type: AWS::S3::Bucket
Properties:
Tags:
- Key: TestKey
Value: my bucket 1
Bucket2:
Type: AWS::S3::Bucket
Properties:
Tags:
- Key: TestKey
Value: my bucket 2
Bucket3:
Type: AWS::S3::Bucket
Properties:
Tags:
- Key: TestKey
Value: my bucket 3
Upvotes: 10