Skip to content

Deploy

Deploy #36

Workflow file for this run

name: Deploy
on:
workflow_dispatch:
branches:
- development.v2
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
AWS_ACCOUNT: ${{ github.ref_name == 'master' && 'UNKNOWN' || 209330743443 }}
AWS_REGION: us-east-1
NAMESPACE: ida
ENVIRONMENT: ${{ github.ref_name == 'master' && 'production' || 'staging' }}
TAG: ${{ github.ref_name == 'master' && 'latest' || 'staging' }}
TFLINT_PLUGIN_CACHE: .terraform.d/plugin-cache
TF_ROOT: ./tf
TF_VERSION: 1.6
TG_VERSION: 0.67.16
OIDC_ROLE_NAME: OIDCGithubActionsRole
permissions:
contents: write
id-token: write # OIDC permission.
jobs:
build_app:
name: 'Build App'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- id: set-oidc-role
uses: mathiasvr/command-output@v2.0.0
with:
run: |
echo "arn:aws:iam::${{ env.AWS_ACCOUNT }}:role/${{ env.OIDC_ROLE_NAME }}"
- id: oidc-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ steps.set-oidc-role.outputs.stdout }}
- id: ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: 'true'
- id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.AWS_ACCOUNT }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.NAMESPACE }}.app
tags: |
type=raw,priority=200,value=${{ env.TAG }}
type=sha,priority=100,prefix=,format=long
- uses: docker/build-push-action@v3
with:
context: .
file: config/docker/Dockerfile.app
push: true
cache-from: |
type=gha,scope=app.production
type=gha,scope=app.install
type=gha,scope=app.reqs
type=gha,scope=app.base
cache-to: |
type=gha,scope=app.production,mode=max
target: production
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build_proxy:
name: 'Build Proxy'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- id: set-oidc-role
uses: mathiasvr/command-output@v2.0.0
with:
run: |
echo "arn:aws:iam::${{ env.AWS_ACCOUNT }}:role/${{ env.OIDC_ROLE_NAME }}"
- id: oidc-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ steps.set-oidc-role.outputs.stdout }}
- id: ecr
uses: aws-actions/amazon-ecr-login@v2
with:
mask-password: 'true'
- id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.AWS_ACCOUNT }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.NAMESPACE }}.proxy
tags: |
type=raw,priority=200,value=${{ env.TAG }}
type=sha,priority=100,prefix=,format=long
- uses: docker/build-push-action@v3
with:
context: .
file: config/docker/Dockerfile.proxy
push: true
cache-from: |
type=gha,scope=proxy.serve
cache-to: |
type=gha,scope=proxy.serve,mode=max
target: serve
tags: ${{ steps.meta.outputs.tags }}
build_ui:
name: 'Build UI'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- id: set-oidc-role
uses: mathiasvr/command-output@v2.0.0
with:
run: |
echo "arn:aws:iam::${{ env.AWS_ACCOUNT }}:role/${{ env.OIDC_ROLE_NAME }}"
- id: oidc-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ steps.set-oidc-role.outputs.stdout }}
- id: parse-oauth-client-id
uses: mathiasvr/command-output@v2.0.0
env:
OAUTH_CLIENT_ID: ${{ github.ref_name == 'master' && secrets.OAUTH_CLIENT_ID_PRODUCTION || secrets.OAUTH_CLIENT_ID_STAGING }}
with:
run: |
echo "${{ env.OAUTH_CLIENT_ID }}.${{ env.NAMESPACE }}.${{ env.ENVIRONMENT }}"
- uses: docker/build-push-action@v5
env:
OAUTH_CLIENT_ID: ${{ steps.parse-oauth-client-id.outputs.stdout }}
with:
context: .
file: config/docker/Dockerfile.ui
build-args: |
ENV=${{ env.ENVIRONMENT }}
BUILD=${{ github.sha }}
OAUTH_CLIENT_ID=${{ env.OAUTH_CLIENT_ID }}
load: true
push: false
cache-from: |
type=gha,scope=ui.production
type=gha,scope=ui.reqs
type=gha,scope=ui.base
cache-to: |
type=gha,scope=ui.production,mode=max
target: production
tags: ${{ env.NAMESPACE }}.ui:build
- uses: shrink/actions-docker-extract@v2
id: extract
with:
image: ${{ env.NAMESPACE }}.ui:build
path: /opt/ui/dist/spa/.
- uses: actions/upload-artifact@v4
with:
name: build-artifact
path: ${{ steps.extract.outputs.destination }}
if-no-files-found: error
include-hidden-files: true
should-provision-tf:
name: 'Provision?'
runs-on: ubuntu-latest
if: false # NOTE: Currently disabled...
needs:
- build_app
- build_proxy
- build_ui
outputs:
apply: ${{ steps.changed-tf.outputs.any_changed }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: changed-tf
uses: tj-actions/changed-files@v46
with:
since_last_remote_commit: true
files: tf/**/*.{tf,hcl}
provision-modules:
name: "Provision Modules"
runs-on: ubuntu-latest
needs:
- should-provision-tf
if: >
false &&
always() &&
!failure() &&
!cancelled() &&
(github.event_name == 'pull_request' && github.event.pull_request.merged == true) &&
needs.should-provision-tf.outputs.apply == 'true'
steps:
- uses: actions/checkout@v4
- id: create-caches
run: |
mkdir -p ~/${{ env.TFLINT_PLUGIN_CACHE }}
- uses: actions/cache@v4
with:
path: ~/${{ env.TFLINT_PLUGIN_CACHE }}
key: ${{ runner.os }}-tflint-plugin-cache-${{ hashFiles('**/.terraform.lock.hcl') }}
restore-keys: |
${{ runner.os }}-tflint-plugin-cache-
- id: set-oidc-role
uses: mathiasvr/command-output@v2.0.0
with:
run: |
echo "arn:aws:iam::${{ env.AWS_ACCOUNT }}:role/${{ env.OIDC_ROLE_NAME }}"
- id: oidc-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ steps.set-oidc-role.outputs.stdout }}
output-credentials: true
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
terraform_wrapper: false
- id: setup-terragrunt
uses: autero1/action-terragrunt@v3
with:
terragrunt-version: ${{ env.TG_VERSION }}
token: ${{ secrets.GITHUB_TOKEN }}
- id: define-modules
uses: mathiasvr/command-output@v2.0.0
env:
GRAPH: '["authorization", "security", "network", "firewall", "load-balancer", "cdn", "datastores", "orchestration", "ida"]'
with:
run: >
echo -n ${{ env.GRAPH }} |
sed -e 's/\[//g' -e 's/\]//g' -e 's/\,//g' -e 's/\"//g'
- id: parse-modules
uses: mathiasvr/command-output@v2.0.0
env:
TRAP: >
trap 'echo "exit-code=$?" >> "$GITHUB_OUTPUT"' EXIT
APPLY: >
./config/scripts/tf.apply.sh
${{ env.TF_ROOT }}/environments/${{ env.ENVIRONMENT }}/${{ env.AWS_REGION }}
"${{ steps.define-modules.outputs.stdout }}"
with:
run: |
${{ env.TRAP }}
${{ env.APPLY }}
deploy:
name: 'Deploy'
needs: provision-modules
if: >
always() &&
!failure() &&
!cancelled()
runs-on: ubuntu-latest
steps:
- id: set-oidc-role
uses: mathiasvr/command-output@v2.0.0
with:
run: |
echo "arn:aws:iam::${{ env.AWS_ACCOUNT }}:role/${{ env.OIDC_ROLE_NAME }}"
- id: oidc-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ steps.set-oidc-role.outputs.stdout }}
- uses: brunocascio/ecs-deploy@v2.0.0
id: ecs-deploy
env:
ECS_CLUSTER: ecs-cluster
ECS_SERVICE: ecs-service
TASK_DEFINITION: ida-ecs-task-definition-app
with:
args: >
deploy
${{ env.NAMESPACE }}-${{ env.ENVIRONMENT }}-${{ env.ECS_CLUSTER }}
${{ env.NAMESPACE }}-${{ env.ENVIRONMENT }}-${{ env.ECS_SERVICE }}
--task=${{ env.NAMESPACE }}-${{ env.ENVIRONMENT }}-${{ env.TASK_DEFINITION }}
--timeout=600
- uses: actions/download-artifact@master
id: artifact
if: steps.ecs-deploy.outcome == 'success'
with:
name: build-artifact
path: ${{ runner.temp }}/dist
- id: assets-deploy
if: steps.artifact.outcome == 'success'
env:
BUCKET: assets
run: >
aws s3 sync
${{ runner.temp }}/dist
s3://${{ env.NAMESPACE }}-${{ env.ENVIRONMENT }}-${{ env.BUCKET }}-${{ env.AWS_ACCOUNT }}
--delete
invalidate:
name: 'Invalidate Cloudfront'
needs: deploy
if: always() && !failure() && !cancelled()
runs-on: ubuntu-latest
steps:
- id: set-oidc-role
uses: mathiasvr/command-output@v2.0.0
with:
run: |
echo "arn:aws:iam::${{ env.AWS_ACCOUNT }}:role/${{ env.OIDC_ROLE_NAME }}"
- id: oidc-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_REGION }}
role-to-assume: ${{ steps.set-oidc-role.outputs.stdout }}
output-credentials: true
- id: set-distribution
env:
FILTER: '.ResourceTagMappingList[].ResourceARN'
NAME: cloudfront
REGION: us-east-1 # Always the case for cloudfront.
run: >
echo "DISTRIBUTION=$(aws
resourcegroupstaggingapi
get-resources
--tag-filters Key=Name,Values=${{ env.NAMESPACE }}-${{ env.ENVIRONMENT }}-${{ env.NAME }}
--resource-type-filters ${{ env.NAME }}
--region=${{ env.AWS_REGION }}
| jq -r ${{ env.FILTER }}
| sed 's:.*/::')"
>> $GITHUB_OUTPUT
- uses: chetan/invalidate-cloudfront-action@v2
env:
DISTRIBUTION: ${{ steps.set-distribution.outputs.DISTRIBUTION }}
AWS_REGION: us-east-1
PATHS: '/db/*'
should-deploy-docs:
name: 'Docs?'
runs-on: ubuntu-latest
needs: deploy
if: false && always() && !failure() && !cancelled()
outputs:
deploy: ${{ steps.changed-docs.outputs.any_changed }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: changed-docs
uses: tj-actions/changed-files@v46
with:
since_last_remote_commit: true
files: docs/**/*.{md,py,rst,txt}
files_ignore: docs/README.md
deploy_docs:
name: 'Deploy Docs'
needs:
- should-deploy-docs
if: >
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push' &&
github.ref_name == 'development.v2' &&
needs.should-deploy-docs.outputs.deploy == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v3
with:
context: .
file: config/docker/Dockerfile.docs
load: true
cache-from: |
type=gha,scope=docs.render
type=gha,scope=docs.install
type=gha,scope=docs.reqs
type=gha,scope=docs.base
cache-to: |
type=gha,scope=docs.render,mode=max
target: render
tags: ${{ env.NAMESPACE }}.docs:render
- uses: shrink/actions-docker-extract@v2
id: extract
with:
image: ${{ env.NAMESPACE }}.docs:render
path: /opt/docs/_build/html/.
- uses: peaceiris/actions-gh-pages@v3
with:
publish_branch: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ${{ steps.extract.outputs.destination }}
force_orphan: true