Recently, we faced the challenge of creating a new S3 bucket in each of a number of specific regions. We have found that we can do this by using a Cloudformation Stack, that deploys a StackSet, that again deploys a Stack for each region.
Sounds confusing? Let me explain. We will create a StackSet that is going to deploy the same Stack template into multiple regions, and if you wish, to multiple AWS accounts as well. And the thing is, we will deploy the StackSet using a Stack.
Prerequisites
Before you start, make sure you set the permissions correctly. Check out the AWS Docs. If the resources you’d like to deploy should end up in the same AWS account as your primary deployment, create all the permissions in the same account. But even though, you have to.
The Cloudformation template
Actually, it’s not a big deal to create a template for a StackSet. There are several guides out there explaining how to do it. But what took us a little more time to figure out, is how to pass a parameter from the parent template through the stack to the child templates.
Here’s the template and how we made it work:
AWSTemplateFormatVersion: '2010-09-09'
Description: Stackset for multiple S3 buckets
Parameters:
env:
Type: String
Description: Amplify environment
deployRegions:
Type: CommaDelimitedList
Description: aws regions to deploy the S3 buckets to
Resources:
StackSet:
Type: AWS::CloudFormation::StackSet
Properties:
Description: Multiple S3 buckets in multiple regions
PermissionModel: SELF_MANAGED
Parameters:
- ParameterKey: env
ParameterValue: !Ref env
StackInstancesGroup:
- DeploymentTargets:
Accounts:
- !Ref "AWS::AccountId"
Regions: !Ref deployRegions
StackSetName: !Sub "s3Buckets-${env}"
TemplateBody: |
AWSTemplateFormatVersion: 2010-09-09
Description: Create a S3 bucket
Parameters:
env:
Type: String
Resources:
s3bucketInRegion:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub myNewBucket-${env}-${AWS::Region}
AccessControl: Private
LifecycleConfiguration:
Rules:
- ExpirationInDays: 3
Id: "Remove files after 3 days"
Status: Enabled
Prefix: "upload/3d"
CorsConfiguration:
CorsRules:
- AllowedHeaders:
- "*"
AllowedMethods:
- GET
- POST
AllowedOrigins:
- "*"
MaxAge: 3600
Tags:
- Key: Company
Value: myCompany
The parent template gets a parameter called env from the AWS Amplify framework. This one is passed to the Properties of the StackSet. This way the StackSet provides this parameter to its child Stacks.
As we are using AWS Amplify to deploy the StackSet, we’re providing the deployment regions as a parameter to the parent template. If you’d like to specify the regions within the template, edit the following part.
StackInstancesGroup:
- DeploymentTargets:
Accounts:
- !Ref "AWS::AccountId"
Regions:
- eu-west-1
- eu-west-2
- ap-northeast-1
And if you like to deploy your resources into multiple AWS accounts, just provide the corresponding account IDs.
We hope, we were able to help you with creating your Cloudformation template.
Best regards
Andy / cloudxs