Continuous Delivery to S3 via CodePipeline and CodeBuild
In this blog post, you see a demonstration of Continuous Delivery of a static website to Amazon S3 via AWS CodeBuild and AWS CodePipeline. At the conclusion, you will be able to provision all of the AWS resources by clicking a “Launch Stack” button and going through the AWS CloudFormation steps to launch a solution stack.
Using S3 is useful when you want to host static files such as HTML and image files as a website for others to access. Fortunately, S3 provides us the capability to configure an S3 bucket for static website hosting. For more information on manually configuring this for a custom domain, see Example: Setting up a Static Website Using a Custom Domain.
However, once you go through this process manually a few times, and if you’re like me, you’ll quickly grow tired of manually uploading new files, deleting old files, and setting the permissions for the files in the S3 bucket.
In this example, all the source files are hosted in GitHub and can be made available to developers. All of the steps in the process are orchestrated via CodePipeline and the build and deployment actions are performed by CodeBuild. The provisioning of all of the AWS resources is defined in a CloudFormation template.
By automating the actions and stages into a deployment pipeline, you can release changes to users in production whenever you choose to do so without needing to repeatedly manually upload files to S3. Instead, you just commit the changes to the GitHub repository and the pipeline orchestrates the rest. While this is a simple example, you can follow the same model and tools for much larger and sophisticated applications.
Figure 1 shows this deployment pipeline in action.
Figure 1 – Deployment Pipeline in CodePipeline to deploy a static website to S3
The remainder of this post describes how to configure the solution in your AWS account.
Prerequisites
Here are the prerequisites for this solution:
- AWS Account – Follow these instructions to create an AWS Account: Creating an AWS Account and grant IAM privileges to access at least CodeBuild, CodePipeline, CloudFormation, IAM, and S3.
- Fork GitHub Repo – Fork and clone your own stelligent/devops-essentials GitHub repository
- OAuth Token – Create an OAuth token in GitHub and provide access to the admin:repo_hook and repo scopes.
To see these steps in more detail, go to devopsessentialsaws.com and go to section 2.1 Configure course prerequisites.
Architecture and Implementation
In Figure 2, you see the architecture for provisioning an infrastructure that launches a deployment pipeline to orchestrate the build the solution. You can click on the image to launch the template in CloudFormation Designer within your AWS account.
Figure 2 – CloudFormation Template for provisioning AWS resources
The components of this solution are described in more detail below:
- AWS CloudFormation – All of the resource generation of this solution is described in CloudFormation which is a declarative code language that can be written in JSON or YAML (or generated by more expressive domain-specific languages)
- AWS CodePipeline – The CodePipeline stages and actions are defined in a CloudFormation template. This includes CodePipeline’s integration with CodeCommit, CodeBuild, and CloudFormation (For more information, see Action Structure Requirements in AWS CodePipeline).
- GitHub – CodePipeline connects with an existing GitHub repository using the GitHub Source provider action.
- AWS CodeBuild – Creates a CodeBuild project using the AWS::CodeBuild::Project to package and store the Lambda function
- AWS IAM – An Identity and Access Management (IAM) Role is provisioned using the AWS::IAM::Role resource which defines the resources that the pipeline, CloudFormation, and other resources can access.
CloudFormation Template
In this section, I’ll highlight a few code snippets from the CloudFormation template that automates the provisioning of the AWS Developer Tools stack along with other resources including S3 and IAM.
S3 Buckets
There are two S3 buckets provisioned in this CloudFormation template. The SiteBucket resource defines the S3 bucket that hosts all the files that are copied from the downloaded source files from Git. The PipelineBucket hosts the input artifacts for CodePipeline that are referenced across stages in the deployment pipeline.
SiteBucket: Type: AWS::S3::Bucket Properties: AccessControl: PublicRead BucketName: !Ref SiteBucketName WebsiteConfiguration: IndexDocument: index.html PipelineBucket: Type: AWS::S3::Bucket
IAM Role
The IAM role for CodePipeline provides the CodePipeline the necessary permissions for access to the necessary resource to deploy the static website resources.
CodePipelineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - codepipeline.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: codepipeline-service PolicyDocument: Statement: - Action: - codebuild:* Resource: "*" Effect: Allow - Action: - s3:GetObject - s3:GetObjectVersion - s3:GetBucketVersioning Resource: "*" Effect: Allow - Action: - s3:PutObject Resource: - arn:aws:s3:::codepipeline* Effect: Allow - Action: - s3:* - cloudformation:* - iam:PassRole Resource: "*" Effect: Allow Version: '2012-10-17'
CodePipeline
The CodePipeline pipeline CloudFormation snippet shown below defines the two stages and two actions that orchestrate the deployment of the static website. The Source action within the Source stage configures GitHub as the source provider. Then, it moves to the Deploy stage which runs CodeBuild to copy all the HTML and other assets to an S3 bucket that’a configured to be hosted as a website.
Pipeline: Type: AWS::CodePipeline::Pipeline Properties: RoleArn: !GetAtt CodePipelineRole.Arn Stages: - Name: Source Actions: - InputArtifacts: [] Name: Source ActionTypeId: Category: Source Owner: ThirdParty Version: '1' Provider: GitHub OutputArtifacts: - Name: SourceOutput Configuration: Owner: !Ref GitHubUser Repo: !Ref GitHubRepo Branch: !Ref GitHubBranch OAuthToken: !Ref GitHubToken RunOrder: 1 - Name: Deploy Actions: - Name: Artifact ActionTypeId: Category: Build Owner: AWS Version: '1' Provider: CodeBuild InputArtifacts: - Name: SourceOutput OutputArtifacts: - Name: DeployOutput Configuration: ProjectName: !Ref CodeBuildDeploySite RunOrder: 1 ArtifactStore: Type: S3 Location: !Ref PipelineBucket
Costs
Since costs can vary as you use certain AWS services and other tools, you can see a cost breakdown and some sample scenarios to give you an idea of what your monthly spend might look like. Note this will be dependent on your unique environment and deployment, and the AWS Cost Calculator can assist in establishing cost projections.
- CloudFormation – No additional cost.
- CodeBuild – CodeBuild charges per minute used. It comes with 100 minutes per month at no charge. For a simple execution of this demo, you can stay within the limits of the AWS Free Tier – please read about the Free Tier here. For more information, see AWS CodeBuild pricing.
- CodePipeline – Customers can create new pipelines without incurring any charges on that pipeline for the first thirty calendar days. After that period, the new pipelines will be charged at the existing rate of $1 per active pipeline per month. For more information, see AWS CodePipeline pricing.
- GitHub – No charge for public repositories
- IAM – No additional cost.
- S3 – If you launch the solution and delete the S3 bucket, it’ll be pennies (if that). See S3 Pricing.
The bottom line on pricing for this particular example is that you will charged no more than a few pennies if you launch the solution run through a few changes and then terminate the CloudFormation stack and associated AWS resources.
Deployment Steps
There are three main steps in launching this solution: preparing an AWS account, launching the stack, and testing the deployment. Each is described in more detail in this section. Please note that you are responsible for any charges incurred while creating and launching your solution.
Step 1. Prepare an AWS Account
- If you don’t already have an AWS account, create one at http://aws.amazon.com by following the on-screen instructions. Part of the sign-up process involves receiving a phone call and entering a PIN using the phone keypad. Be sure you’ve signed up for the CloudFormation service.
- Use the region selector in the navigation bar of the console to choose the Northern Virginia (us-east-1) region
Step 2. Launch the Stack
Click on the “Launch Stack” button below to launch the CloudFormation stack. Before you launch the stack, review the architecture, configuration, and other considerations discussed in this post. To download the template, click here.
Time to deploy: Approximately 5 minutes
The template includes default settings that you can customize by following the instructions in this post.
Step 3. Test the Deployment
Here are the steps to test the deployment:
- Once the CloudFormation stack is complete, select checkbox next to the stack and go to the Outputs tab
- Click on the PipelineUrl link to launch the CodePipeline pipeline.
- Click on the SiteUrl link to launch the website that was configured and launched as part of the deployment pipeline
- From your Terminal, type (replacing YOURGITHUBUSERID with your GitHub userid):
git clone https://github.com/YOURGITHUBUSERID/devops-essentials
- Make obvious visual changes to any of your local files (for example, change .bg-primary{color:#fff;background-color: in your forked repo version of devops-essentials/html/css/bootstrap.min.css) and type the following from your Terminal:
git commit -am "add new files" && git push
- Go back to your pipeline in CodePipeline and see the changes successfully flow through the pipeline.
DevOps Essentials on AWS Video Course
This and many more topics are covered in the DevOps Essentials on AWS Complete Video Course (Udemy, InformIT, SafariBooksOnline). In it, you’ll learn how to automate the infrastructure and deployment pipelines using AWS services and tools so if you’re some type of software orDevOps-focused engineer or architect interested in learning how to use AWS Developer and AWS Management Tools to create a full-lifecycle software delivery solution, it’s the course for you. The focus of the course is on deployment pipeline architectures and its implementations.
Additional Resources
Here are some of the supporting resources discussed in this post:
- DevOps Essentials on AWS Course Website
- Source code for this post
- GitHub: Open Source Examples from the Course
- See Action Type Constraints for Artifacts header at AWS CodePipeline Pipeline Structure Reference
Did you find this post interesting? Are you passionate about working with the latest AWS technologies? If so, Stelligent is hiring and we would love to hear from you!
Acknowledgements
My colleague Casey Lee created the initial CodePipeline/CodeBuild/S3 CloudFormation template that’s the basis for this solution.
Stelligent Amazon Pollycast
|