DEV Community

Cover image for Deploying A Dockerized Golang App To AWS App Runner

Deploying A Dockerized Golang App To AWS App Runner

AWS App Runner is a fully managed container application service offered by Amazon Web Services (AWS). It is designed to simplify the process of building, deploying, and scaling containerized web applications and API services. 

In this demo, we will deploy a containerised golang app with a mongodb database running on EC2, to AWS AppRunner.

To begin, we will clone the project repo on github to our local machine. The project is a task management app that saves data to a mongodb database.

The project contains a dockerfile. We will use github actions to build and push the docker image to Amazon ECR. Ensure you have created the ecr repository.

name: Build and Push to ECR

on:
  push:
    branches: ['main']

env:
  AWS_REGION: 'eu-west-1'
  ECR_REPOSITORY: 'tasky'
  ACCOUNT_ID: '<fill in>'
  ROLE_NAME: 'github-actions-role'

permissions:
  id-token: write
  contents: read

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ env.ROLE_NAME }}
          role-session-name: github_action_session
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build and push image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
Enter fullscreen mode Exit fullscreen mode

Since AWS strongly recommends OIDC (OpenID Connect) over long-term access keys, we will configure oidc for the role 'github-actions-role'.

First, Create the OIDC provider:

aws iam create-open-id-connect-provider \
  --url https://token.actions.githubusercontent.com \
  --client-id-list sts.amazonaws.com \
  --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 \
  --profile 
Enter fullscreen mode Exit fullscreen mode

Next, configure an IAM role “github-actions-role“ with an IAM policy that gives github actions runner the required permssion to push to ECR, add a trust policy similar to the following:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<Account-ID>:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:<github-username>/tasky:ref:refs/heads/main"
        }
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Push your changes to the github repo and the workflow should be triggered.

Fig. 1: Github Workflow

Navigate to the ECR console to view the docker image in the repository.

Fig. 2: Docker image on ECR

Deploying The MongoDB instance on EC2

Navigating to the EC2 console and launch a t3.micro ubuntu instance. Ensure to have the following in your Security Group Configuration apart from SSH port 22:

Type: Custom TCP
Port: 27017
Source: 0.0.0.0/0
Enter fullscreen mode Exit fullscreen mode

Connect to the instance terminal and use the following commands to install MongoDB.
First, Install the public key using the following command.

curl -fsSL https://pgp.mongodb.com/server-7.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg
Enter fullscreen mode Exit fullscreen mode

Next, Add sources (Mongo 7.0 repo).

echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
Enter fullscreen mode Exit fullscreen mode

Reload the local package database and install the MongoDB packages using the command.

sudo apt update
sudo apt install -y mongodb-org
Enter fullscreen mode Exit fullscreen mode

To check if MongoDB is installed or not, verify using the following command.

mongod --version
Enter fullscreen mode Exit fullscreen mode

Run the following commands to start mongodb.

sudo systemctl start mongod
sudo systemctl enable mongod
sudo systemctl status mongod
Enter fullscreen mode Exit fullscreen mode

You should see an output similar to the following;

Fig.3: MongoDB service status

Creating a MongoDB User and Password

MongoDB doesn't have a default password when installed on Ubuntu. By default, MongoDB runs without authentication enabled.

Connect to MongoDB (no password needed initially):

mongosh
Enter fullscreen mode Exit fullscreen mode

Create an admin user:

use admin
db.createUser({
  user: "admin",
  pwd: "yourstrongpassword",
  roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"]
})

Enter fullscreen mode Exit fullscreen mode

MongoDB Configuration:

By default, the MongoDB server (mongod) only allows loopback connections from IP address 127.0.0.1 (localhost). To allow connections from elsewhere in your Amazon VPC, do the following:

Edit the /etc/mongod.conf file and look for the following lines.

# network interfaces
net:
  port: 27017
  bindIp: public-dns-name  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses
Enter fullscreen mode Exit fullscreen mode

NB: Replace public-dns-name with the actual public DNS name for your instance, for example ec2-11-22-33-44.us-west-2.compute.amazonaws.com.

To enable authentication in config, Add:

security:
  authorization: enabled
Enter fullscreen mode Exit fullscreen mode

Then, Restart MongoDB:

sudo systemctl restart mongod
Enter fullscreen mode Exit fullscreen mode

Creating The AppRunner Service

Navigate to the Apprunner console, click “Create Service“ button

Fig.5: Creating apprunner service

Click “Next” and on the “Configure service” page, fill in the required environment variables such as below;

NOTE:
When specifying the hostname in the MONGODB_URI, ensure you use the Private IP and NOT the Public IP of the host EC2 instance
Also, update the Port as necessary (our golang app is exposed on port 8080)
Enter fullscreen mode Exit fullscreen mode

Fig.6: Creating apprunner service

Navigate to the “Networking” section and under “Outgoing network traffic”, click “Custom VPC”.

Fig.7: Creating apprunner service

To create custom vpc endpoint, follow this guide

If the deployment is successful and service status changes to “Running” state as shown below.

Fig.8: Apprunner service

Copy the Default Domain URL and paste on your browser

Fig.9: App UI

Proceed to sign up and you will see a daily task management app like so;

to-do

Go ahead to play around with it. Data is persisted in mongodb so you can log out and back in.

Clean Up

To clean up resources, simply delete the EC2 instance as well as the App Runner service.

References

https://docs.aws.amazon.com/dms/latest/sbs/chap-mongodb2documentdb.02.html

https://www.geeksforgeeks.org/installation-guide/how-to-install-mongodb-on-aws-ec2-instance/

https://aws.amazon.com/apprunner/

Top comments (0)