Deploying CloudFormation Stacks From Azure DevOps to AWS
This guide demonstrates how to deploy a CloudFormation stack from Azure DevOps to AWS. To keep this guide simple the CloudFormation Stack will only contain three S3 buckets.
For this guide you will need to create to files: pipeline.yaml
for the pipeline file and template.yaml for the CloudFormation template file.
Variables
To follow along with this guide you will need to the define the following variables:
Variable | Description |
---|---|
AwsServiceConnection |
Service connection name found under Service Connections in the project settings page |
AwsBucket |
AWS bucket for the deploy files |
Region |
AWS region to deploy the solution to. E.g: eu-west-1 |
StackName |
Name of the stack to deploy |
The variables needs to be placed in the library folder with the name prod.
Azure DevOps Build File
The Azure DevOps build file contains three steps: create a S3 bucket, build the template files and lastly deploying the template file.
Create Deploy Bucket for CloudFormation Template
AWS CloudFormation stacks can be at most 51,200 bytes using the API or the CLI. The template size limit can be increased by uploading the CloudFormation template file to AWS S3. In this example we use the built in S3Upload
task in Azure DevOps. This task is used only to create an empty bucket for the CloudFormation template to be uploadet to. The inputs used are
- The AWS service connection
- The AWS S3 bucket name
- The region to place the bucket
createBucket
to ensure that the bucket is created if it doesn't existglobExpressions
with the valueundefined
is used because we don't want to upload any files. By using the valueundefined
no files are uploaded to the bucket, as this value will not match any files in your project folder.
- task: S3Upload@1
displayName: Create Deploy Bucket
inputs:
awsCredentials: AwsServiceConnection
bucketName: $(AwsBucket)
regionName: $(Region)
globExpressions: "undefined"
createBucket: true
Build Template
During this step we build the template using the SAM CLI. We could have used the built in AWS task inside Azure DevOps to create and update our template, but if we want to build Lamba functions we need to use the SAM CLI to build the Lamba functions. The Azure DevOps task AWSShellScript
already have the SAM CLI ready for us to use. The inputs used are:
- The AWS service connection
- The AWS region
- The script type defined as
inline
- The inline script itself which uses the command
sam build
to build the project
- task: AWSShellScript@1
displayName: Package
inputs:
awsCredentials: AwsServiceConnection
regionName: $(Region)
scriptType: 'inline'
inlineScript: |
sam build --debug \
--template-file template.yaml
Deploy Template
Lastly, we need to deploy the CloudFormation template to AWS. Again we use the AWSShellScript
, but this time we use the SAM CLI command deploy
which deploys the CloudFormation stack to AWS. In this task we use the following inputs:
- The AWS service connection
- The AWS region
- Defining the script type as
inline
- The
sam deploy
command
The following options are added to the sam deploy
command:
template-file
- defining the name of the CloudFormation template to deploy, in our case that istemplate.yaml
no-confirm-changset
- don't ask for confirmation to deploy the changescapabilities
- accept the stack to create IAM roles and to create nested stacksstack-name
- stack names3-bucket
- S3 bucket to store the CloudFormation filess3-prefix
- Prefix for the CloudFormation deploy files
- task: AWSShellScript@1
displayName: Deploy Infrastructure
inputs:
awsCredentials: AwsServiceConnection
regionName: $(Region)
scriptType: "inline"
inlineScript: |
sam deploy \
--template-file template.yaml \
--no-confirm-changeset \
--capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND \
--stack-name $(StackName) \
--s3-bucket $(AwsBucket) \
--s3-prefix $(StackName)
The Complete Build File
The complete build file can be seen below. As you see there are a few parts not mentioned yet. The trigger
section defines what to trigger a new build, and in this case the master branch. pool
defines the underlying vm to use. variables
reference to a library group called prod
.
trigger:
branches:
include:
- master
pool:
vmImage: "ubuntu-latest"
variables:
- group: prod
steps:
- task: S3Upload@1
displayName: Create Deploy Bucket
inputs:
awsCredentials: AwsServiceConnection
bucketName: $(AwsBucket)
regionName: $(Region)
globExpressions: "undefined"
createBucket: true
- task: AWSShellScript@1
displayName: Package
inputs:
awsCredentials: AwsServiceConnection
regionName: $(Region)
scriptType: 'inline'
disableAutoCwd: true
inlineScript: |
sam build --debug \
--template-file template.yaml
- task: AWSShellScript@1
displayName: Deploy Infrastructure
inputs:
awsCredentials: AwsServiceConnection
regionName: $(Region)
scriptType: "inline"
inlineScript: |
sam deploy \
--template-file template.yaml \
--no-confirm-changeset \
--capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND \
--stack-name $(StackName) \
--s3-bucket $(AwsBucket) \
--s3-prefix $(StackName)
Template File
Create a file called template.yaml. The template file itself in this guide is kept short to simplify the example. The template contains three AWS S3 buckets with the names: images-bucket
, thumbnail-bucket
and video-bucket
.
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Description
Resources:
ImagesBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: images-bucket
ThumbnailBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: thumbnail-bucket
VideBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: video-bucket
Support
If you want to support this blog you can do so by signing up to DigitalOcean using this referral link.