Using AWS CodeDeploy with LightSail instances

May 11, 2020
Configuring AWS Lightsail instances to work with AWS CodeDeploy is not straight forward. This is intentional because Lighsail is not supposed to be a full fledged solution. Lightsail is AWS's cheap alternative to Digital Ocean, Linode and other similar VPS providers.
And it's pretty darn cheap. Comes with enough bandwidth and static IP addresses, making it a good candidate to be used for non critical jobs.
As I mentioned before, this cannot be configured like the other EC2 instances. Fortunately, on-premise instances can be configured easily with AWS CodeDeploy. And here we'll be treating Lightsail instances as on-premise instances.
Here is the AWS Guide to configure on-premise instances with CodeDeploy.
Step 1: Install the AWS CLI, configure it (DIY)
Step 2: Register your instance with CodeDeploy
At this point your instance does not need to be running.
Have a look at the command in Step 2 in the AWS Guide. We'll be running the same command except --iam-user-arn option. The whole process becomes so much easier when we leave out this option because this command creates an IAM User with all the correct polices and permissions.
Our command looks like this:
aws deploy register --instance-name SupportApp --tags Key=name,Value=support-app --region us-west-2
You'll be running this command on your local machine. The IAM User you configured to work with the CLI in Step 1, needs to have the following policy attached. This allows to create the IAM user mentioned before.
{
  "Version": "2012-10-17",
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : [
        "codedeploy:*",
        "iam:CreateAccessKey",
        "iam:CreateUser",
        "iam:DeleteAccessKey",
        "iam:DeleteUser",
        "iam:DeleteUserPolicy",
        "iam:ListAccessKeys",
        "iam:ListUserPolicies",
        "iam:PutUserPolicy",
        "iam:GetUser",
        "tag:GetTags",
        "tag:GetResources"
      ],
      "Resource" : "*"
    }
  ]
}
Here's a sample output of the command:
Creating the IAM user... DONE
IamUserArn: arn:aws:iam::XXXXX:user/AWS/CodeDeploy/SupportApp
Creating the IAM user access key... DONE
AccessKeyId: AKIA3XXXXXXXXXXXXXX
SecretAccessKey: x/tPXXXXXXXXXXXXXXXXXXX
Creating the IAM user policy... DONE
PolicyName: codedeploy-agent
PolicyDocument: {
    "Version": "2012-10-17",
    "Statement": [ {
        "Action": [ "s3:Get*", "s3:List*" ],
        "Effect": "Allow",
        "Resource": "*"
    } ]
}
Creating the on-premises instance configuration file named codedeploy.onpremises.yml...DONE
Registering the on-premises instance... DONE
Adding tags to the on-premises instance... DONE
Copy the on-premises configuration file named codedeploy.onpremises.yml to the on-premises instance, and run the following command on the on-premises instance to install and configure the AWS CodeDeploy Agent:
aws deploy install --config-file codedeploy.onpremises.yml
After successfully running this, go to the CodeDeploy console in the correct AWS region. Then head on to On-premises instances under Deploy menu. You'll see that the instance has been registered.
But still your actual Lightsail instance has no connection with it, yet. In fact, it's okay not to create the Lightsail instance at this point.
This command will generate a file codedeploy.onpremises.yml in your working directory with the following content:
----
aws_access_key_id: <ACCESS_KEY>
aws_secret_access_key: <SECRET_ACCESS_KEY>
iam_user_arn: <IAM_USER_ARN>
region: <AWS_REGION>
Thanks to our decision to ignore --iam-user-arn option, this file will have all the correct values.
Step 3: Create your Lightsail instance
Create your Lightsail instance if you have not done it yet.
Step 4: Configure the Lightsail instance
Now SSH to your Lightsail instance.
The output of the command in Step 2 and the AWS Guide tell us to run another command aws deploy install --config-file ~/codedeploy.onpremises.yml in your on-premis instance.
No need to do it as this will result in the following error anyway:
Amazon EC2 instances are not supported.
Instead, we'll install the Code Deploy Agent manually by running the following commands one by one:
sudo apt -y install ruby wget
wget https://aws-codedeploy-us-west-2.s3.amazonaws.com/latest/install
chmod +x ./install
./install auto
This will install the Code Deploy Agent in the Lightsail instance. Open /etc/codedeploy-agent/conf/codedeploy.onpremises.yml using a text editor (vi) and paste the content of codedeploy.onpremises.yml which was generated as a output of the command in Step 2.
Now restart the Code Deploy Agent:
service codedeploy-agent restart
That's it. Now you can use this instance in Code Deploy like any other EC2 instance. To deploy to it, make sure to use the Tag that was used in Step 2 (Key=name and Value=support-app) in the Code Deploy Deployment Group. This is the only connection between your Application in CodeDeploy and the on-premise instance you registered before.
Note: If you attach a static ip to the Lightsail instance, you can do so before installing the Code Deploy Agent or you have to restart the Code Deploy agent service codedeploy-agent restart after attaching the new ip.
Note 2: If you're on Ubuntu 18.04 and got Directory not empty @ dir_s_rmdir .... error after deploying a revision, remove the *-cleanup files in /opt/codedeploy-agent/deployment-root/deployment-instructions/ folder.