A Step-by-Step Guide to Deploying an Application on AWS App Runner with GitHub Action workflow

Rajeshwar R - May 31 '23 - - Dev Community

Privacy-Protect

Share passwords and sensitive files over email or store them in insecure locations like cloud drives using nothing more than desktop or mobile web browsers like chrome and safari.

No special software. No need to create an account. It's free, open-source, keeps your private data a secret, and leave you alone.

App Runner

AWS App Runner is a fully managed container application service that lets you build, deploy, and run containerized web application and API services without prior infrastructure or container experience.

Cons of App Runner

Lack of EFS Mount Support:

The absence of support for mounting the Elastic File System (EFS). Instead, AWS offers an alternative solution with DynamoDB for handling data storage. The lack of EFS mount support might be a challenge for certain use cases:Limited File Storage Flexibility, Potential Performance Impact, Additional Configuration Complexity. However, by leveraging AWS's alternative storage solution, DynamoDB, developers can work around this limitation and continue to build scalable applications.

Go through this Architecture diagram.

Image description

Create a IAM role

This role is used by AWS App runner to access AWS ECR docker images.

The following are the step-by-step instructions to create a service role and associating AWSAppRunnerServicePolicyForECRAccess policy.

step 1
Create a role named with app-runner-service-role



{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "build.apprunner.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}


Enter fullscreen mode Exit fullscreen mode

step 2

Attach the AWSAppRunnerServicePolicyForECRAccess existing policy to the role app-runner-service-role.

Here the steps to deploy Privacy-Protect application in App Runner using GitHub Action

Create a AWS ECR private repostiory

Image description

Clone the repository



git clone https://github.com/r4jeshwar/privacy-protect.git
cd privacy-protect


Enter fullscreen mode Exit fullscreen mode

Migrate from Server deployment(Vercel-@sveltejs/adapter-vercel) to static site generator(@sveltejs/adapter-static)

First, Install npm i -D @sveltejs/adapter-static

Go to the svelte.config.js file delete the existing content and paste the below content in svelte.config.js file.



import adapter from "@sveltejs/adapter-static";
import { vitePreprocess } from "@sveltejs/kit/vite";
import { mdsvex } from "mdsvex";
import { resolve } from "path";

/** @type {import('@sveltejs/kit').Config} */
export default {
  extensions: [".md", ".svelte"],
  kit: {
    adapter: adapter({
       pages: 'build',
       assets: 'build',
      fallback: null,
      precompress: false,
      strict: true
    }),
    alias: {
      $components: resolve("src/components"),
      $icons: resolve("src/assets/icons"),
    },
    csp: {
      directives: {
        "base-uri": ["none"],
        "default-src": ["self"],
        "frame-ancestors": ["none"],
        "img-src": ["self", "data:"],
        "object-src": ["none"],
        // See https://github.com/sveltejs/svelte/issues/6662
        "style-src": ["self", "unsafe-inline"],
        "upgrade-insecure-requests": true,
        "worker-src": ["none"],
      },
      mode: "auto",
    },
  },
  preprocess: [
    mdsvex({
      extensions: [".md"],
      layout: {
        blog: "src/routes/blog/post.svelte",
      },
    }),
    vitePreprocess(),
  ],
};


Enter fullscreen mode Exit fullscreen mode

Note: This changes is to deploy in various infrastructure and to dockerize in small size. If you need to deploy in vercel ignore this.

Why we need to switch out the adapter from vercel to static ?

Adapter-Static allows deploying Vite.js application to various static hosting providers.It also simplifies the deployment process by eliminating the need for serverless infrastructure and configuration specific to Vercel.

Overall, migrating from Adapter-Vercel to Adapter-Static empowers you with greater flexibility, simplicity.

Dockerfile for privacy-protect to deploy in App Runner



FROM node:18-alpine as build

WORKDIR /app

COPY . .

RUN npm i
RUN npm run build


FROM nginx:stable-alpine

COPY --from=build /app/build/ /usr/share/nginx/html


Enter fullscreen mode Exit fullscreen mode

Push the changes to your repository to be picked up by the GH workflow we'll be setting up next

Configure the GitHub Action secrets

Go to your project repository, Go to settings in the security section click the Secrets and variables drop down and click Actions. Configure the variables.

Image description

  • AWS_ACCESS_KEY_ID is your AWS user access key.

  • AWS_SECRET_ACCESS_KEY is your AWS user secret key.

  • AWS_REGION is the region of AWS services where you creating.

  • ROLE_ARN is your IAM role ARN which you have created before which you named app-runner-service-role

Configure the new workflow in GitHub Action

Click set up a workflow by yourself

Image description

Next, on the file editor(main.yml), populate the below YAML file



name: Deploy to App Runner - Image based # Name of the workflow
on:
push:
branches: [ main ] # Trigger workflow on git push to main branch
workflow_dispatch: # Allow manual invocation of the workflow
jobs:

deploy:
runs-on: ubuntu-latest

steps:      
  - name: Checkout
    uses: actions/checkout@v2
    with:
      persist-credentials: false

  - name: Configure AWS credentials
    id: aws-credentials
    uses: aws-actions/configure-aws-credentials@v1
    with:
      aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
      aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      aws-region: ${{ secrets.AWS_REGION }}

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

  - name: Build, tag, and push image to Amazon ECR
    id: build-image
    env:
      ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
      ECR_REPOSITORY: privacy-protect
      IMAGE_TAG: ${{ github.sha }}
    run: |
      docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
      docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
      echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"  

  - name: Deploy to App Runner
    id: deploy-apprunner
    uses: awslabs/amazon-app-runner-deploy@main        
    with:
      service: privacy-protect-app-runner
      image: ${{ steps.build-image.outputs.image }}          
      access-role-arn: ${{ secrets.ROLE_ARN }}       
      region: ${{ secrets.AWS_REGION }}
      cpu : 1
      memory : 2
      port: 80
      wait-for-service-stability: true

  - name: App Runner ID
    run: echo "App runner ID ${{ steps.deploy-apprunner.outputs.service-id }}"
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode




GitHub Action runs successfully after a few minutes

You can see the AWS App Runner dashboard your application is up and running successfully.

Image description

. . . . . . . . . . . .