Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bootstrap AWS infrastructure #216

Merged
merged 16 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/

**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.next
**/.cache
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
**/build
**/dist
LICENSE
README.md
30 changes: 30 additions & 0 deletions .github/workflows/awsdeploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Based on https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service

name: aws ecs deploy - blake

on:
push:
branches:
- main

jobs:
deploy-core:
uses: ./.github/workflows/deploy-template.yml
with:
service-name: core
environment: staging
env-proper-name: blake
secrets:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

deploy-jobs:
uses: ./.github/workflows/deploy-template.yml
needs: deploy-core
with:
service-name: jobs
environment: staging
env-proper-name: blake
secrets:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
85 changes: 85 additions & 0 deletions .github/workflows/deploy-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Based on https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service

name: aws ecs deploy template

on:
workflow_call:
inputs:
service-name: # example: core
required: true
type: string
env-proper-name: # example: blake
required: true
type: string
environment: # example: staging
required: true
type: string
secrets:
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true

env:
AWS_REGION: us-east-1
ECR_REPOSITORY: pubpub-v7-${{ inputs.service-name }}
ECS_SERVICE: ${{ inputs.env-proper-name }}-${{inputs.service-name}}
ECS_CLUSTER: ${{inputs.env-proper-name}}-ecs-cluster-${{inputs.environment}}
ECS_TASK_DEFINITION_TEMPLATE: ${{ inputs.env-proper-name }}-${{inputs.service-name}}
CONTAINER_NAME: ${{inputs.service-name}}

jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production

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

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

- name: Get short sha
id: shortsha
run: echo "sha_short=$(git describe --always --abbrev=40 --dirty)" >> $GITHUB_OUTPUT

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

- name: Retrieve Task Definition contents from template
id: get-taskdef
run: |
aws ecs describe-task-definition \
--task-definition $ECS_TASK_DEFINITION_TEMPLATE \
--query taskDefinition >> template_task_def.json

- name: Interpolate image tag
id: write-tag
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ steps.shortsha.outputs.sha_short }}
run: |
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

- name: Fill in the new image ID in the Amazon ECS task definition
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@c804dfbdd57f713b6c079302a4c01db7017a36fc
with:
task-definition: template_task_def.json
container-name: ${{ env.CONTAINER_NAME }}
image: ${{ steps.write-tag.outputs.image }}

- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@df9643053eda01f169e64a0e60233aacca83799a
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: false
37 changes: 37 additions & 0 deletions .github/workflows/ecrbuild-all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Based on https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service

name: docker build to ECR

on:
push:
branches:
- main
pull_request:
types:
- opened
- synchronize

jobs:
build-core:
uses: ./.github/workflows/ecrbuild-template.yml
with:
package-name: core
secrets:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

build-intg-submissions:
uses: ./.github/workflows/ecrbuild-template.yml
with:
package-name: integration-submissions
secrets:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}

build-jobs:
uses: ./.github/workflows/ecrbuild-template.yml
with:
package-name: jobs
secrets:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
64 changes: 64 additions & 0 deletions .github/workflows/ecrbuild-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Based on https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-amazon-elastic-container-service

name: aws ecr build template

on:
workflow_call:
inputs:
package-name:
required: true
type: string
secrets:
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true

env:
AWS_REGION: us-east-1 # set this to your preferred AWS region, e.g. us-west-1
ECR_REPOSITORY_PREFIX: pubpub-v7 # set this to your Amazon ECR repository name

jobs:
build:
name: Build
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: ${{ vars.IAM_ROLE_TO_ASSUME }}
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Get short sha
id: shortsha
run: echo "sha_short=$(git describe --always --abbrev=40 --dirty)" >> $GITHUB_OUTPUT

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

- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ steps.shortsha.outputs.sha_short }}
PACKAGE: ${{ inputs.package-name }}
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build \
--platform linux/amd64 \
--build-arg PACKAGE=$PACKAGE \
--build-arg PACKAGE_DIR=$PACKAGE_DIR \
-t $ECR_REGISTRY/$ECR_REPOSITORY_PREFIX-$PACKAGE:$IMAGE_TAG \
.
docker push $ECR_REGISTRY/$ECR_REPOSITORY_PREFIX-$PACKAGE:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY_PREFIX-$PACKAGE:$IMAGE_TAG" >> $GITHUB_OUTPUT

62 changes: 62 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# syntax=docker/dockerfile:1

# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/

ARG NODE_VERSION=20.6.0
ARG PNPM_VERSION=8.14.3

ARG PACKAGE=core
ARG PORT=3000

################################################################################
# Use node image for base image for all stages.
FROM node:${NODE_VERSION}-alpine as base

# Install python deps for node-gyp
RUN apk add g++ make py3-pip

# Set working directory for all build stages.
WORKDIR /usr/src/app

# Install pnpm.
RUN --mount=type=cache,target=/root/.npm \
npm install -g pnpm@${PNPM_VERSION}

################################################################################
# Create a stage for building the application.
FROM base as monorepo
ARG PACKAGE

# Copy the rest of the source files into the image.
COPY . .

# Run the build script.
RUN ./bin/render-build.sh ${PACKAGE}

RUN pnpm --filter ${PACKAGE} --prod deploy /tmp/app

################################################################################
# Create a new stage to run the application with minimal runtime dependencies
# where the necessary files are copied from the build stage.
FROM base AS app
ARG PORT

# # needed so that the CMD can use this var
# ENV PACKAGE=$PACKAGE

# Use production node environment by default.
ENV NODE_ENV production

# Copy package.json so that package manager commands can be used.
COPY --from=monorepo /tmp/app \
./

# Run the application as a non-root user.
USER node

# Expose the port that the application listens on.
EXPOSE $PORT
# Run the application.
CMD pnpm start
Loading