Skip to content

Instantly share code, notes, and snippets.

@dayitv89
Last active December 11, 2024 18:15
Show Gist options
  • Select an option

  • Save dayitv89/593522a6e05b5d0ae1d70a0a08519109 to your computer and use it in GitHub Desktop.

Select an option

Save dayitv89/593522a6e05b5d0ae1d70a0a08519109 to your computer and use it in GitHub Desktop.
GitHub action to deploy rails app into AWS ECS
# .github/workflows/aws.yml
# This workflow will build and push a new container image to Amazon ECR,
# and then will deploy a new task definition to Amazon ECS, when a release is created
#
# To use this workflow, you will need to complete the following set-up steps:
#
# 1. Create an ECR repository to store your images.
# For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`.
# Replace the value of `ECR_REPOSITORY` in the workflow below with your repository's name.
# Replace the value of `aws-region` in the workflow below with your repository's region.
#
# 2. Create an ECS task definition, an ECS cluster, and an ECS service.
# For example, follow the Getting Started guide on the ECS console:
# https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun
# Replace the values for `service` and `cluster` in the workflow below with your service and cluster names.
#
# 3. Store your ECS task definition as a JSON file in your repository.
# The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`.
# Replace the value of `task-definition` in the workflow below with your JSON file's name.
# Replace the value of `container-name` in the workflow below with the name of the container
# in the `containerDefinitions` section of the task definition.
#
# 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
# See the documentation for each action used below for the recommended IAM policies for this IAM user,
# and best practices on handling the access key credentials.
on:
push:
branches: [ master ]
name: Deploy to Amazon ECS
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure 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: ap-south-1
- 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: myproj-rails
IMAGE_TAG: ${{ github.sha }}
ENIGMA_URL: ${{secrets.ENIGMA_URL}}
ENIGMA_TOKEN: ${{secrets.ENIGMA_TOKEN}}
ENIGMA_PATH: ${{secrets.ENIGMA_PATH}}
ENIGMA_KEY: ${{secrets.ENIGMA_KEY}}
SECRET_KEY_BASE: ${{secrets.SECRET_KEY_BASE}}
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build . --file build/Dockerfile --tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG --build-arg ENIGMA_URL_ARG=$ENIGMA_URL --build-arg ENIGMA_TOKEN_ARG=$ENIGMA_TOKEN --build-arg ENIGMA_PATH_ARG=$ENIGMA_PATH --build-arg ENIGMA_KEY_ARG=$ENIGMA_KEY --build-arg SECRET_KEY_BASE_ARG=$SECRET_KEY_BASE
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: .github/workflows/task-definition.json
container-name: myproj-rails
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: myproj-rails-server
cluster: prod
# build/Dockerfile
FROM ruby:2.7.1-buster
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y nodejs yarn default-mysql-client nano --no-install-recommends && rm -rf /var/lib/apt/lists/*
ARG APP_ENV=production
ENV RAILS_ENV=$APP_ENV
ENV RAKE_ENV=$APP_ENV
ENV RAILS_SERVE_STATIC_FILES true
ENV RAILS_LOG_TO_STDOUT true
ARG ENIGMA_URL_ARG=https://enigma.herokuapp.com/api1/service
ENV ENIGMA_URL=$ENIGMA_URL_ARG
ARG ENIGMA_TOKEN_ARG=null
ENV ENIGMA_TOKEN=$ENIGMA_TOKEN_ARG
ARG ENIGMA_PATH_ARG=rails-server
ENV ENIGMA_PATH=$ENIGMA_PATH_ARG
ARG ENIGMA_KEY_ARG=null
ENV ENIGMA_KEY=$ENIGMA_KEY_ARG
ARG SECRET_KEY_BASE_ARG=null
ENV SECRET_KEY_BASE=$SECRET_KEY_BASE_ARG
COPY Gemfile /usr/src/app/
COPY Gemfile.lock /usr/src/app/
RUN bundle config --global frozen 1
RUN bundle config set without 'development test'
RUN bundle install
COPY . /usr/src/app
RUN bundle exec rails assets:precompile
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]
//.github/workflows/task-definition.json
{
"ipcMode": null,
"executionRoleArn": "arn:aws:iam::164043721925:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"dnsSearchDomains": null,
"environmentFiles": null,
"logConfiguration": {
"logDriver": "awslogs",
"secretOptions": null,
"options": {
"awslogs-group": "/ecs/myproj-deploy",
"awslogs-region": "ap-south-1",
"awslogs-stream-prefix": "ecs"
}
},
"entryPoint": null,
"portMappings": [
{
"hostPort": 3000,
"protocol": "tcp",
"containerPort": 3000
}
],
"command": null,
"linuxParameters": null,
"cpu": 0,
"environment": [],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"mountPoints": [],
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": null,
"memoryReservation": 1024,
"volumesFrom": [],
"stopTimeout": null,
"image": "164043721925.dkr.ecr.ap-south-1.amazonaws.com/myproj-rails:latest",
"startTimeout": null,
"firelensConfiguration": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "myproj-rails"
}
],
"placementConstraints": [],
"memory": "2048",
"taskRoleArn": "arn:aws:iam::164043721925:role/ecsTaskExecutionRole",
"compatibilities": [
"EC2",
"FARGATE"
],
"taskDefinitionArn": "arn:aws:ecs:ap-south-1:164043721925:task-definition/myproj-deploy:1",
"family": "myproj-deploy",
"requiresAttributes": [
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "ecs.capability.execution-role-awslogs"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.ecr-auth"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.task-iam-role"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "ecs.capability.execution-role-ecr-pull"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
},
{
"targetId": null,
"targetType": null,
"value": null,
"name": "ecs.capability.task-eni"
}
],
"pidMode": null,
"requiresCompatibilities": [
"FARGATE"
],
"networkMode": "awsvpc",
"cpu": "1024",
"revision": 4,
"status": "ACTIVE",
"inferenceAccelerators": null,
"proxyConfiguration": null,
"volumes": []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment