Traditionally, managing transport layer security (TLS) digital certificates that are used for encrypting data in transit between clients and servers has been a very manual process. In 2016, Amazon Web Services began offering the AWS Certificate Manager (ACM) – a service for managing these digital certificates. By using AWS CloudFormation and AWS CodePipeline, you can automate the end-to-end process for deploying these TLS certificates to the websites that need TLS encryption.
Here is a list of the core AWS services covered in this post:
- Amazon CloudFront is a managed cloud distribution network (CDN) that helps improve performance of static and dynamic content through the use of edge locations across the world. What’s more, when configured properly, you get built-in security features such as reducing the chance of a distributed denial of service attack.
- AWS Certificate Manager (ACM) is a service that lets you easily provision, manage, and deploy Secure Sockets Layer/Transport Layer Security (SSL/TLS) certificates for use with AWS services. With ACM, you can encrypt data in transit.
- AWS CloudFormation is a service for creating and managing AWS resources with templates.
- AWS CodePipeline is a fully-managed service for releasing software using Continuous Delivery.
In this post, you will see an example static web application in which all of the AWS infrastructure resources are defined as code in AWS CloudFormation and versioned in an AWS CodeCommit version repository. Furthermore, you will automate the continuous delivery workflow of this solution using AWS CodePipeline.
I’ve also included a screencast below that provides a walkthrough of the steps covered in this post.
Creating a Pipeline to Deploy an ACM Certificate
In this example, you will see how you can create a CloudFormation template that automatically provisions CodePipeline, a CodeCommit private Git repository, a CodeBuild project to deploy the static website, and a CloudFormation deploy provider for CodePipeline to launch CloudFormation stacks that deploy CloudFront and ACM resources.
This way you can deploy changes to your ACM and CloudFront configurations as code without needing to manually provision and run a new CloudFormation stack every time.
There are four main steps in launching this solution: prepare an AWS account, create and store source files, launch the CloudFormation stack, and test the deployment. Each is described in more detail in this section. Please note that you are responsible for any fees incurred while creating and launching your solution.
Step 1. Prerequisites
This example assumes you have access to an AWS account and have established the necessary permissions. In order to show specific directory names, it also assumes you are using AWS Cloud9 for your IDE. If you are not, you should be able to simply modify the directory names accordingly.
Step 2. Create and Store Source Files
Next, you will create a few source files that will be stored in S3 and then uploaded to AWS CodeCommit when launching the CloudFormation stack. You will also download the files for an example static website provided by AWS that you will be deployed as part of the CodeBuild and CodePipeline configuration in the CloudFormation template.
From your AWS Cloud9 terminal, type the following to setup your directory structure:
sudo rm -rf ~/environment/tls mkdir ~/environment/tls aws s3 mb s3://ceoa-tls-$(aws sts get-caller-identity --output text --query 'Account') cd ~/environment/tls wget https://docs.aws.amazon.com/codepipeline/latest/userguide/samples/sample-website.zip unzip sample-website.zip
Create and save three empty source files:
touch tls-acm.yml touch tls-cloudfront.yml touch tls-pipeline.yml
Copy the source contents from the tls-acm.yml file and save it to your local file of the same name in your Cloud9 environment. This CloudFormation template provisions an ACM certificate for the specified domain that you own.
You will need to modify the DnsDomainName parameter (currently listed as encryptaws.com) to the domain name that you are managing in Amazon Route 53.
Copy the source contents from the tls-cloudfront.yml file and save it to your local file of the same name in your Cloud9 environment. This CloudFormation template provisions a CloudFront distribution and links it to the ACM certificate you provisioned in the tls-acm.yml template.
You will need to modify the following parameters:
- BucketName – Change the Default value (currently listed as www.encryptaws.com) to the globally unique S3 bucket name you wish for the CloudFormation stack to create.
- DomainName – Change the Default value (currently listed as www.encryptaws.com.s3.amazonaws.com) to the globally unique S3 bucket name automatically generated based on the BucketName.
- CloudFrontCName – Change the Default value (currently listed as www.encryptaws.com) to a name that will be used in Route 53.
- HostedZoneId – Change the Default value (currently listed as Z3DG6IL3SJCGPX) to the Hosted Zone ID you configured in Route 53. To do this, go to the Route 53 console and click on Hosted Zones. There will be a column called Hosted Zone ID next to the domain you are managing in Route 53. Copy that value to the parameter default in this CloudFormation template.
Copy the source contents from the tls-pipeline.yml file and save it to your local file of the same name in your Cloud9 environment. The file is a nearly 400-line CloudFormation template and provisions CodeCommit, IAM, CodeBuild, and CodePipeline to deploy the CloudFormation templates for CloudFront and ACM.
Sync the files with your S3 bucket
Here, you will zip and upload all of the source files to S3 so that they can be committed to the CodeCommit repository that is automatically provisioned by the stack generated by the tls-pipeline.yml template.
From your AWS Cloud9 environment, type the following:
cd ~/environment/tls zip ceoa-tls-examples.zip *.* aws s3 sync ~/environment/tls s3://ceoa-tls-$(aws sts get-caller-identity --output text --query 'Account')
Step 3. Launch the Stack
From your AWS Cloud9 environment, type the following (replacing CloudFrontCName with the value you used for the parameter of the same name in the tls-cloudfront.yml template. In my case, I have access to a domain called www.encryptaws.com. Your will be different):
aws cloudformation create-stack --stack-name ceoa-tls-pipeline --template-body file:///home/ec2-user/environment/tls/tls-pipeline.yml --parameters ParameterKey=CodeCommitS3Bucket,ParameterValue=ceoa-tls-$(aws sts get-caller-identity --output text --query 'Account') ParameterKey=CodeCommitS3Key,ParameterValue=ceoa-tls-examples.zip ParameterKey=SiteBucketName,ParameterValue=CloudFrontCName --capabilities CAPABILITY_NAMED_IAM --disable-rollback
Step 4. Test the Deployment
Verify the CloudFormation template has launched by going to the CloudFormation dashboard.
Once the stack is CREATE_COMPLETE, select it and click on the Outputs tab. Then, click on the PipelineUrl Output. This will launch the pipeline you automatically provisioned in CodePipeline – as shown below.
Once it has successfully run through all the stages in the pipeline, you will verify the TLS certificate is configured in the AWS Certificate Manager by opening your web browser and typing the URL you entered for the CloudFrontCName parameter value. Verify that the website launches and that encryption has been enabled in transit by looking for the TLS certificate next to the URL in the browser.
In this post, you learned how to automate the provisioning of a pipeline deploys changes to CloudFront and the ACM whenever there is a modification to the CloudFormation templates that manage the provisioning of these services.
As demonstrated in Deploy Managed Config Rules using CloudFormation and CodePipeline, this is an approach you can use in deploying changes to multiple CloudFormation templates as part of a deployment pipeline in CodePipeline.
Stelligent Amazon Pollycast