Skip to content

Commit

Permalink
- Refactor build/publish infra GHA to simplify logic for building, sc…
Browse files Browse the repository at this point in the history
…anning and deploying infra resources

- Updated initial stack to be part of the main stack file to preserve single state file
- Added db subnet group for rds
- Updated openshift jobs to allow to target different environment
  • Loading branch information
Ronaldo Macapobre committed Dec 13, 2024
1 parent d6b888c commit 1cfa12f
Show file tree
Hide file tree
Showing 29 changed files with 908 additions and 267 deletions.
92 changes: 74 additions & 18 deletions .github/workflows/build-infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,79 @@ on:
- test
- prod

jobs:
build-initial:
uses: ./.github/workflows/aws-template-terraform.yml
with:
CONTEXT_FOLDER: "./infrastructure/cloud/environments/initial"
CHANGE_FOLDER_NAME: environments/${{ inputs.environment || 'dev' }}
ENVIRONMENT_NAME: ${{ inputs.environment || 'dev' }}
APPLY_TF_CODE: false
secrets: inherit
env:
WORKING_DIRECTORY: "./infrastructure/cloud/environments/${{ inputs.environment }}"

jobs:
build:
needs: [build-initial]
uses: ./.github/workflows/aws-template-terraform.yml
with:
CONTEXT_FOLDER: "./infrastructure/cloud/environments/${{ inputs.environment || 'dev' }}"
CHANGE_FOLDER_NAME: environments/${{ inputs.environment || 'dev' }}
ENVIRONMENT_NAME: ${{ inputs.environment || 'dev' }}
APPLY_TF_CODE: false
secrets: inherit

runs-on: ubuntu-latest
environment:
name: ${{ inputs.environment }}
env:
TF_VAR_app_name: ${{ vars.APP_NAME }}
TF_VAR_environment: ${{ vars.ENVIRONMENT_NAME }}
TF_VAR_kms_key_name: ${{ vars.KMS_KEY_NAME }}
TF_VAR_vpc_id: ${{ vars.VPC_ID }}
TF_VAR_lambda_memory_size: ${{ vars.LAMBDA_MEMORY_SIZE }}
permissions:
id-token: write
actions: read
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: tfsec
uses: aquasecurity/[email protected]
with:
sarif_file: tfsec.sarif
working_directory: ${{ env.WORKING_DIRECTORY }}
tfsec_args: "--tfvars-file=${{ env.WORKING_DIRECTORY }}/${{ inputs.environment }}.tfvars"

- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: tfsec.sarif

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-skip-session-tagging: true
aws-region: ${{ vars.AWS_REGION }}
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
role-duration-seconds: 1800
role-session-name: ci-deployment

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.9.0

- name: Terraform Init
id: init
run: |
terraform init -input=false -backend-config=backend.tfvars -var-file=${{ inputs.environment }}.tfvars
working-directory: ${{ env.WORKING_DIRECTORY }}

- name: Terraform Plan (Initial Stack)
id: plan-initial
run: |
terraform plan -target=module.initial -no-color -input=false -var-file=${{ inputs.environment }}.tfvars
continue-on-error: true
working-directory: ${{ env.WORKING_DIRECTORY }}

- name: Terraform Plan (Initial) Status
if: steps.plan-initial.outcome == 'failure'
run: exit 1

- name: Terraform Plan (Main Stack)
id: plan-main
run: |
terraform plan -no-color -input=false -var-file=${{ inputs.environment }}.tfvars
continue-on-error: true
working-directory: ${{ env.WORKING_DIRECTORY }}

- name: Terraform Plan (Main) Status
if: steps.plan-main.outcome == 'failure'
run: exit 1
27 changes: 13 additions & 14 deletions .github/workflows/publish-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,20 +118,19 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

# Uncomment when infra in AWS in TEST environment has been configured
# - name: Deploy to ${{ env.ENVIRONMENT }}
# uses: ./.github/workflows/actions/deploy-app
# with:
# environment: ${{ env.ENVIRONMENT }}
# aws_account: ${{ vars.AWS_ACCOUNT }}
# region: ${{ vars.AWS_REGION }}
# app_name: ${{ vars.APP_NAME }}
# aws_role_arn: ${{ vars.AWS_ROLE_ARN }}
# ghcr_token: ${{ secrets.GITHUB_TOKEN }}
# github_image_repo: ${{ env.GITHUB_IMAGE_REPO }}
# image_name: ${{ env.IMAGE_NAME }}
# tier_name: api
# short_sha: ${{ needs.build.outputs.short_sha }}
- name: Deploy to ${{ env.ENVIRONMENT }}
uses: ./.github/workflows/actions/deploy-app
with:
environment: ${{ env.ENVIRONMENT }}
aws_account: ${{ vars.AWS_ACCOUNT }}
region: ${{ vars.AWS_REGION }}
app_name: ${{ vars.APP_NAME }}
aws_role_arn: ${{ vars.AWS_ROLE_ARN }}
ghcr_token: ${{ secrets.GITHUB_TOKEN }}
github_image_repo: ${{ env.GITHUB_IMAGE_REPO }}
image_name: ${{ env.IMAGE_NAME }}
tier_name: api
short_sha: ${{ needs.build.outputs.short_sha }}

deploy2prod:
name: Deploy to PROD
Expand Down
168 changes: 120 additions & 48 deletions .github/workflows/publish-infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,83 @@ on:
- dev
- test
- prod
run_initial:
description: "Run initial Terraform setup?"
required: false
default: "No"
type: choice
options:
- "No"
- "Yes"

env:
WORKING_DIRECTORY: "./infrastructure/cloud/environments/${{ inputs.environment }}"
DUMMY_IMAGE_NAME: dummy-image
GITHUB_IMAGE_REPO: ghcr.io/bcgov/jasper
APP_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-app-repo-${{ inputs.environment }}
LAMBDA_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-lambda-repo-${{ inputs.environment }}

jobs:
initial:
if: ${{ inputs.run_initial == 'Yes' }}
uses: ./.github/workflows/aws-template-terraform.yml
with:
CONTEXT_FOLDER: "./infrastructure/cloud/environments/initial"
CHANGE_FOLDER_NAME: environments/${{ inputs.environment }}
ENVIRONMENT_NAME: ${{ inputs.environment || 'dev' }}
APPLY_TF_CODE: true
secrets: inherit

post-initial:
deploy:
runs-on: ubuntu-latest
needs: initial
if: ${{ inputs.run_initial == 'Yes' }}
environment: ${{ inputs.environment }}
environment:
name: ${{ inputs.environment }}
env:
TF_VAR_app_name: ${{ vars.APP_NAME }}
TF_VAR_environment: ${{ vars.ENVIRONMENT_NAME }}
TF_VAR_kms_key_name: ${{ vars.KMS_KEY_NAME }}
TF_VAR_vpc_id: ${{ vars.VPC_ID }}
TF_VAR_lambda_memory_size: ${{ vars.LAMBDA_MEMORY_SIZE }}
permissions:
id-token: write
actions: read
contents: read
security-events: write
packages: write
env:
DUMMY_IMAGE_NAME: dummy-image
GITHUB_IMAGE_REPO: ghcr.io/bcgov/jasper
APP_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-app-repo-${{ inputs.environment }}
LAMBDA_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-lambda-repo-${{ inputs.environment }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: tfsec
uses: aquasecurity/[email protected]
with:
sarif_file: tfsec.sarif
working_directory: ${{ env.WORKING_DIRECTORY }}
tfsec_args: "--tfvars-file=${{ env.WORKING_DIRECTORY }}/${{ inputs.environment }}.tfvars"

- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: tfsec.sarif

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-skip-session-tagging: true
aws-region: ${{ vars.AWS_REGION }}
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
role-duration-seconds: 1800
role-session-name: ci-deployment

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.9.0

- name: Terraform Init
id: init
run: |
terraform init -input=false -backend-config=backend.tfvars -var-file=${{ inputs.environment }}.tfvars
working-directory: ${{ env.WORKING_DIRECTORY }}

- name: Terraform Plan (Initial Stack)
id: plan-initial
run: |
terraform plan -target=module.initial -no-color -input=false -var-file=${{ inputs.environment }}.tfvars
continue-on-error: true
working-directory: ${{ env.WORKING_DIRECTORY }}

- name: Terraform Plan (Initial) Status
if: steps.plan-initial.outcome == 'failure'
run: exit 1

- name: Terraform Apply (Initial Stack)
run: |
terraform apply -target=module.initial --auto-approve -input=false -var-file=${{ inputs.environment }}.tfvars
working-directory: ${{ env.WORKING_DIRECTORY }}

- name: Log in to the GHCR
uses: docker/login-action@v3
with:
Expand All @@ -72,7 +112,7 @@ jobs:
${{ env.GITHUB_IMAGE_REPO }}/${{ env.DUMMY_IMAGE_NAME }}
tags: |
type=raw,value=latest
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
Expand All @@ -87,39 +127,71 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-skip-session-tagging: true
aws-region: ${{ vars.AWS_REGION }}
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
role-duration-seconds: 1800
role-session-name: ci-deployment

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

- name: Push dummy images to App ECR
- name: Check dummy-image in App ECR exists
id: app-ecr-check
shell: bash
run: |
IMAGE_TAG=${{ env.DUMMY_IMAGE_NAME }}
REPOSITORY_NAME=${{ vars.APP_NAME }}-app-repo-${{ inputs.environment }}
IMAGE_EXISTS=$(aws ecr describe-images --repository-name $REPOSITORY_NAME --query "imageDetails[?contains(imageTags, '$IMAGE_TAG')]" --output text)
if [ -z "$IMAGE_EXISTS" ]; then
echo "Image with tag $IMAGE_TAG does not exist."
echo "exists=false" >> $GITHUB_OUTPUT
else
echo "Image with tag $IMAGE_TAG already exists."
echo "exists=true" >> $GITHUB_OUTPUT
fi
- name: Push dummy image to App ECR
if: steps.app-ecr-check.outputs.exists == 'false'
shell: bash
run: |
echo 'Deploying ${{ env.DUMMY_IMAGE_NAME }} to App ECR'
docker tag ${{ env.GITHUB_IMAGE_REPO }}/${{ env.DUMMY_IMAGE_NAME }}:latest ${{ env.APP_ECR_REPO_URL }}:${{ env.DUMMY_IMAGE_NAME }}
docker push ${{ env.APP_ECR_REPO_URL }}:${{ env.DUMMY_IMAGE_NAME }}
- name: Check dummy-image in Lambda ECR exists
id: lambda-ecr-check
shell: bash
run: |
IMAGE_TAG=${{ env.DUMMY_IMAGE_NAME }}
REPOSITORY_NAME=${{ vars.APP_NAME }}-lambda-repo-${{ inputs.environment }}
IMAGE_EXISTS=$(aws ecr describe-images --repository-name $REPOSITORY_NAME --query "imageDetails[?contains(imageTags, '$IMAGE_TAG')]" --output text)
if [ -z "$IMAGE_EXISTS" ]; then
echo "Image with tag $IMAGE_TAG does not exist."
echo "exists=false" >> $GITHUB_OUTPUT
else
echo "Image with tag $IMAGE_TAG already exists."
echo "exists=true" >> $GITHUB_OUTPUT
fi
- name: Push dummy images to Lambda ECR
if: steps.lambda-ecr-check.outputs.exists == 'false'
shell: bash
run: |
echo 'Deploying ${{ env.env.DUMMY_IMAGE_NAME }} to Lambda ECR'
docker tag ${{ env.GITHUB_IMAGE_REPO }}/${{ env.DUMMY_IMAGE_NAME }}:latest ${{ env.LAMBDA_ECR_REPO_URL }}:${{ env.DUMMY_IMAGE_NAME }}
docker push ${{ env.LAMBDA_ECR_REPO_URL }}:${{ env.DUMMY_IMAGE_NAME }}
deploy:
needs: [initial, post-initial]
if: always()
uses: ./.github/workflows/aws-template-terraform.yml
with:
CONTEXT_FOLDER: "./infrastructure/cloud/environments/${{ inputs.environment || 'dev' }}"
CHANGE_FOLDER_NAME: environments/${{ inputs.environment || 'dev' }}
ENVIRONMENT_NAME: ${{ inputs.environment || 'dev' }}
APPLY_TF_CODE: true
secrets: inherit
- name: Terraform Plan (Main Stack)
id: plan-main
run: |
terraform plan -no-color -input=false -var-file=${{ inputs.environment }}.tfvars
continue-on-error: true
working-directory: ${{ env.WORKING_DIRECTORY }}

- name: Terraform Plan (Main) Status
if: steps.plan-main.outcome == 'failure'
run: exit 1

- name: Terraform Apply (Main Stack)
run: |
terraform apply --auto-approve -input=false -var-file=${{ inputs.environment }}.tfvars
working-directory: ${{ env.WORKING_DIRECTORY }}
29 changes: 14 additions & 15 deletions .github/workflows/publish-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,19 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

# Uncomment when infra in AWS in TEST environment has been configured
# - name: Deploy to ${{ env.ENVIRONMENT }}
# uses: ./.github/workflows/actions/deploy-app
# with:
# environment: ${{ env.ENVIRONMENT }}
# aws_account: ${{ vars.AWS_ACCOUNT }}
# region: ${{ vars.AWS_REGION }}
# app_name: ${{ vars.APP_NAME }}
# aws_role_arn: ${{ vars.AWS_ROLE_ARN }}
# ghcr_token: ${{ secrets.GITHUB_TOKEN }}
# github_image_repo: ${{ env.GITHUB_IMAGE_REPO }}
# image_name: ${{ env.WEB_IMAGE_NAME }}
# tier_name: web
# short_sha: ${{ needs.build.outputs.short_sha }}
- name: Deploy to ${{ env.ENVIRONMENT }}
uses: ./.github/workflows/actions/deploy-app
with:
environment: ${{ env.ENVIRONMENT }}
aws_account: ${{ vars.AWS_ACCOUNT }}
region: ${{ vars.AWS_REGION }}
app_name: ${{ vars.APP_NAME }}
aws_role_arn: ${{ vars.AWS_ROLE_ARN }}
ghcr_token: ${{ secrets.GITHUB_TOKEN }}
github_image_repo: ${{ env.GITHUB_IMAGE_REPO }}
image_name: ${{ env.WEB_IMAGE_NAME }}
tier_name: web
short_sha: ${{ needs.build.outputs.short_sha }}

deploy2prod:
name: Deploy to PROD
Expand Down Expand Up @@ -167,4 +166,4 @@ jobs:
# github_image_repo: ${{ env.GITHUB_IMAGE_REPO }}
# image_name: ${{ env.WEB_IMAGE_NAME }}
# tier_name: web
# short_sha: ${{ needs.build.outputs.short_sha }}
# short_sha: ${{ needs.build.outputs.short_sha }}
4 changes: 2 additions & 2 deletions docker/openshift/update-aws-creds.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ if [ $? -eq 0 ]; then
currentSecretAccessKey=$(echo "$param_value" | jq -r '.current.SecretAccessKey')

if [ "$AWS_ACCESS_KEY_ID" = "$pendingAccessKeyId" ] || [ "$AWS_SECRET_ACCESS_KEY" = "$pendingSecretAccessKey" ]; then
echo "Updating AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY..."
echo "Updating AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY for aws-secret-${ENVIRONMENT} secret..."

oc create secret generic aws-secret \
oc create secret generic aws-secret-${ENVIRONMENT} \
--from-literal=AWS_ACCESS_KEY_ID=$currentAccessKeyId \
--from-literal=AWS_SECRET_ACCESS_KEY=$currentSecretAccessKey \
--dry-run=client -o yaml | oc apply -f -
Expand Down
Loading

0 comments on commit 1cfa12f

Please sign in to comment.