Skip to content

Merge pull request #119 from kunduso/central-ecr #246

Merge pull request #119 from kunduso/central-ecr

Merge pull request #119 from kunduso/central-ecr #246

Workflow file for this run

name: docker-build-deploy
on:
workflow_dispatch:
push:
branches: [ '*' ]
paths:
- 'app/**'
- '!app/tf/**'
- 'deploy/**'
- '.github/workflows/app-ci-cd.yml'
pull_request:
branches: ["main"]
paths:
- 'app/**'
- '!app/tf/**'
- 'deploy/**'
- '.github/workflows/app-ci-cd.yml'
env:
AWS_REGION: us-east-2 # set this to your preferred AWS region, e.g. us-west-1
ECR_REPOSITORY: app-6
permissions: read-all
jobs:
build:
name: 'continuous-integration'
runs-on: ubuntu-latest
environment: development
permissions:
contents: read
id-token: write
pull-requests: write
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
# Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
defaults:
run:
shell: bash
working-directory: ./app
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout
uses: actions/checkout@v3
- name: Generate Image Tag
id: tag
run: echo "TAG_NAME=$(date +'%Y%m%d').${{ github.run_number }}.${{ github.run_attempt }}" >> $GITHUB_ENV
- name: Print Image Tag
run: echo "Tag Name for the Image ${{ env.TAG_NAME }}"
# https://github.com/marketplace/actions/configure-aws-credentials-action-for-github-actions
- name: Configure AWS Credentials Action For GitHub Actions
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.CENTRAL_ACCOUNT_IAM_ROLE }}
role-session-name: AWSSession
aws-region: ${{ env.AWS_REGION }}
# https://github.com/marketplace/actions/amazon-ecr-login-action-for-github-actions
- name: Login to Amazon ECR Private
id: login-ecr
uses: aws-actions/[email protected]
with:
mask-password: 'true'
- name: Build and tag docker image to Amazon ECR
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: ${{ env.ECR_REPOSITORY }}
IMAGE_TAG: ${{ env.TAG_NAME }}
run: docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG .
# https://github.com/marketplace/actions/aqua-security-trivy
- name: Run Trivy vulnerability scanner
uses: aquasecurity/[email protected]
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: ${{ env.ECR_REPOSITORY }}
IMAGE_TAG: ${{ env.TAG_NAME }}
with:
image-ref: '${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ env.TAG_NAME }}'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
# Push the Docker image to Amazon ECR, but only if the even is not a pull request.
- name: Push docker image to Amazon ECR
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: ${{ env.ECR_REPOSITORY }}
IMAGE_TAG: ${{ env.TAG_NAME }}
run: docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
if: github.event_name != 'pull_request'
- name: Create output file
id: create-output
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: ${{ env.ECR_REPOSITORY }}
IMAGE_TAG: ${{ env.TAG_NAME }}
run: echo "IMAGE_ID=$REGISTRY/$REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
outputs:
image-id: ${{ steps.create-output.outputs.IMAGE_ID }}
deploy:
needs: build
name: 'continuous-deployment'
runs-on: ubuntu-latest
environment: development
env:
IMAGE_ID: ${{ needs.build.outputs.image-id }}
permissions:
contents: read
id-token: write
pull-requests: write
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
# Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
defaults:
run:
shell: bash
working-directory: ./deploy
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout
uses: actions/checkout@v3
- name: Print Image Tag
run: echo "Tag Name for the Image ${{ env.IMAGE_ID }}"
- name: Configure AWS Credentials Action For GitHub Actions
uses: aws-actions/configure-aws-credentials@v1-node16
with:
role-to-assume: ${{ secrets.IAM_ROLE }}
role-session-name: AWSSession
aws-region: ${{ env.AWS_REGION }}
# Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
- name: Setup Infracost
uses: infracost/actions/setup@v2
# See https://github.com/infracost/actions/tree/master/setup for other inputs
# If you can't use this action, see Docker images in https://infracost.io/cicd
with:
api-key: ${{ secrets.INFRACOST_API_KEY }}
if: github.event_name == 'pull_request'
# Checkout the base branch of the pull request (e.g. main/master).
- name: Checkout base branch
if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }}
uses: actions/checkout@v3
with:
ref: '${{ github.event.pull_request.base.ref }}'
# Generate Infracost JSON file as the baseline.
- name: Generate Infracost cost estimate baseline
if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }}
run: |
infracost breakdown --path=. \
--format=json \
--out-file=/tmp/infracost-base.json
# Checkout the current PR branch so we can create a diff.
- name: Checkout PR branch
if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }}
uses: actions/checkout@v3
# Generate an Infracost diff and save it to a JSON file.
- name: Generate Infracost diff
if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'hcl_code') }}
run: |
infracost diff --path=. \
--format=json \
--compare-to=/tmp/infracost-base.json \
--out-file=/tmp/infracost.json
# Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc.
- name: Terraform Init
id: init
run: terraform init
# Checks that all Terraform configuration files adhere to a canonical format
- name: Terraform Format
id: fmt
run: terraform fmt -check
# Checks that all Terraform configuration files are correctly written
- name: Terraform Validate
id: validate
run: terraform validate -no-color
# Generates an execution plan for Terraform
- name: Terraform Plan
id: plan
if: github.ref != 'refs/heads/main' || github.event_name == 'pull_request'
run: |
terraform plan -no-color -input=false \
-var="image_tag=${{ env.IMAGE_ID }}" \
-out=TFplan.JSON
continue-on-error: true
# Generate an Infracost diff and save it to a JSON file.
- name: Generate Infracost diff
if: ${{ (github.event_name == 'pull_request') && (vars.INFRACOST_SCAN_TYPE == 'tf_plan') }}
run: |
infracost diff --path=TFplan.JSON \
--format=json \
--out-file=/tmp/infracost.json
- name: Post Infracost estimate
if: github.event_name == 'pull_request'
run: |
infracost comment github --path=/tmp/infracost.json \
--repo=$GITHUB_REPOSITORY \
--github-token=${{github.token}} \
--pull-request=${{github.event.pull_request.number}} \
--show-skipped \
--behavior=update
- name: Post Terraform Plan output
uses: actions/github-script@v6
if: github.event_name == 'pull_request'
env:
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
#### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
#### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
#### Terraform Validation 🤖\`${{ steps.validate.outcome }}\`
<details><summary>Show Plan</summary>
\`\`\`\n
${process.env.PLAN}
\`\`\`
</details>
*Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
# On push to "main", build or change infrastructure according to Terraform configuration files
# Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks
- name: Terraform Apply
if: github.ref == 'refs/heads/main'
run: |
terraform apply -auto-approve -input=false \
-var="image_tag=${{ env.IMAGE_ID }}"