Skip to content

AWS

2 posts with the tag “AWS”

Automatic Deployment to EC2 When Pushed to GitHub Actions

I tried the method of automatic deployment to EC2 using GitHub Actions with reference to the article below.

https://qiita.com/kaino5454/items/bae4bca47e6f409e072f

I made some changes, so here’s a record for future reference.

Prerequisites

  • You have a GitHub account and remote repository
  • A local repository is placed on the EC2 instance and can push to GitHub via SSH
  • You have an AWS account
  • You can SSH into the EC2 instance using a key pair

Adding Secrets for GitHub Actions

Open the repository page you want to apply automatic deployment to, and click the “Settings” tab in the upper right.

Then select “Secrets and variables” → “Actions” from the menu on the left.

Image from Gyazo

You can add secrets to be used in GitHub Actions by clicking the “New repository secret” button shown in the image above.

We will add each of the following Secrets one by one:

  • AWS_ACCESS_KEY
  • AWS_SECRET_ACCESS_KEY
  • USER_HOST_NAME
  • EC2_SECURITY_GROUP_ID
  • PRIVATE_KEY

AWS_ACCESS_KEY and AWS_SECRET_ACCESS_KEY

First, create an AWS IAM role and add an access key and secret key.

  1. Log in to the AWS Management Console and open the IAM service

    Image from Gyazo

  2. Select “Users” from the menu on the left and click the “Create user” button

    Image from Gyazo

  3. Enter a username and select “Next”

    Image from Gyazo

  4. Check “Attach policies directly”, check “AmazonEC2FullAccess” for permission policies, and click “Next”

    Image from Gyazo

  5. Click “Create user”

    Image from Gyazo

  6. Select the created user and click the “Create access key” button

    Image from Gyazo

  7. Check “Command Line Interface” and the confirmation checkbox, then click “Next”

    Image from Gyazo

  8. Click the “Create access key” button

    Image from Gyazo

  9. Copy the “Access key ID” and “Secret access key”

    Image from Gyazo

  10. Add the values you copied to GitHub Secrets as the following two:

    • AWS_ACCESS_KEY
    • AWS_SECRET_ACCESS_KEY

Now you have added the secret key to the AWS IAM role.

USER_HOST_NAME

Next, add the username and hostname of the EC2 instance to GitHub Secrets.

  1. Open the EC2 instance page, check the instance, and click the “Connect” button.

    Image from Gyazo

  2. Open the “SSH client” tab and copy the part at the bottom where it says “Example:” that combines the username and hostname.

    Image from Gyazo

  3. Add the copied part to GitHub Secrets with the following name:

    • USER_HOST_NAME

Now you have added the username and hostname of the EC2 instance.

PRIVATE_KEY

To SSH connect from GitHub Actions to the EC2 instance, you need to register the private key in GitHub secrets.

You should have created a key for SSH connection when creating the EC2 instance, so use that to enable SSH connection to the EC2 instance.

This assumes you’re using a pem file.

Run the following command to copy the contents of the file:

Terminal window
cat {file path}

It’s usually saved in the following location:

Terminal window
cat ~/.ssh/{filename}.pem

Add the copied part to GitHub Secrets with the following name:

  • PRIVATE_KEY

EC2_SECURITY_GROUP_ID

Add the security group ID of the EC2 instance to GitHub Secrets.

  • EC2_SECURITY_GROUP_ID

Creating GitHub Actions Workflow

Create a .github/workflows/ec2-deploy.yml file in the root directory of the repository and write the following content.

In the case below, it will be executed when pushed to the main branch of the repository.

Replace the part on line 46 that says “repository file path” with the actual path of your repository.

Also, this code assumes starting with docker compose, but change it as needed.

ec2-deploy.yml
name: Deploy to EC2
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
# Install IP acquisition library
- name: Public IP Install
id: ip
uses: haythem/[email protected]
# Checkout Branch
- name: Checkout
uses: actions/checkout@v2
# Install AWS CLI
- name: AWS CLI install
run: |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install --update
aws --version
# Set keys for AWS CLI
- name: AWS set Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
# Deploy
- name: Deploy
run: |
# Open security group for SSH
aws ec2 authorize-security-group-ingress --group-id ${{ secrets.EC2_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32
# SSH connect and git pull
echo "${{ secrets.PRIVATE_KEY }}" > private_key
chmod 600 private_key
ssh -oStrictHostKeyChecking=no ${{ secrets.USER_HOST_NAME }} -i private_key "cd repository file path && git fetch --prune && git checkout main && git pull origin main && sudo docker compose down && sudo docker system prune --all --force && sudo docker compose up -d --build"
# Close security group for SSH
aws ec2 revoke-security-group-ingress --group-id ${{ secrets.EC2_SECURITY_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32

Verification

Once the setup is complete, push changes to the main branch to verify that automatic deployment works properly.

Terminal window
git add .
git commit -m "Setup GitHub Actions auto-deploy"
git push origin main

You can check the execution status of the workflow in the “Actions” tab of the GitHub repository.

Registering Cloudflare Subdomains in AWS Route53

I registered a Cloudflare domain as a subdomain in AWS Route53, so I’m documenting the process for future reference.

Using this method, you can utilize parts of your Cloudflare-managed domain with AWS services.

Prerequisites

  • A domain managed by Cloudflare (e.g., example.com)
  • An AWS account

First, we’ll prepare for DNS delegation of the subdomain in Cloudflare.

In this example, we’ll delegate the subdomain aws.example.com to Route53.

Creating a Hosted Zone in Route53

To delegate a Cloudflare domain to Route53, you first need to create a hosted zone in Route53.

  1. Log in to the AWS Management Console

    Image from Gyazo

  2. Click on the icon in the top left, then “Networking & Content Delivery” >> “Route53”

    Image from Gyazo

  3. Select “Hosted zones” from the menu icon in the top left, then click the “Create hosted zone” button

    Image from Gyazo

  4. Enter the subdomain you want to delegate (e.g., aws.example.com) in the domain name field, select “Public hosted zone”, and click the “Create hosted zone” button

    Image from Gyazo

When the hosted zone is created, four NS records (name servers) are automatically generated. Make note of these NS record values.

For example:

ns-1234.awsdns-12.org
ns-567.awsdns-34.com
ns-890.awsdns-56.net
ns-1234.awsdns-78.co.uk

Setting up NS Records in Cloudflare

Next, add NS records specifying Route53’s name servers in Cloudflare’s DNS settings.

  1. Log in to the Cloudflare dashboard and select your domain (example.com)

    Image from Gyazo

  2. Click on the “DNS” tab in the left menu and navigate to the “Records” section

    Image from Gyazo

  3. Click “Add record”

    Image from Gyazo

  4. Select “NS” as the type, enter the subdomain name (e.g., aws) in the “Name” field, enter one of the Route53 NS records (e.g., ns-1234.awsdns-78.co.uk) in the name server field, and click the “Save” button

    Image from Gyazo

  5. Repeat step 4 for all four NS records obtained from Route53

Wait for DNS Propagation

It takes time for DNS setting changes to be reflected.

Usually, it takes from a few minutes to several hours, but in some cases, it may take up to 48 hours.

Verifying the Configuration

To check if the DNS settings have been reflected, you can use the following commands:

Terminal window
dig NS aws.example.com

If configured correctly, the Route53 name servers should be returned.

For example, part of the output should look like this:

;; ANSWER SECTION:
aws.example.com. 3600 IN NS ns-1234.awsdns-12.org.
aws.example.com. 3600 IN NS ns-567.awsdns-34.com.
aws.example.com. 3600 IN NS ns-890.awsdns-56.net.
aws.example.com. 3600 IN NS ns-1234.awsdns-78.co.uk.

Now, DNS management for aws.example.com has been delegated to Route53.

You can add necessary DNS records (A, CNAME, MX, etc.) for this subdomain in the Route53 hosted zone.