How to loop through values in a CloudFormation template
Solution 1
https://palletsprojects.com/p/jinja/ is another option for adding for-loops to CloudFormation templates. You will need to render the Jinja template before passing it to CloudFormation, as CloudFormation itself cannot currently process Jinja templates.
{% for country in ["fr", "us", "gb"] %}
{{country}}_myprod_bucket:
Type: AWS::S3::Bucket
{% endfor %}
Rendering that Jinja snippet would produce:
fr_myprod_bucket:
Type: AWS::S3::Bucket
us_myprod_bucket:
Type: AWS::S3::Bucket
gb_myprod_bucket:
Type: AWS::S3::Bucket
Solution 2
You are correct — there is no concept of a loop in AWS CloudFormation.
AWS CloudFormation is a declarative language. It describes the output desired, but does not state how the outcome should be achieved.
To perform logic like you describe, you will need to create an AWS Lambda-backed Custom Resource. CloudFormation will call the supplied Lambda function, which can then make any desired API calls.
The the template is only creating these buckets, then there is actually no benefit in using CloudFormation. Just run a program or script that does it directly.
Solution 3
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
Solution 4
An alternative would be to use CDK, which wraps CloudFormation in Typescript, Python, Java, .NET or Golang.
Njoi
Updated on June 05, 2022Comments
-
Njoi almost 2 years
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 createfr_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?
-
Shabin Muhammed about 4 yearsThis requires installing the Count macro in your AWS account. Refer : github.com/awslabs/aws-cloudformation-templates/tree/master/aws/…
-
Tom over 2 yearsCDK only let's you have flow-control when compiling, not at run-time.
-
D.J.Duff about 2 years@Tom Yes I should have clarified that in order to use CDK for this you would have to use CDK a level above the CloudFormation. The "compiling" (synth) can happen when you like though. And you can bring (docs.aws.amazon.com/cdk/v2/guide/use_cfn_template.html) CloudFormation in to your CDK .