AWS Compute Blog
Using AWS CodeDeploy and AWS CodePipeline to Deploy Applications to Amazon Lightsail
This post is contributed by Mike Coleman | Developer Advocate for Lightsail | Twitter: @mikegcoleman
Introduction
Amazon Lightsail is the easiest way to get started in the cloud, allowing you to get your application running on your own virtual server in a matter of minutes. But, what do you do if you want to update that running application?
In order to automate the process of both deploying and updating software many developers are turning to automated workflows. AWS has a full complement of tools that allow you to build deployment pipelines to cover a wide array of use cases.
This blog post provides guidance on how to configure Lightsail to work with AWS CodePipeline and AWS CodeDeploy to automatically deploy (or update) an application every time you push a change to GitHub. Even though this tutorial provides detailed, step-by-step instructions, you may still want to read some of the docs (CodeDeploy and CodePipeline) if you’re unfamiliar with deployment pipelines.
After completing this walkthrough you’ll be on your way to implementing more complex pipelines that might include build and test steps.
Prerequisites
You need the following to complete this walkthrough:
- A GithHub account in which to fork the demo code
- git installed on your local machine, and a basic understanding on how to use it
- An AWS account with sufficient privileges to create AWS Identity and Access (IAM) users, policies, and service roles as well as to create resources with the following services: Amazon S3, CodePipeline, CodeDeploy and Lightsail
- The AWS CLI installed and configured on your local machine
Document Important Values
As you go through this tutorial, you’ll need to take note of a few key values. Open up a text editor of your choice, and copy and paste the template below into a new document. As you go through the guide, when instructed, copy the values into your text document
S3 Bucket Name:
Access Key ID:
Secret Key:
IAM User ARN:
Note: Both the Access key ID and Secret access key should be protected in the same manner you protect any sensitive username / password pair.
Solution Overview
The rest of this blog guides you through the process of setting up your deployment pipeline. You start by creating a service role for CodeDeploy, an Amazon S3 bucket, and an IAM user. After deploying these services, you create a Lightsail instance. You also install and configure the CodeDeploy agent, as well as registering the instance with CodeDeploy. Finally, you create an application in CodeDeploy, and configure CodePipeline to kick off a new deployment whenever you push changes to GitHub.
Create a service role
In AWS a service role is a role that an AWS service assumes to perform actions on your behalf. The policies that you attach to the service role determine which AWS resources the service can access and what it can do with those resources. Below you use AWS IAM to create a service role for CodeDeploy that has the necessary permissions to work with Lightsail.
- Sign in to the AWS Management Console and open the IAM console at https://console.aws.amazon.com/iam/.
- In the navigation pane, choose Roles, and then choose Create role.
- On the Create role page, choose AWS service, and from the Choose the service that will use this role list, choose CodeDeploy.
- Near the bottom of the screen under Select your use case, choose CodeDeploy and click Next: Permissions.
- On the Attached permissions policy page, the default permission policy (AWSCodeDeployRule) is displayed. You can click on the policy name if you’d like to review the details of the policy.Click Next: Tags, and then click Next: Review.
- On the Create Role page, in Role name, enter a name for the service role (for example, CodeDeployServiceRole).
- Click Create role.
Create an S3 bucket
In this section, you create an Amazon S3 bucket to store the deployment artifact created by CodeDeploy. This artifact is a compressed file containing your source code files, and any scripts that need to run as part of the installation or update process.
- Sign in to the AWS Management Console and open the S3 console, and click Create Bucket.
- Enter a name under Bucket name. The name must be unique across all of S3.
Be sure to copy the S3 bucket name into your text document.
- Ensure Block all public access is checked.
- Click Create bucket.
Create IAM policy
An IAM policy is a set of rules that, when attached to an identity or resource, defines their permissions. For this use case, you want a policy that only allows AWS CodeDeploy agent to read the S3 bucket you just created. In the next set of steps, you define the policy. Then in the subsequent section you apply that policy to an IAM user. That user ultimately is associated with the CodeDeploy agent running on your Lightsail instance.
- Sign in to the AWS Management Console and open the IAM console.
- In the navigation pane, choose Policies, and then choose Create policy.
- Click on the JSON tab.
Erase the content in the editor window, and paste in the code from below.
NOTE: Be sure to replace <S3 Bucket Name
> with the name of the S3 bucket you created in the previous step.
- Click Review policy.
- Enter
CodeDeployS3BucketPolicy
for the policy name. - Click Create policy.
Create an IAM user
Because you cannot assign an IAM role to a Lightsail instance, you need to create your IAM user with the appropriate permissions. In this case the user will need to be able to list the contents of the S3 bucket you just created.
- Stay in the IAM console.
- In the navigation pane, choose Users, and then choose Add user.
- Enter
LightSailCodeDeployUser
for the User name and click Programmatic access under Select AWS access type (you use programmatic access since this user account will never need to log into the console). Click Next: permissions. - Click Attach existing polices directly. Enter
CodeDeployS3BucketPolicy
in the search box, and check the box next to theCodeDeployS3BucketPolicy
policy. - Click Next: Tags. Click Next: Review. Click Create user.
- Copy the Access key ID and Secret access key into your text document. You will need to click Show to display the secret access key. Note: If you do not copy these values now, you cannot go back and retrieve them from the console. You will need to create a new set of credentials
.
7. Click Close.
8. Click on the user you just and copy the User ARN into your document.
At this point you created an S3 bucket where CodeDeploy can store your build artifact, as well as the IAM components you need (a service role, IAM Policy, and an IAM user) to configure the CodeDeploy agent. In the next step, you actually deploy a Lightsail instance with the CodeDeploy agent, and then you register that instance with CodeDeploy
Create a Lightsail instance and install the CodeDeploy agent
In this section you create the Lightsail instance where you want your code to run. In order for the instance to work with CodeDeploy you must install the CodeDeploy agent. The agent installation is done by providing a startup script that runs when the instance is first created.
- Log in to the AWS Management Console, and navigate to the Lightsail home page.
- Click Create instance.
- Ensure that you’re creating your instance in the correct AWS Region.
- Under Pick your instance image click on Linux/Unix. Click on OS Only. Select Amazon Linux.
- Scroll down and click + Add launch script. In the code below paste in your Access key ID, Secret access key, and IAM User ARN from your text document. Also replace <
Desired Region
> with the Region that you deployed instance into (e.g.us-west-2
).
After you edit the code below, paste it into the launch script edit window. The configuration below allows the CodeDeploy agent run with the permissions you assigned to the IAM user earlier. These permissions allow the CodeDeploy agent to download the deployment artifact created by the CodeDeploy service from the S3 bucket where it will be stored. Additionally, the agent will use the information in the artifact to deploy or update your application.
mkdir /etc/codedeploy-agent/
mkdir /etc/codedeploy-agent/conf
cat <<EOT >> /etc/codedeploy-agent/conf/codedeploy.onpremises.yml
---
aws_access_key_id: <Access Key ID>
aws_secret_access_key: <Secret Access Key>
iam_user_arn: <IAM User ARN>
region: <Desired Region>
EOT
wget https://aws-codedeploy-us-west-2.s3.us-west-2.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
6. Enter codedeploy
for the instance name under Identify your instance. Click Create Instance.
Verify the CodeDeploy agent
Wait about 5-10 minutes for the instance to boot up and run the startup script.
In this section you verify that the CodeDeploy agent is up and running, register your instance with CodeDeploy, and, finally, tag the instance.
Note: You will be using the command line for both your Lightsail instance and on your local machine. Pay careful attention to the instructions to ensure you’re issuing the commands on the right command line.
- Start an SSH session by clicking on the terminal icon next to the name of your instance
- On the command line of the Lightsail terminal session enter the command below to verify the CodeDeploy agent is running.
sudo service codedeploy-agent status
You should see a response similar to the one below (the PID will be different):
The AWS CodeDeploy agent is running as PID 2783
3. Enter the command below using the AWS CLI in a terminal session on your local machine to register your Lightsail instance with CodeDeploy.
NOTE: Replace <IAM User ARN
> with the value in your document and the <Desired Region
> with the appropriate Region.
NOTE: If you did not name your Lightsail instance codedeploy
you will need to adjust the –instance-name
parameter accordingly.
NOTE: The command does not provide any output
aws deploy register-on-premises-instance --instance-name codedeploy --iam-user-arn <IAM User ARN> --region <Desired Region>
- Enter the following command using the AWS CLI in a terminal session on your local machine to tag your Lightsail instance in CodeDeploy. The tag will be used by CodeDeploy to know where to install your code.
NOTE: If you did not name your Lightsail instancecodedeploy
you will need to adjust the–instance-name
parameter accordingly.
NOTE: Replace <Desired Region
> with the appropriate Region.
NOTE: The command does not provide any output
aws deploy add-tags-to-on-premises-instances --instance-names codedeploy --tags Key=Name,Value=CodeDeployLightsailDemo --region <Desired Region>
5. Enter the command below using the AWS CLI in a terminal session on your local machine to verify your machine was successfully registered:
NOTE: Replace <Desired Region
> with the appropriate Region.
aws deploy list-on-premises-instances --region <Desired Region>
You should see output similar to:
{
"instanceNames": [
"codedeploy"
]
}
At this point you are now ready to setup your actual code deployment using CodePipeline and CodeDeploy.
Setup the application in CodeDeploy
- Navigate to the CodeDeploy console, make sure you’re in the correct Region, and click Create application.
- Enter
CodeDeployLightsailDemo
for the Application name and select EC2/On-premises under Compute platform. Click Create application. - In the Deployment groups section Click Create deployment group.
- Enter
CodeDeployLightsailDemoDeploymentGroup
for the Deployment group name. - Click in the text box for Enter a service role and select the service role you created earlier (
CodeDeployServiceRole
) - Under Environment configuration check the box for On-premises instances. Under Key enter Name and under Value enter.
- Under Load balancer uncheck Enable load balancing.
- Click Create deployment group.
Fork the GitHub Repo
In this section, you connect your GitHub account to CodePipeline so that whenever you push a change to GitHub your new code will automatically be deployed. For this tutorial, I placed a small demo application in a GitHub repository. These next steps guide you through forking that code into your own GitHub account.
- Sign into GithHub.
- Navigate to the demo repository: http://github.com/mikegcoleman/codedeploygithubdemo
- To the right of the repository name at the top click the Fork
- Click on the account that you want to fork the repository into.
After a few seconds the fork process completes, and you are redirected to the new repo in your account.
Setup CodePipeline
As the name implies, CodePipeline allows you to create an automated set of steps for your application deployment. For instance, build and test processes that must happen before a final deployment step. In this example you’re going to build a very simple pipeline that will redeploy your application when a change is pushed to the associated GitHub repository.
- Navigate to the CodePipeline console, ensure you’re in the correct Region, and click Create pipeline.
- Enter
CodeDeployLightsailDemoPipeline
for the Pipeline name. - Click on Advanced Settings. Under Artifact store click the radio button next to Custom Location. Click into the Bucket text box and select the S3 bucket you created earlier. Click Next.
- From the Source provider drop down choose Click Connect to GitHub and follow any prompts to authorize CodePipeline to access your GitHub account.
- Note: If you’ve connected GitHub previously there will not be any additional prompts.
- Click in the Repository text box and select the repository you forked earlier. The name should be
<your github username>/codedeploygithubdemo
. - Click in the Branch box and choose Click Next. Since there isn’t a build stage click Skip build stage and confirm by clicking Skip.
- Choose AWS CodeDeploy from the Deploy provider Ensure the appropriate Region is selected. Choose CodeDeployLightsailDemo from the Application name list. Choose CodeDeployLightsailDemoDeploymentGroup from the Deployment group list.
- Click Next.
- Click Create pipeline.
- You’ll be taken to the details page for your pipeline, and can watch the status of the pipeline update. Once the Deploy step has a status of succeeded feel free to move on to the next section.
Test and Update the Application
In this final section you to verify the application deployed, and then you’ll make an update to the application to kick off a new deployment. Finally, you’ll verify that the update was successfully pushed to your server.
- Navigate in your web browser to the IP address of your Lightsail instance. You can find the IP address on the card for your instance on the Lightsail home page. You should see a simple webpage displayed.
- Move to the command line of your local machine, and clone the GitHub repository, being sure to insert your GitHub username.NOTE: If you are using SSH to authenticate to GitHub adjust the GitHub command accordingly
git clone https://github.com/<your github username>/codedeploygithubdemo
You should see output similar to the following:Cloning into 'codedeploygithubdemo'...
remote: Enumerating objects: 49, done.
remote: Counting objects: 100% (49/49), done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 49 (delta 25), reused 36 (delta 12), pack-reused 0
Unpacking objects: 100% (49/49), done.
- Change into the directory with the website code:
cd codedeploygithubdemo
- Using an editor of your choice edit the html file by changing the background color to purple:
background-color: purple;
- Push the changes to GitHub by issuing each of the following commands one at a time:
git add index.html
git commit -m “new background color”
git push origin master
- Navigate back to the CodePipeline console and click on the name of your pipeline. You should see that the change from GitHub has been picked up and the pipeline is deploying your website. Once the pipeline has successfully completed move to the next step.
- Reload to demo website to see that the background color has changed.
Conclusion
Congratulations on finishing this tutorial. You should now have an understanding of how to automate the deployment and updating of your application running on Lightsail using CodeDeploy and CodePipeline. As a next step, you might want to try and deploy a more complex application to Lightsail, including adding a build step. You can find information on how to do that in AWS CodeBuild documentation.