AWS DevOps & Developer Productivity Blog

Setting Up the Jenkins Plugin for AWS CodeDeploy

The following is a guest post by Maitreya Ranganath, Solutions Architect.


In this post, we’ll show you how to use the Jenkins plugin to automatically deploy your builds with AWS CodeDeploy. We’ll walk through the steps for creating an AWS CodeCommit repository, installing Jenkins and the Jenkins plugin, adding files to the CodeCommit repository, and configuring the plugin to create a deployment when changes are committed to an AWS CodeCommit repository.

Create an AWS CodeCommit Repository

First, we will create an AWS CodeCommit repository to store our sample code files.

1. Sign in to the AWS Management Console and open the AWS CodeCommit console in the us-east-1 (N. Virginia) Region.  Choose Get Started or Create Repository.

2. For Repository Name, type a name for your repository (for example, DemoRepository). For Description, type Repository for Jenkins Code Deploy.

3. Choose the Create repository button.

4. Choose the repository you just created to view its details.

5. Choose the Clone URL button, and then choose HTTPS. Copy the URL displayed into a clipboard. You’ll need it later to configure Jenkins.

 

Now that you have created an AWS CodeCommit repository, we’ll create a Jenkins server and AWS CodeDeploy environment.

Create a Jenkins Server and AWS CodeDeploy Environment

In this step, we’ll launch a CloudFormation template that will create the following resources:

  • An Amazon S3 bucket that will be used to store deployment files.
  • JenkinsRole, an IAM role and instance profile for the Amazon EC2 instance that will run Jenkins. This role allows Jenkins on the EC2 instance to assume the CodeDeployRole and access repositories in CodeCommit.
  • CodeDeployRole, an IAM role assumed by the CodeDeploy Jenkins plugin. This role has permissions to write files to the S3 bucket created by this template and to create deployments in CodeDeploy.
  • Jenkins server, an EC2 instance running Jenkins.
  • An Auto Scaling group of EC2 instances running Apache and the CodeDeploy agent fronted by an Elastic Load Balancing load balancer.

To create the CloudFormation stack, choose the link that corresponds to the AWS region where you want to work:

For the us-east-1 region:

or use the link below:

https://console.thinkwithwp.com/cloudformation/home?region=us-east-1#/stacks/new?stackName=JenkinsCodeDeploy&templateURL=https://s3.amazonaws.com/aws-codedeploy-us-east-1/templates/latest/CodeDeploy_SampleCF_Jenkins_Integration.json

For the us-west-2 region:

or use the link below:

https://console.thinkwithwp.com/cloudformation/home?region=us-west-2#/stacks/new?stackName=JenkinsCodeDeploy&templateURL=https://s3.amazonaws.com/aws-codedeploy-us-east-1/templates/latest/CodeDeploy_SampleCF_Jenkins_Integration.json

6. Choose Next and specify the following values:

  • For InstanceCount, accept the default of 3. (Three EC2 instances will be launched for CodeDeploy.)
  • For InstanceType, accept the default of t2.medium.
  • For KeyName, choose an existing EC2 key pair. You will use it to connect by using SSH to the Jenkins server. Ensure that you have access to the private key of this key pair.
  • For PublicSubnet1, choose a public subnet where the load balancer, Jenkins server, and CodeDeploy web servers will be launched.
  • For PublicSubnet2, choose a public subnet where the load balancers and CodeDeploy web servers will be launched.
  • For VpcId, choose the VPC for the public subnets you used in PublicSubnet1 and PublicSubnet2.
  • For YourIPRange, type the CIDR block of the network from where you will connect to the Jenkins server using HTTP and SSH. If your local machine has a static public IP address, find it by going to https://www.whatismyip.com/ and then entering it followed by a ‘/32’. If you do not have a static IP address (or aren’t sure if you have one), you may enter ‘0.0.0.0/0’ in this field then any address can reach your Jenkins server.

7. On the Review page, select the I acknowledge that this template might cause AWS CloudFormation to create IAM resources check box, and then choose Create.

8. Wait for the CloudFormation stack status to change to CREATE_COMPLETE. This will take approximately 6-10 minutes.

 

9. Note the values displayed on the Outputs tab. You’ll need them later.

10. Point your browser to the ELBDNSName from the Outputs tab and verify that you can see the Sample Application page.

Secure Jenkins

Point your browser to the JenkinsServerDNSName (for example, ec2-54-163-4-211.compute-1.amazonaws.com) from the Outputs tab. You should be able to see the Jenkins home page:

The Jenkins installation is currently accessible through the Internet without any form of authentication. Before proceeding to the next step, let’s secure Jenkins. On the Jenkins home page, choose Manage Jenkins. Choose Configure Global Security, and then to enable Jenkins security, select the Enable security check box.

Under Security Realm, choose Jenkins’s own user database and select the Allow users to sign up check box. Under Authorization, choose Matrix-based security. Add a user (for example, admin) and give this user all privileges. Save your changes.

Now you will be asked to provide a user name and password for the user. Choose Create an account, provide the user name (for example, admin), a strong password, and then complete the user details. Now you will be able to sign in securely to Jenkins.

Create a Project and Configure the CodeDeploy Jenkins Plugin

Now we’ll create a project in Jenkins and configure the Jenkins plugin to poll for code updates from the AWS CodeCommit repository.

1. Sign in to Jenkins with the user name and password you created earlier.

2. Choose New Item, and then choose Freestyle project. Type a name for the project (for example, CodeDeployApp), and then choose OK.

3. On the project configuration page, under Source Code Management, choose Git. Paste the URL you noted when you created the AWS CodeCommit repository (step 5).

4. In Build Triggers, select the Poll SCM check box. In the Schedule text field, type H/2 * * * *. This tells Jenkins to poll CodeCommit every two minutes for updates. (This may be too frequent for production use, but it works well for testing because it returns results frequently.)

5. Under Post-build Actions, choose Add post-build actions, and then select the Deploy an application to AWS CodeDeploy check box.

6. Paste the values you noted on the Outputs tab when you created the CloudFormation stack (step 9):

  • For AWS CodeDeploy Application Name, paste the value of CodeDeployApplicationName.
  • For AWS CodeDeploy Deployment Group, paste the value of CodeDeployDeploymentGroup.
  • For AWS CodeDeploy Deployment Config, type CodeDeployDefault.OneAtATime.
  • For AWS Region, choose the region where you created the CodeDeploy environment.
  • For S3 Bucket, paste the value of S3BucketName.
  • Leave the other settings at their default (blank).

7. Choose Use temporary credentials, and then paste the value of JenkinsCodeDeployRoleArn that appeared in the CloudFormation output.

Note the External ID field displayed on this page. This is a unique random ID generated by the CodeDeploy Jenkins plugin. This ID can be used to add a condition to the IAM role to ensure that only the plugin can assume this role. To keep things simple, we will not use the External ID as a condition, but we strongly recommend you use it for added protection in a production scenario, especially when you are using cross-account IAM roles.

 

8. Choose Test Connection.

 

9. Confirm the text “Connection test passed” appears, and then choose Save to save your settings.

Add Files to the CodeCommit Repository

Now, we’ll use the git command-line tool to clone the AWS CodeCommit repository and then add files to it. These steps show you how to use SSH to connect to the Jenkins server. If you are more comfortable with Git integrated in your IDE, follow the steps in the CodeCommit documentation to clone the repository and add files to it.

1. Use SSH to connect to the public DNS name of the EC2 instance for Jenkins (JenkinsServerDNSName from the Outputs tab) and sign in as the ec2-user. Run the following commands to configure git. Replace the values enclosed in quotes with your name and email address.

$ aws configure set region us-east-1
$ aws configure set output json
$ git config --global credential.helper '!aws codecommit credential-helper $@'
$ git config --global credential.useHttpPath true
$ git config --global user.name "YOUR NAME"
$ git config --global user.email "example@example.com"

2. Clone the repository you created in the previous step.

$ git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/DemoRepository
Cloning into 'DemoRepository'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

3. Switch to the DemoRepository directory:

$ cd DemoRepository/

4. Now we’ll download the source for the Sample CodeDeploy application.

$ curl -OLs http://aws-codedeploy-us-east-1.s3.amazonaws.com/samples/latest/SampleApp_Linux.zip

5. Unzip the downloaded file:

$ unzip SampleApp_Linux.zip
Archive:  SampleApp_Linux.zip
extracting: scripts/install_dependencies  
extracting: scripts/start_server    
inflating: scripts/stop_server     
inflating: appspec.yml             
inflating: index.html              
inflating: LICENSE.txt 

6. Delete the ZIP file:

$ rm SampleApp_Linux.zip

7. Use a text editor to edit the index.html file:

$ vi index.html

8. Scroll down to the body tag and add the highlighted text:

9. Save the file and close the editor.

10. Add the files to git and commit them with a comment:

$ git add appspec.yml index.html LICENSE.txt scripts/*
$ git commit -m "Initial versions of files"

11. Now push these updates to CodeCommit:

$ git push

12. If your updates have been successfully pushed to CodeCommit, you should see something like the following:

Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (9/9), 5.05 KiB | 0 bytes/s, done.
Total 9 (delta 0), reused 0 (delta 0)
remote: 
To https://git-codecommit.us-east-1.amazonaws.com/v1/repos/DemoRepository
 * [new branch]      master -> master

13. On the Jenkins dashboard, choose the CodeDeployApp project.

14. Choose Git Polling Log to see the results of polling git for updates. There may be a few failed polls from earlier when the repository was empty.

15. Within two minutes of pushing updates, a new build with a Build ID (for example, #2 or #3) should appear in the build history.

16. Choose the most recent build. On the Build details page, choose Console Output to view output from the build.

17. At the bottom of the output, check that the status of the build is SUCCESS.

18. In the CodeDeploy console, choose AWS CodeDeploy, and then choose Deployments.

 

19. Confirm that there are two deployments: the initial deployment created by CloudFormation and a recent deployment of the latest code from AWS CodeCommit. Confirm that the status of the recent deployment is Succeeded.

 

20. Point your browser to the ELBDNSName from the Outputs tab of CloudFormation. Confirm that the text “This version was deployed by Jenkins” appears on the page.

Congratulations, you have now successfully set up the CodeDeploy Jenkins plugin and used it to automatically deploy a revision to CodeDeploy when code updates are pushed to AWS CodeCommit.

You can experiment by committing more changes to the code and then pushing them to deploy the updates automatically.

Cleaning Up

In this section, we’ll delete the resources we’ve created so that you will not be charged for them going forward.

1. Sign in to the Amazon S3 console and choose the S3 bucket you created earlier. The bucket name will start with “jenkinscodedeploy-codedeploybucket.” Choose all files in the bucket, and from Actions, choose Delete.

2. Choose OK to confirm the deletion.

3. In the CloudFormation console, choose the stack named “JenkinsCodeDeploy,” and from Actions, choose Delete Stack. Refresh the Events tab of the stack until the stack disappears from the stack list.