Deploy - dev #75
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
name: Deployment | |
run-name: Deploy - ${{ inputs.environment == '' && 'dev' || inputs.environment }} | |
on: | |
workflow_dispatch: | |
inputs: | |
environment: | |
description: Which environment is being deployed? | |
required: true | |
default: test | |
type: choice | |
options: | |
- dev | |
- test | |
- prod | |
push: | |
branches: | |
- main | |
paths-ignore: | |
- '**/README.md' | |
- '**/.gitignore' | |
- './docs/**' | |
permissions: | |
contents: read | |
id-token: write | |
env: | |
DEFAULT_ENV: dev | |
TF_VERSION: =1.7.0 | |
jobs: | |
env-vars: | |
name: Set Env Vars as Outputs | |
runs-on: ubuntu-latest | |
outputs: | |
AWS_ACCOUNT_ID: ${{ steps.set-outputs.outputs.aws_account_id }} | |
ENVIRONMENT: ${{ steps.set-outputs.outputs.environment }} | |
TF_VERSION: ${{ steps.set-outputs.outputs.tf_version }} | |
steps: | |
# this sets environment variable outputs consumed by downstream jobs | |
# this is needed because the 'env' context is not available to reusable workflows | |
- name: Set Output Values | |
id: set-outputs | |
run: | | |
# set environment output | |
if [ -n "${{ inputs.environment }}" ]; then | |
# will use environment input value when workflow_dispatch trigger is used | |
echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT | |
else | |
# this will default the environment for all other triggers | |
echo "environment=${DEFAULT_ENV}" >> $GITHUB_OUTPUT | |
fi | |
# set AWS Account ID output based on environment | |
if [ "${{ inputs.environment }}" == "test" ]; then | |
echo "aws_account_id=${{ vars.TEST_ACCOUNT_ID }}" >> $GITHUB_OUTPUT | |
elif [ "${{ inputs.environment }}" == "prod" ]; then | |
echo "aws_account_id=${{ vars.PROD_ACCOUNT_ID }}" >> $GITHUB_OUTPUT | |
else | |
echo "aws_account_id=${{ vars.DEV_ACCOUNT_ID }}" >> $GITHUB_OUTPUT | |
fi | |
# sets terraform version output | |
echo "tf_version=${TF_VERSION}" >> $GITHUB_OUTPUT | |
################################################################### | |
# These first few jobs must be run before the remaining TF stacks # | |
################################################################### | |
tf-plan-oidc: | |
name: Terraform Plan - OIDC | |
needs: | |
- env-vars | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_plan.yml@v1 | |
with: | |
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }} | |
aws_region: ${{ vars.AWS_REGION }} | |
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }} | |
role_name: GithubActionsRole-ReadOnly | |
stack_name: oidc | |
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }} | |
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} | |
tf_backend_key: ${{ github.event.repository.name }}/oidc.tfstate | |
tfvars_path: ./environments/${{ needs.env-vars.outputs.ENVIRONMENT }}.tfvars | |
working_directory: infra/tf/stacks/oidc | |
tf-apply-oidc: | |
name: Terraform Apply - OIDC | |
if: ${{ needs.tf-plan-oidc.outputs.CHANGES_DETECTED == 'true' }} | |
needs: | |
- env-vars | |
- tf-plan-oidc | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply.yml@v1 | |
with: | |
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }} | |
aws_region: ${{ vars.AWS_REGION }} | |
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }} | |
role_name: GithubActionsRole-Write | |
stack_name: oidc | |
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }} | |
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} | |
tf_backend_key: ${{ github.event.repository.name }}/oidc.tfstate | |
working_directory: infra/tf/stacks/oidc | |
tf-plan-prereqs: | |
name: Terraform Plan - Prerequisite Stacks | |
if: ${{ !cancelled() && needs.tf-apply-oidc.result != 'failure' }} | |
needs: | |
- env-vars | |
- tf-apply-oidc | |
# Using the matrix strategy here because the 'env' context is not available | |
# This gives us the ability to define the stack name once and use many times in the inputs, | |
# or define multiple stack names and have the job run against each stack. | |
strategy: | |
fail-fast: false | |
matrix: | |
STACK_NAME: | |
- storage | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_plan.yml@v1 | |
with: | |
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }} | |
aws_region: ${{ vars.AWS_REGION }} | |
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }} | |
role_name: GithubActionsRole-ReadOnly | |
stack_name: ${{ matrix.STACK_NAME }} | |
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }} | |
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} | |
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate | |
tfvars_path: ./environments/${{ needs.env-vars.outputs.ENVIRONMENT }}.tfvars | |
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }} | |
tf-apply-prereqs-matrix: | |
name: Set TF Apply Matrix - Prerequisite Stacks | |
if: ${{ !cancelled() && needs.tf-plan-prereqs.result == 'success' }} | |
needs: [ tf-plan-prereqs ] | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply_matrix.yml@v1 | |
with: | |
stacks_to_ignore: oidc | |
tf-apply-prereqs: | |
name: Terraform Apply - Prerequisite Stacks | |
if: ${{ !cancelled() && needs.tf-apply-prereqs-matrix.outputs.MATRIX != 'skip' }} | |
needs: | |
- env-vars | |
- tf-apply-prereqs-matrix | |
strategy: | |
# The matrix values are coming from the `tf-apply-prereqs-matrix` job. The matrix will only | |
# consist of those stacks from the TF Plan job that showed changes and produced artifacts. | |
fail-fast: false | |
matrix: ${{ fromJson(needs.tf-apply-prereqs-matrix.outputs.MATRIX) }} | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply.yml@v1 | |
with: | |
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }} | |
aws_region: ${{ vars.AWS_REGION }} | |
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }} | |
role_name: GithubActionsRole-Write | |
stack_name: ${{ matrix.STACK_NAME }} | |
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }} | |
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} | |
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate | |
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }} | |
build: | |
name: Build Lambda Package | |
strategy: | |
fail-fast: false | |
matrix: | |
LAMBDA_NAME: | |
- DownloadImage | |
- ReverseImage | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__build_python_lambda.yml@v1 | |
with: | |
aws_region: ${{ vars.AWS_REGION }} | |
lambda_name: ${{ matrix.LAMBDA_NAME }} | |
python_version: 3.11 | |
src_directory: src/lambdas/${{ matrix.LAMBDA_NAME }} | |
##################################################### | |
# These jobs must run after the preceding TF stacks # | |
##################################################### | |
deploy: | |
name: Deploy Lambda Package | |
if: | | |
${{ !cancelled() && needs.build.result == 'success' && | |
needs.tf-apply-prereqs.result != 'failure' }} | |
needs: | |
- env-vars | |
- build | |
- tf-apply-prereqs | |
strategy: | |
fail-fast: false | |
matrix: | |
LAMBDA_NAME: | |
- DownloadImage | |
- ReverseImage | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__upload_s3_object.yml@v1 | |
with: | |
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }} | |
aws_region: ${{ vars.AWS_REGION }} | |
bucket_name: ${{ vars.LAMBDA_PKG_BUCKET_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} | |
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }} | |
object_key: ${{ matrix.LAMBDA_NAME }}_${{ needs.env-vars.outputs.ENVIRONMENT }}.zip | |
object_name: ${{ matrix.LAMBDA_NAME }}.zip | |
role_name: GithubActionsRole-Write | |
tf-plan: | |
name: Terraform Plan - Dependent Stacks | |
if: | | |
${{ !cancelled() && needs.deploy.result == 'success' && | |
needs.tf-apply-prereqs.result != 'failure' }} | |
needs: | |
- env-vars | |
- deploy | |
- tf-apply-prereqs | |
strategy: | |
fail-fast: false | |
matrix: | |
STACK_NAME: | |
- api | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_plan.yml@v1 | |
with: | |
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }} | |
aws_region: ${{ vars.AWS_REGION }} | |
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }} | |
role_name: GithubActionsRole-ReadOnly | |
stack_name: ${{ matrix.STACK_NAME }} | |
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }} | |
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} | |
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate | |
tfvars_path: ./environments/${{ needs.env-vars.outputs.ENVIRONMENT }}.tfvars | |
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }} | |
tf-apply-matrix: | |
name: Set TF Apply Matrix - Dependent Stacks | |
if: ${{ !cancelled() && needs.tf-plan.result == 'success' }} | |
needs: [ tf-plan ] | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply_matrix.yml@v1 | |
with: | |
stacks_to_ignore: oidc,storage | |
tf-apply: | |
name: Terraform Apply - Dependent Stacks | |
if: ${{ !cancelled() && needs.tf-apply-matrix.outputs.MATRIX != 'skip' }} | |
needs: | |
- env-vars | |
- tf-apply-matrix | |
strategy: | |
# The matrix values are coming from the `tf-apply-matrix` job. The matrix will only consist | |
# of those stacks from the TF Plan job that showed changes and produced artifacts. | |
fail-fast: false | |
matrix: ${{ fromJson(needs.tf-apply-matrix.outputs.MATRIX) }} | |
uses: chrisba11/terraform-feature-stacks/.github/workflows/__tf_apply.yml@v1 | |
with: | |
aws_account_id: ${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }} | |
aws_region: ${{ vars.AWS_REGION }} | |
environment: ${{ needs.env-vars.outputs.ENVIRONMENT }} | |
role_name: GithubActionsRole-Write | |
stack_name: ${{ matrix.STACK_NAME }} | |
terraform_version: ${{ needs.env-vars.outputs.TF_VERSION }} | |
tf_backend_name: ${{ vars.TF_BACKEND_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} | |
tf_backend_key: ${{ github.event.repository.name }}/${{ matrix.STACK_NAME }}.tfstate | |
working_directory: infra/tf/stacks/${{ matrix.STACK_NAME }} | |
update: | |
name: Update Lambda | |
if: | | |
${{ !cancelled() && needs.deploy.result == 'success' && | |
needs.tf-apply.result != 'failure' }} | |
runs-on: ubuntu-latest | |
needs: | |
- env-vars | |
- deploy | |
- tf-apply | |
strategy: | |
fail-fast: false | |
matrix: | |
LAMBDA_NAME: | |
- DownloadImage | |
- ReverseImage | |
steps: | |
- name: Configure AWS Credentials | |
uses: aws-actions/configure-aws-credentials@v4 | |
with: | |
role-to-assume: arn:aws:iam::${{ needs.env-vars.outputs.AWS_ACCOUNT_ID }}:role/GithubActionsRole-Write | |
aws-region: ${{ vars.AWS_REGION }} | |
role-duration-seconds: 900 | |
role-session-name: ${{ github.event.repository.name }}+run=${{ github.run_id }}-${{ github.run_number }}+${{ github.triggering_actor }} | |
- name: Update Lambda Function Code | |
run: | | |
# triggers lambda function to use new updated zip archive | |
aws lambda update-function-code \ | |
--function-name ${{ matrix.LAMBDA_NAME }}_${{ needs.env-vars.outputs.ENVIRONMENT }} \ | |
--s3-bucket ${{ vars.LAMBDA_PKG_BUCKET_PREFIX }}-${{ needs.env-vars.outputs.ENVIRONMENT }} \ | |
--s3-key ${{ matrix.LAMBDA_NAME }}_${{ needs.env-vars.outputs.ENVIRONMENT }}.zip |