-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add workflows to deploy AWS infrastructure with OpenTofu and to deplo…
…y Docker (#69)
- Loading branch information
1 parent
3a65859
commit b10acaf
Showing
25 changed files
with
531 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
name: Docker Build Workflow | ||
|
||
on: | ||
workflow_call: | ||
inputs: | ||
deployment: | ||
required: true | ||
type: string | ||
aws_region: | ||
description: 'AWS region' | ||
type: string | ||
required: false | ||
default: 'us-east-1' | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
services: | ||
registry: | ||
image: registry:2 | ||
ports: | ||
- 5000:5000 | ||
steps: | ||
- name: Checkout code | ||
uses: actions/[email protected] | ||
|
||
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
aws-region: ${{ inputs.aws_region }} | ||
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-role-shared | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
with: | ||
driver-opts: network=host | ||
|
||
- name: Login to Amazon ECR | ||
id: login-ecr | ||
uses: aws-actions/amazon-ecr-login@v2 | ||
|
||
- name: Compute image tag | ||
id: compute-image-tag | ||
run: | | ||
short_sha=$(git rev-parse --short ${{ github.sha }}) | ||
echo "tag=${{ steps.login-ecr.outputs.registry }}/${{ inputs.deployment }}-shared:$short_sha" >> $GITHUB_OUTPUT | ||
echo "short_sha=$short_sha" >> $GITHUB_OUTPUT | ||
- name: Check for image tag | ||
id: check-image-tag | ||
run: | | ||
found_tag=$(aws ecr list-images --repository-name ${{ inputs.deployment }}-shared --region ${{ inputs.aws_region }} --query 'imageIds[*].imageTag' | grep -q "${{ steps.compute-image-tag.outputs.short_sha }}"; echo $?) | ||
echo "found_tag=$found_tag" >> $GITHUB_OUTPUT | ||
- name: Build base Docker image | ||
# only build if the image tag doesn't exist | ||
if: steps.check-image-tag.outputs.found_tag == 1 | ||
uses: docker/build-push-action@v6 | ||
with: | ||
context: . | ||
push: true | ||
file: Dockerfile.base | ||
tags: localhost:5000/osm/osm_base | ||
|
||
- name: Build and push Docker image | ||
# only build if the image tag doesn't exist | ||
if: steps.check-image-tag.outputs.found_tag == 1 | ||
uses: docker/build-push-action@v6 | ||
with: | ||
context: . | ||
push: true | ||
tags: ${{ steps.compute-image-tag.outputs.tag }} | ||
file: web/${{ inputs.deployment }}/Dockerfile | ||
build-args: | | ||
BASE_IMAGE=localhost:5000/osm/osm_base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
name: Push to Docker image to AWS ECR and deploy to AWS EC2 | ||
|
||
on: | ||
workflow_dispatch: | ||
inputs: | ||
development-environment: | ||
description: Development environment to deploy to. | ||
required: true | ||
default: staging | ||
type: choice | ||
options: | ||
- staging | ||
- production | ||
pull_request: | ||
branches: | ||
- main | ||
types: | ||
- closed | ||
paths-ignore: | ||
- 'web/deploy/terraform/**' | ||
workflow_call: | ||
inputs: | ||
development-environment: | ||
description: Development environment to deploy to. Usually `staging` or `production` | ||
required: true | ||
default: staging | ||
type: string | ||
|
||
permissions: | ||
id-token: write | ||
contents: read | ||
|
||
jobs: | ||
set-development-environment: | ||
runs-on: ubuntu-latest | ||
name: Set development environment | ||
outputs: | ||
development-environment: ${{ steps.set-development-environment.outputs.development-environment }} | ||
steps: | ||
- name: Set development environment | ||
id: set-development-environment | ||
run: | | ||
if [[ "${{ github.event_name }}" == 'pull_request' || "${{ inputs.development-environment }}" == 'staging' ]]; then | ||
echo "development-environment=staging" >> $GITHUB_OUTPUT | ||
else | ||
echo "development-environment=production" >> $GITHUB_OUTPUT | ||
fi | ||
cat "$GITHUB_OUTPUT" | ||
cat "$GITHUB_OUTPUT" | grep 'development-environment' | ||
infrastructure-modified: | ||
runs-on: ubuntu-latest | ||
name: Check for modified infrastructure | ||
outputs: | ||
modified-files: ${{ steps.set-output.outputs.modified-files }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
name: Checkout repository | ||
|
||
- name: Get modified infrastructure configuration | ||
id: infrastructure-modified | ||
uses: tj-actions/changed-files@v45 | ||
with: | ||
files: | | ||
web/deploy/terraform/** | ||
- name: Set modified output | ||
id: set-output | ||
env: | ||
MODIFIED_FILES: ${{ steps.infrastructure-modified.outputs.any_modified }} | ||
run: | | ||
echo "modified-files=${MODIFIED_FILES}" >> $GITHUB_OUTPUT | ||
build-and-push: | ||
needs: [infrastructure-modified, set-development-environment] | ||
strategy: | ||
matrix: | ||
deployment: ["api", "dashboard"] | ||
uses: ./.github/workflows/build-docker.yml | ||
if: ( (github.event_name == 'pull_request' && github.event.pull_request.merged == true && needs.infrastructure-modified.outputs.modified-files != 'true' && needs.set-development-environment.result == 'success') || (github.event_name == 'workflow_dispatch') || (github.event_name == 'workflow_call') ) | ||
secrets: inherit | ||
with: | ||
deployment: ${{ matrix.deployment }} | ||
|
||
docker-up: | ||
needs: [build-and-push, set-development-environment, infrastructure-modified] | ||
if: ${{ always() && !cancelled() && needs.build-and-push.result == 'success' && ( (github.event_name == 'pull_request' && github.event.pull_request.merged == 'true' && needs.infrastructure-modified.outputs.modified-files != 'true') || (github.event_name == 'workflow_dispatch') || (github.event_name == 'push') || (github.event_name == 'workflow_call') )}} | ||
name: Deploy and run Docker images on EC2 | ||
uses: ./.github/workflows/docker-up.yml | ||
secrets: inherit | ||
with: | ||
development-environment: ${{ needs.set-development-environment.outputs.development-environment }} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
name: Deploy OpenTofu | ||
|
||
on: | ||
push: | ||
branches: | ||
- '**' | ||
- '!main' | ||
paths: | ||
- 'web/deploy/terraform/**' | ||
workflow_dispatch: | ||
inputs: | ||
development-environment: | ||
description: Development environment to deploy to. | ||
required: true | ||
default: staging | ||
type: choice | ||
options: | ||
- staging | ||
- production | ||
pull_request: | ||
branches: | ||
- main | ||
types: | ||
- closed | ||
paths: | ||
- 'web/deploy/terraform/**' | ||
env: | ||
working_directory_parent: ./web/deploy/terraform | ||
TF_VAR_AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} | ||
|
||
permissions: | ||
id-token: write | ||
contents: read | ||
|
||
jobs: | ||
set-development-environment: | ||
runs-on: ubuntu-latest | ||
name: Set development environment | ||
outputs: | ||
development-environment: ${{ steps.set-development-environment.outputs.development-environment }} | ||
steps: | ||
- name: Set development environment | ||
id: set-development-environment | ||
run: | | ||
if [[ "${{ github.event_name }}" == 'workflow_dispatch' && "${{ inputs.development-environment }}" == 'production' ]]; then | ||
echo 'development-environment=production' >> "$GITHUB_OUTPUT" | ||
else | ||
echo 'development-environment=staging' >> "$GITHUB_OUTPUT" | ||
fi | ||
cat "$GITHUB_OUTPUT" | ||
cat "$GITHUB_OUTPUT" | grep 'development-environment' | ||
deploy-shared-resources: | ||
needs: [set-development-environment] | ||
if: ${{ always() && !cancelled() && needs.set-development-environment.result == 'success' && needs.set-development-environment.outputs.development-environment == 'staging' }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout code | ||
uses: actions/[email protected] | ||
|
||
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
aws-region: ${{ secrets.AWS_REGION }} | ||
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-role-shared | ||
|
||
- name: Setup OpenTofu | ||
uses: opentofu/setup-opentofu@v1 | ||
|
||
- name: Initialize shared resources | ||
working-directory: ${{ env.working_directory_parent }}/shared | ||
run: | | ||
tofu init | ||
- name: Plan resources | ||
working-directory: ${{ env.working_directory_parent }}/shared | ||
run: | | ||
tofu plan -no-color -detailed-exitcode -out=tfplan | ||
continue-on-error: true | ||
|
||
- name: Deploy shared resources | ||
if: ${{ github.event_name != 'push' }} | ||
working-directory: ${{ env.working_directory_parent }}/shared | ||
run: | | ||
tofu apply -no-color -auto-approve tfplan | ||
deploy-environments: | ||
needs: [deploy-shared-resources, set-development-environment] | ||
runs-on: ubuntu-latest | ||
if: ${{ always() && !cancelled() && (needs.deploy-shared-resources.result == 'success' || (needs.deploy-shared-resources.result == 'skipped' && github.event_name == 'workflow_dispatch')) }} | ||
env: | ||
TF_VAR_PUBLIC_KEY: ${{ secrets.SSH_PUBLIC_KEY }} | ||
steps: | ||
- name: Checkout code | ||
uses: actions/[email protected] | ||
|
||
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
aws-region: ${{ secrets.AWS_REGION }} | ||
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-role-shared | ||
|
||
- name: Setup OpenTofu | ||
uses: opentofu/setup-opentofu@v1 | ||
|
||
- name: Initialize resources | ||
working-directory: ${{ env.working_directory_parent }}/${{ needs.set-development-environment.outputs.development-environment }} | ||
run: | | ||
tofu init | ||
- name: Plan resources | ||
working-directory: ${{ env.working_directory_parent }}/${{ needs.set-development-environment.outputs.development-environment }} | ||
run: | | ||
tofu plan -no-color -detailed-exitcode -out=tfplan | ||
continue-on-error: true | ||
|
||
- name: Deploy resources | ||
if: ${{ github.event_name != 'push' }} | ||
working-directory: ${{ env.working_directory_parent }}/${{ needs.set-development-environment.outputs.development-environment }} | ||
run: | | ||
tofu apply -no-color -auto-approve tfplan | ||
deploy-docker: | ||
needs: [deploy-environments, set-development-environment] | ||
if: ${{ always() && !cancelled() && needs.deploy-environments.result == 'success' && github.event_name != 'push' }} | ||
name: Push and deploy Docker images to EC2 | ||
uses: ./.github/workflows/deploy-docker.yml | ||
secrets: inherit | ||
with: | ||
development-environment: ${{ needs.set-development-environment.outputs.development-environment }} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
name: Execute `docker compose up` | ||
|
||
on: | ||
workflow_call: | ||
inputs: | ||
development-environment: | ||
description: Development environment to deploy to. Usually `staging` or `production` | ||
required: true | ||
default: staging | ||
type: string | ||
|
||
jobs: | ||
deploy: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/[email protected] | ||
|
||
- name: Get image tag | ||
run: | | ||
echo "RELEASE_TAG=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_ENV | ||
- name: Set host URI | ||
env: | ||
SSH_PROD_HOST: ${{ secrets.SSH_PROD_HOST }} | ||
SSH_STAGE_HOST: ${{ secrets.SSH_STAGE_HOST }} | ||
run: | | ||
if [[ ${{ inputs.development-environment }} == 'production' ]]; then | ||
echo "HOST_URI=${SSH_PROD_HOST}" >> $GITHUB_ENV | ||
else | ||
echo "HOST_URI=${SSH_STAGE_HOST}" >> $GITHUB_ENV | ||
fi | ||
- name: Configure SSH | ||
env: | ||
PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} | ||
DEPLOY_USERNAME: ${{ secrets.DEPLOYMENT_USERNAME }} | ||
run: | | ||
mkdir -p ~/.ssh/ | ||
echo "$PRIVATE_KEY" > ~/.ssh/aws | ||
chmod 600 ~/.ssh/aws | ||
cat >>~/.ssh/config <<END | ||
Host ${{ inputs.development-environment }} | ||
HostName ${HOST_URI} | ||
User ${DEPLOY_USERNAME} | ||
IdentityFile ~/.ssh/aws | ||
StrictHostKeyChecking no | ||
END | ||
- name: Log in to ECR | ||
env: | ||
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} | ||
AWS_REGION: ${{ secrets.AWS_REGION }} | ||
run: | | ||
ssh ${{ inputs.development-environment }} "aws ecr get-login-password --region ${AWS_REGION} | \ | ||
docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" | ||
- name: Run `docker compose up` on remote staging host | ||
env: | ||
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} | ||
AWS_REGION: ${{ secrets.AWS_REGION }} | ||
MONGODB_URI: ${{ secrets.MONGODB_URI }} | ||
LETSENCRYPT_ADMIN_EMAIL: ${{ secrets.LETSENCRYPT_ADMIN_EMAIL }} | ||
run: | | ||
ssh ${{ inputs.development-environment }} \ | ||
MONGODB_URI="${MONGODB_URI}" \ | ||
HOST_URI="${HOST_URI}" \ | ||
RELEASE_TAG="${RELEASE_TAG}" \ | ||
AWS_ACCOUNT_ID="${AWS_ACCOUNT_ID}" \ | ||
AWS_REGION="${AWS_REGION}" \ | ||
LETSENCRYPT_ADMIN_EMAIL=${LETSENCRYPT_ADMIN_EMAIL} \ | ||
docker compose -f - up -d < ./web/deploy/docker-compose.yaml | ||
- name: Prune Docker artifacts | ||
run: | | ||
ssh ${{ inputs.development-environment }} docker system prune -af --filter "until=24h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,9 @@ jobs: | |
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-python@v3 | ||
- uses: opentofu/setup-opentofu@v1 | ||
- name: Install tflint | ||
run: curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash | ||
- uses: pre-commit/[email protected] | ||
tox-tests: | ||
runs-on: ubuntu-latest | ||
|
Oops, something went wrong.