What Is CI/CD?
Continuous Integration, Continuous Deployment (CI/CD) is all about making frequent (often daily) code updates, building and testing new releases, and rolling out the changes to your production servers quickly and efficiently.
It’s a very wide term that encapsulates the core of DevOps culture—streamlining the flow of new code from your developer’s brains and onto your servers. Usually, CI/CD is implemented with a toolkit called a pipeline, which is a set of tools that automates the entire process from source to deployment.
This is what AWS provides with their CodeSuite tools, and they’re in a particularly good place to implement such a pipeline, as you will usually be running your production servers on EC2, making the deployment stage much easier and well integrated.
AWS’s CodeSuite Tools
CodeSuite is made up of a few different tools. It starts with CodeCommit, AWS’s managed source control service. It’s a bit clunkier and less feature rich than the competition, but it’s easy enough to set up Git with multiple remotes that you might as well use it if you plan on using the rest of the pipeline. CodeCommit has a very generous free tier, so you likely won’t incur many charges for it.
Next comes CodeBuild, which takes source control from CodeCommit (or GitHub/BitBucket) and builds from source, running any tests you provide in the process. This uses an EC2 server for building, which you must pay for while the build is running. Complex projects can require a powerful machine for fast builds.
Once the build is complete, your application is ready for deployment. This stage is handled with CodeDeploy; you create a “deployment group,” which can contain any number of EC2 instances or whole auto-scaling groups. This is where AWS’s pipeline really shines.
With CodeDeploy, you can fine tune how deployment is handled—there are presets for all at once, half the group, 10% every few minutes, and many more, which are all designed to minimize application downtime due to unexpected bugs in production. Having all your servers update automatically is nice enough, but CodeDeploy can even connect to your load balancer and cut traffic to instances in the process of being updated. Combined with a staggered rollout strategy to ensure a minimum number of healthy hosts, this makes production updates stress-free.
All of this is wrapped up together into a single pipeline, which monitors your source control and triggers the pipeline to run automatically whenever you push changes to the release branch, building, testing, and deploying your code onto all of your servers.
How to Set Up a Pipeline
First, you need to get your code into CodeCommit. We recommend setting up CodeCommit as separate release remote alongside your primary source control. If you’re using Github or BitBucket, you can connect directly to your repository instead, but CodeCommit is an entirely AWS solution and enables you to manage organizational access to server updates through the IAM console.
Next, head over to the CodePipeline console to get started. Click “Create Pipeline,” and give it a name and description.
Each stage of the pipeline needs some configuration. The first is the source stage, which connects to CodeCommit, Github, and BitBucket. The latter two requires you to connect your accounts over OAuth, but CodeCommit connects directly. Choose the repository you’re usin, and the branch for releases. If you’re using CodeCommit as a secondary remote, you’ll probably choose master here, but if you’re using a third-party provider, you may want to set up a seperate release branch.
Below the branch options, you can find the settings for how this pipeline automatically runs. By default, it runs every time a new commit is pushed to the release branch you specified. You can change this, but this is probably what you want.
Next up, the build stage. CodePipeline supports Jenkins and the built in CodeBuild for building code. If you’re already using Jenkins for building, you must install the CodePipeline plugin to connect it to AWS. Otherwise, you can set up CodeBuild by clicking “Create Project” to open up a dialog.
CodeBuild has a lot of stuff to configure, so you can read our guide to setting it up to learn more. Once you’re done, the dialog should close and bring you back to the CodePipeline setup.
The next stage is deployment. CodePipeline supports a few different deployment options; most notably, if you’re using AWS CloudFormation or Elastic Container Service, you can deploy updates directly to those. For general EC2 and Lambda deployments, you need to use CodeDeploy.
CodeDeploy also requires a lot of configuration, so you can read our complete guide to set it up. In short, you create a deployment group consisting of your EC2 servers, an Auto-Scaling group, or Lambda functions, and choose a deployment configuration—all at once, half at once, etc. CodeDeploy handles everything else, tweaking your load balancer so that traffic isn’t routed to updating servers, and always maintaining a set number of healthy hosts, so your service never goes down for updates.
Once you’re done, come back to CodePipeline and select the deployment you just set up. That should mark all of the setup done, and you can click next to review your pipeline before setting it in motion.
Once you create the pipeline, it runs the first build automatically. If it runs into any errors in the build, the pipeline stops and your servers won’t be updated.
You can test the pipeline’s update detection by making a new commit in your source control. The pipeline should start again automatically, and roll out changes to your servers if everything looks good.
You can go back and edit the pipeline at any time, or tweak the CodeBuild or CodeDeploy configurations. If you’re running into build errors, you need to make sure your buildspec file is handling everything correctly.