From d8f1ceb8e916c6d428fdfc91efdeb25d38bb4343 Mon Sep 17 00:00:00 2001 From: Rohith Jayawardene Date: Sat, 28 Sep 2024 10:21:32 +0100 Subject: [PATCH 01/14] feat: adding the ability to detect drift and send slack notifications --- .github/workflows/terraform-drift.yml | 141 ++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 .github/workflows/terraform-drift.yml diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml new file mode 100644 index 0000000..0b77c89 --- /dev/null +++ b/.github/workflows/terraform-drift.yml @@ -0,0 +1,141 @@ +--- +name: Terraform Drift Detection + +on: + # Trigger the workflow on a weekly random day at 9:00 AM + schedule: + - cron: "0 9 * * *" + workflow_dispatch: + inputs: + aws-account-id: + description: "The AWS account ID to deploy to" + required: true + type: string + + aws-role: + default: "${{ github.event.repository.name }}" + description: "The AWS role to assume" + required: false + type: string + + aws-read-role-name: + description: "Overrides the default behavior, and uses a custom role name for read-only access" + required: false + type: string + + aws-write-role-name: + description: "Overrides the default behavior, and uses a custom role name for read-write access" + required: false + type: string + + aws-region: + default: "eu-west-2" + description: "The AWS region to deploy to" + required: false + type: string + +jobs: + terraform-plan: + name: "Terraform Plan" + runs-on: ${{ inputs.runs-on }} + defaults: + run: + working-directory: ${{ inputs.working-directory }} + outputs: + result-auth: ${{ steps.auth.outcome }} + result-init: ${{ steps.init.outcome }} + result-plan: ${{ steps.plan.outcome }} + plan-stdout: ${{ steps.plan.outputs.stdout }} + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 16 + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ inputs.terraform-version }} + - name: Retrieve Web Identity Token for AWS Authentication + run: | + curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com" | jq -r '.value' > $AWS_WEB_IDENTITY_TOKEN_FILE + - name: Determine AWS Role + id: role + run: | + if [ "${{ inputs.use-env-as-suffix }}" == "true" ]; then + role_suffix="-${{ inputs.environment }}" + else + role_suffix="" + fi + if [[ "${GITHUB_REF##*/}" == "main" ]]; then + echo "name=${AWS_READWRITE_OVERRIDE_ROLE:-${AWS_ROLE}${role_suffix}}" >> $GITHUB_OUTPUT + else + echo "name=${AWS_READONLY_OVERRIDE_ROLE:-${AWS_ROLE}${role_suffix}-ro}" >> $GITHUB_OUTPUT + fi + - name: Authenticate with AWS + id: auth + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: ${{ inputs.aws-region }} + role-session-name: ${{ github.event.repository.name }} + role-to-assume: arn:aws:iam::${{ inputs.aws-account-id }}:role/${{ steps.role.outputs.name }} + mask-aws-account-id: "no" + - name: Set terraform-state-key variable + id: state-key + run: | + if [ -n "${{ inputs.terraform-state-key }}" ]; then + echo "name=${{ inputs.terraform-state-key }}" >> $GITHUB_OUTPUT + else + if [ "${{ inputs.use-env-as-suffix }}" == "true" ]; then + echo "name=${{ github.event.repository.name }}-${{ inputs.environment }}.tfstate" >> $GITHUB_OUTPUT + else + echo "name=${{ github.event.repository.name }}.tfstate" >> $GITHUB_OUTPUT + fi + fi + - name: Terraform Init + id: init + run: terraform -chdir=${{ inputs.terraform-dir }} init -backend-config="bucket=${{ inputs.aws-account-id }}-${{ inputs.aws-region }}-tfstate" -backend-config="key=${{ steps.state-key.outputs.name }}" -backend-config="encrypt=true" -backend-config="dynamodb_table=${{ inputs.aws-account-id }}-${{ inputs.aws-region }}-tflock" -backend-config="region=${{ inputs.aws-region }}" + - name: Terraform Validate + id: validate + run: terraform -chdir=${{ inputs.terraform-dir }} validate -no-color + - name: Terraform S3 Backend Check + id: s3-backend-check + run: | + if grep -E '^[^#]*backend\s+"s3"' terraform.tf; then + echo "Terraform configuration references an S3 backend." + else + echo "Terraform configuration does not reference an S3 backend." + exit 1 + fi + - name: Set terraform-values-file variable + run: | + if [ -n "${{ inputs.terraform-values-file }}" ]; then + echo "TF_VAR_FILE=${{ inputs.terraform-values-file }}" >> $GITHUB_ENV + else + echo "TF_VAR_FILE=values/${{ inputs.environment }}.tfvars" >> $GITHUB_ENV + fi + - name: Check for drift and set status + id: check-drift + run: | + if grep -q 'No changes' <(terraform -chdir=${{ inputs.terraform-dir }} plan -var-file=$TF_VAR_FILE -no-color -input=false -out=tfplan -lock-timeout=${{ inputs.terraform-lock-timeout }}); then + echo "No drift detected." + echo "::set-output name=DRIFT_STATUS::no-drift" + else + echo "Drift detected!" + echo "::set-output name=DRIFT_STATUS::drift" + exit 1 # Fail if drift is detected + fi + - name: Send Slack notification if drift is detected + if: steps.check-drift.outputs.DRIFT_STATUS == 'drift' + uses: slackapi/slack-github-action@v1.24.0 + with: + payload: | + { + "channel": "#${{ secrets.SLACK_CHANNEL }}", + "username": "GitHub Actions", + "text": "🚨 Drift Detected (${{ github.repository }})", + "icon_emoji": ":warning:" + } + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} From acd47eceb605e8ebb4302609754d8f086e06a9f7 Mon Sep 17 00:00:00 2001 From: Rohith Jayawardene Date: Fri, 4 Oct 2024 10:43:35 +0100 Subject: [PATCH 02/14] docs: adding the documentation and the updates --- .github/workflows/terraform-drift.yml | 12 ++++--- docs/terraform-drift.md | 50 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 docs/terraform-drift.md diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 0b77c89..032c24d 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -2,10 +2,12 @@ name: Terraform Drift Detection on: - # Trigger the workflow on a weekly random day at 9:00 AM - schedule: - - cron: "0 9 * * *" workflow_dispatch: + secrets: + slack-webhook-url: + description: "The Slack webhook URL" + required: false + inputs: aws-account-id: description: "The AWS account ID to deploy to" @@ -78,9 +80,9 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: aws-region: ${{ inputs.aws-region }} + mask-aws-account-id: "no" role-session-name: ${{ github.event.repository.name }} role-to-assume: arn:aws:iam::${{ inputs.aws-account-id }}:role/${{ steps.role.outputs.name }} - mask-aws-account-id: "no" - name: Set terraform-state-key variable id: state-key run: | @@ -138,4 +140,4 @@ jobs: "icon_emoji": ":warning:" } env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_WEBHOOK_URL: ${{ secrets.slack-webhook-url }} diff --git a/docs/terraform-drift.md b/docs/terraform-drift.md new file mode 100644 index 0000000..4c59d55 --- /dev/null +++ b/docs/terraform-drift.md @@ -0,0 +1,50 @@ +# Terraform Draft Workflow for AWS Infrastructure + +This workflow is used to run an scheduled or manually triggered drift detection on AWS infrastructure. In order to trigger the workflow, firstly the workflow must be referenced from the calling workflow flow, see below. + +## Usage + +Create a new workflow file in your Terraform repository (e.g. `.github/workflows/terraform.yml`) with the below contents: + +```yml +name: Terraform +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + terraform: + uses: appvia/appvia-cicd-workflows/.github/workflows/terraform-plan-and-apply-aws.yml@main + name: Plan and Apply + with: + aws-account: + aws-role: +``` + +And we can create another workflow file in your Terraform repository (e.g. `.github/workflows/terraform-drift.yml`) with the below contents: + +```yml +name: Terraform +on: + workflow_dispatch: + scheduled: + - cron: "0 0 * * *" + +jobs: + terraform-drift: + uses: appvia/appvia-cicd-workflows/.github/workflows/terraform-drift.yml@main + name: Drift Detection + with: + aws-account: + aws-role: +``` + +- `aws-account` is the AWS account number where the infrastructure is deployed. +- `aws-role` inputs are optional and will default to the repository name. + +**Note:** This template may change over time, so it is recommended that you point to a tagged version rather than the main branch. From 0dedd6b52b3f851ce614b97fbdb7146bfede54ed Mon Sep 17 00:00:00 2001 From: Rohith Jayawardene Date: Thu, 10 Oct 2024 18:04:32 +0100 Subject: [PATCH 03/14] chore: increasing the compression level on the upload --- .github/workflows/terraform-plan-and-apply-aws.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/terraform-plan-and-apply-aws.yml b/.github/workflows/terraform-plan-and-apply-aws.yml index 19b2416..86247f8 100644 --- a/.github/workflows/terraform-plan-and-apply-aws.yml +++ b/.github/workflows/terraform-plan-and-apply-aws.yml @@ -346,6 +346,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: tfplan-${{ inputs.environment }} + compression-level: 9 path: "tfplan*" retention-days: 14 - name: Optional Additional Directory Upload @@ -357,9 +358,10 @@ jobs: if: inputs.additional-dir uses: actions/upload-artifact@v4 with: + name: additional-dir-${{ inputs.environment }} + compression-level: 9 if-no-files-found: error include-hidden-files: true - name: additional-dir-${{ inputs.environment }} path: ${{ inputs.additional-dir }} retention-days: 14 From 1dd8da02eca10bfe8e2ff6394a88245c19a43a95 Mon Sep 17 00:00:00 2001 From: Rohith Jayawardene Date: Thu, 10 Oct 2024 18:17:41 +0100 Subject: [PATCH 04/14] chore: hacking around while we workout a fix --- .github/workflows/terraform-plan-and-apply-aws.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/terraform-plan-and-apply-aws.yml b/.github/workflows/terraform-plan-and-apply-aws.yml index 86247f8..ac8ac0e 100644 --- a/.github/workflows/terraform-plan-and-apply-aws.yml +++ b/.github/workflows/terraform-plan-and-apply-aws.yml @@ -264,7 +264,8 @@ jobs: result-validate: ${{ steps.validate.outcome }} result-s3-backend-check: ${{ steps.s3-backend-check.outcome }} result-plan: ${{ steps.plan.outcome }} - plan-stdout: ${{ steps.plan.outputs.stdout }} + #plan-stdout: ${{ steps.plan.outputs.stdout }} + plan-stdout: "" steps: - name: Checkout Repository uses: actions/checkout@v4 From bd029c54688e4aca340f4ada8180c6a753752780 Mon Sep 17 00:00:00 2001 From: Rohith Jayawardene Date: Thu, 10 Oct 2024 18:21:27 +0100 Subject: [PATCH 05/14] Revert "chore: hacking around while we workout a fix" This reverts commit 1dd8da02eca10bfe8e2ff6394a88245c19a43a95. --- .github/workflows/terraform-plan-and-apply-aws.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/terraform-plan-and-apply-aws.yml b/.github/workflows/terraform-plan-and-apply-aws.yml index ac8ac0e..86247f8 100644 --- a/.github/workflows/terraform-plan-and-apply-aws.yml +++ b/.github/workflows/terraform-plan-and-apply-aws.yml @@ -264,8 +264,7 @@ jobs: result-validate: ${{ steps.validate.outcome }} result-s3-backend-check: ${{ steps.s3-backend-check.outcome }} result-plan: ${{ steps.plan.outcome }} - #plan-stdout: ${{ steps.plan.outputs.stdout }} - plan-stdout: "" + plan-stdout: ${{ steps.plan.outputs.stdout }} steps: - name: Checkout Repository uses: actions/checkout@v4 From f8a4a361e9b06f05fe7fb3cc26ba86ccec4790f0 Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Tue, 24 Dec 2024 15:45:37 +0000 Subject: [PATCH 06/14] feat: initial commit --- .github/workflows/terraform-drift.yml | 13 +++++++++---- .gitignore | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 032c24d..5a3fe2a 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -2,13 +2,19 @@ name: Terraform Drift Detection on: - workflow_dispatch: + workflow_call: secrets: slack-webhook-url: description: "The Slack webhook URL" required: false inputs: + runs-on: + default: "ubuntu-latest" + description: "Single label value for the GitHub runner to use (custom value only applies to Terraform Plan and Apply steps)" + required: false + type: string + aws-account-id: description: "The AWS account ID to deploy to" required: true @@ -130,8 +136,9 @@ jobs: fi - name: Send Slack notification if drift is detected if: steps.check-drift.outputs.DRIFT_STATUS == 'drift' - uses: slackapi/slack-github-action@v1.24.0 + uses: slackapi/slack-github-action@v2.0.0 with: + webhook: ${{ secrets.SLACK_WEBHOOK_URL }} payload: | { "channel": "#${{ secrets.SLACK_CHANNEL }}", @@ -139,5 +146,3 @@ jobs: "text": "🚨 Drift Detected (${{ github.repository }})", "icon_emoji": ":warning:" } - env: - SLACK_WEBHOOK_URL: ${{ secrets.slack-webhook-url }} diff --git a/.gitignore b/.gitignore index 7072af3..513d30b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ **/._.DS_Store *.orig + +.idea \ No newline at end of file From 1f156ea258e238d6c9414a71f29db443db4a7207 Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Mon, 30 Dec 2024 14:11:41 +0000 Subject: [PATCH 07/14] feat: yaml linting --- .github/workflows/terraform-drift.yml | 58 +++++++++++++++++++++------ 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 5a3fe2a..fcc9a07 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -9,36 +9,68 @@ on: required: false inputs: + aws-account-id: + description: "The AWS account ID to deploy to" + required: true + type: string + + aws-region: + default: "eu-west-2" + description: "The AWS region to deploy to" + required: false + type: string + + environment: + default: "production" + description: "The environment to deploy to" + required: false + type: string + + use-env-as-suffix: + default: false + description: "Whether to use the environment as a suffix for the state file and iam roles" + required: false + type: boolean + runs-on: default: "ubuntu-latest" description: "Single label value for the GitHub runner to use (custom value only applies to Terraform Plan and Apply steps)" required: false type: string - aws-account-id: - description: "The AWS account ID to deploy to" - required: true + terraform-dir: + default: "." + description: "The directory to validate" + required: false type: string - aws-role: - default: "${{ github.event.repository.name }}" - description: "The AWS role to assume" + terraform-lock-timeout: + default: "30s" + description: The time to wait for a lock required: false type: string - aws-read-role-name: - description: "Overrides the default behavior, and uses a custom role name for read-only access" + terraform-state-key: + default: "" + description: "The key of the terraform state (default: .tfstate)" required: false type: string - aws-write-role-name: - description: "Overrides the default behavior, and uses a custom role name for read-write access" + terraform-values-file: + default: "" + description: "The values file to use (default: .tfvars)" required: false type: string - aws-region: - default: "eu-west-2" - description: "The AWS region to deploy to" + terraform-version: + default: "1.7.1" + description: "The version of terraform to use" + required: false + type: string + + working-directory: + default: "." + description: "The working directory to run terraform commands in" required: false type: string From 486ba7c26b4d543af5986f39119faa9eb5172c93 Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Mon, 30 Dec 2024 14:13:23 +0000 Subject: [PATCH 08/14] feat: yaml linting --- .github/workflows/terraform-drift.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index fcc9a07..29ffb06 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -84,8 +84,8 @@ jobs: outputs: result-auth: ${{ steps.auth.outcome }} result-init: ${{ steps.init.outcome }} - result-plan: ${{ steps.plan.outcome }} - plan-stdout: ${{ steps.plan.outputs.stdout }} + result-validate: ${{ steps.validate.outcome }} + result-s3-backend-check: ${{ steps.s3-backend-check.outcome }} steps: - name: Checkout Repository uses: actions/checkout@v4 @@ -118,9 +118,9 @@ jobs: uses: aws-actions/configure-aws-credentials@v4 with: aws-region: ${{ inputs.aws-region }} - mask-aws-account-id: "no" role-session-name: ${{ github.event.repository.name }} role-to-assume: arn:aws:iam::${{ inputs.aws-account-id }}:role/${{ steps.role.outputs.name }} + mask-aws-account-id: "no" - name: Set terraform-state-key variable id: state-key run: | @@ -158,22 +158,21 @@ jobs: - name: Check for drift and set status id: check-drift run: | - if grep -q 'No changes' <(terraform -chdir=${{ inputs.terraform-dir }} plan -var-file=$TF_VAR_FILE -no-color -input=false -out=tfplan -lock-timeout=${{ inputs.terraform-lock-timeout }}); then + if grep -q 'No changes' <(terraform -chdir=${{ inputs.terraform-dir }} plan -var-file=$TF_VAR_FILE -no-color -input=false -out=tfplan -lock-timeout=${{ inputs.terraform-lock-timeout }}); then echo "No drift detected." - echo "::set-output name=DRIFT_STATUS::no-drift" + echo "DRIFT_STATUS=no-drift" >> "$GITHUB_OUTPUT" else echo "Drift detected!" - echo "::set-output name=DRIFT_STATUS::drift" + echo "DRIFT_STATUS=drift" >> "$GITHUB_OUTPUT" exit 1 # Fail if drift is detected fi - name: Send Slack notification if drift is detected if: steps.check-drift.outputs.DRIFT_STATUS == 'drift' uses: slackapi/slack-github-action@v2.0.0 with: - webhook: ${{ secrets.SLACK_WEBHOOK_URL }} + webhook: ${{ secrets.slack-webhook-url }} payload: | { - "channel": "#${{ secrets.SLACK_CHANNEL }}", "username": "GitHub Actions", "text": "🚨 Drift Detected (${{ github.repository }})", "icon_emoji": ":warning:" From be02bc0767441e2648b46aba8294d33ab01ba67f Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Mon, 30 Dec 2024 14:55:08 +0000 Subject: [PATCH 09/14] feat: update workflow envs --- .github/workflows/terraform-drift.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 29ffb06..4a3c882 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -20,6 +20,22 @@ on: required: false type: string + aws-role: + default: "${{ github.event.repository.name }}" + description: "The AWS role to assume" + required: false + type: string + + aws-read-role-name: + description: "Overrides the default behavior, and uses a custom role name for read-only access" + required: false + type: string + + aws-write-role-name: + description: "Overrides the default behavior, and uses a custom role name for read-write access" + required: false + type: string + environment: default: "production" description: "The environment to deploy to" @@ -74,6 +90,17 @@ on: required: false type: string +env: + AWS_ROLE: ${{ inputs.aws-role }} + AWS_READONLY_OVERRIDE_ROLE: ${{ inputs.aws-read-role-name }} + AWS_READWRITE_OVERRIDE_ROLE: ${{ inputs.aws-write-role-name }} + AWS_WEB_IDENTITY_TOKEN_FILE: /tmp/web_identity_token_file + +permissions: + id-token: write + contents: read + pull-requests: write + jobs: terraform-plan: name: "Terraform Plan" From d579c014e1b6d9e528965a21dba2c51c33611a4b Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Mon, 30 Dec 2024 14:59:01 +0000 Subject: [PATCH 10/14] feat: update workflow permissions --- .github/workflows/terraform-drift.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 4a3c882..1af99e7 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -99,7 +99,6 @@ env: permissions: id-token: write contents: read - pull-requests: write jobs: terraform-plan: From 398a52656b6b2b7646ca2b1718779570e1b45653 Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Mon, 30 Dec 2024 15:10:49 +0000 Subject: [PATCH 11/14] feat: conitnue on failure during drift detection --- .github/workflows/terraform-drift.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 1af99e7..6fe34b2 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -192,6 +192,7 @@ jobs: echo "DRIFT_STATUS=drift" >> "$GITHUB_OUTPUT" exit 1 # Fail if drift is detected fi + continue-on-error: true - name: Send Slack notification if drift is detected if: steps.check-drift.outputs.DRIFT_STATUS == 'drift' uses: slackapi/slack-github-action@v2.0.0 From 4b56a03d057d6864c094707633cb684a4ed005b0 Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Mon, 30 Dec 2024 15:19:25 +0000 Subject: [PATCH 12/14] feat: add webhook type --- .github/workflows/terraform-drift.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 6fe34b2..9c20a84 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -198,6 +198,7 @@ jobs: uses: slackapi/slack-github-action@v2.0.0 with: webhook: ${{ secrets.slack-webhook-url }} + webhook-type: incoming-webhook payload: | { "username": "GitHub Actions", From 3e075440a3268a14ef0667b434f48e23c608d163 Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Mon, 30 Dec 2024 15:47:05 +0000 Subject: [PATCH 13/14] feat: tidy up --- .github/workflows/terraform-drift.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/terraform-drift.yml b/.github/workflows/terraform-drift.yml index 9c20a84..bd6bd4d 100644 --- a/.github/workflows/terraform-drift.yml +++ b/.github/workflows/terraform-drift.yml @@ -190,9 +190,7 @@ jobs: else echo "Drift detected!" echo "DRIFT_STATUS=drift" >> "$GITHUB_OUTPUT" - exit 1 # Fail if drift is detected fi - continue-on-error: true - name: Send Slack notification if drift is detected if: steps.check-drift.outputs.DRIFT_STATUS == 'drift' uses: slackapi/slack-github-action@v2.0.0 From 7f9075b3f2b46fcb7d5bf8d87ca4ec835597f7de Mon Sep 17 00:00:00 2001 From: Priyesh Mistry Date: Thu, 2 Jan 2025 14:09:57 +0000 Subject: [PATCH 14/14] feat: update readme --- docs/terraform-drift.md | 71 ++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/docs/terraform-drift.md b/docs/terraform-drift.md index 4c59d55..40c820f 100644 --- a/docs/terraform-drift.md +++ b/docs/terraform-drift.md @@ -1,50 +1,61 @@ # Terraform Draft Workflow for AWS Infrastructure -This workflow is used to run an scheduled or manually triggered drift detection on AWS infrastructure. In order to trigger the workflow, firstly the workflow must be referenced from the calling workflow flow, see below. +This workflow is used to run an scheduled or manually triggered drift detection on AWS infrastructure and alert in Slack if a change is detected, using GitHub Actions workflow template ([terraform-drift.yml](../.github/workflows/terraform-drift.yml)) +In order to trigger the workflow, firstly the workflow must be referenced from the calling workflow flow, see below. -## Usage - -Create a new workflow file in your Terraform repository (e.g. `.github/workflows/terraform.yml`) with the below contents: +## Workflow Steps -```yml -name: Terraform -on: - push: - branches: - - main - pull_request: - branches: - - main - workflow_dispatch: +1. **Setup Terraform:** Terraform is fetched at the specified version (overridable via inputs). +2. **AWS Authentication:** The workflow uses Web Identity Federation to authenticate with AWS. The required AWS Role ARN must be provided as an input for successful authentication. + - A Web Identity Token File is also generated and stored in `/tmp/web_identity_token_file`, which can be referenced in Terraform Provider configuration blocks if required. +3. **Terraform Init:** The Terraform backend is initialised and any necessary provider plugins are downloaded. The required inputs for AWS S3 bucket name and DynamoDB table name must be provided for storing the Terraform state. +4. **Terraform Plan:** A Terraform plan is generated with a specified values file (overridable via inputs) using the terraform plan command. +5. **Change Detection Status:** Plan is checked for any changes and status is set as to drift status, "No drift detected." or "Drift detected!" +6. **Alerting:** If drift is detected from the Terraform Plan, an alert is sent to a configured Slack Channel alerting users. Otherwise where there is no change, this step is skipped. -jobs: - terraform: - uses: appvia/appvia-cicd-workflows/.github/workflows/terraform-plan-and-apply-aws.yml@main - name: Plan and Apply - with: - aws-account: - aws-role: -``` +## Usage -And we can create another workflow file in your Terraform repository (e.g. `.github/workflows/terraform-drift.yml`) with the below contents: +Create a workflow file in your Terraform repository (e.g. `.github/workflows/terraform-drift.yml`) with the below contents: ```yml -name: Terraform +--- +name: Terraform Drift on: workflow_dispatch: - scheduled: - - cron: "0 0 * * *" + schedule: + - cron: "56 10 * * *" + +permissions: + contents: read + id-token: write jobs: terraform-drift: uses: appvia/appvia-cicd-workflows/.github/workflows/terraform-drift.yml@main name: Drift Detection + secrets: + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} with: - aws-account: - aws-role: + aws-account-id: ``` -- `aws-account` is the AWS account number where the infrastructure is deployed. -- `aws-role` inputs are optional and will default to the repository name. +REQUIRED INPUTS: +- `slack-webhook-url` - Slack Webhook to a channel/app, stored as a secret in your Github Actions Secrets +- `aws-account-id` - AWS account number where the infrastructure is deployed, and consequently planned against + +OPTIONAL INPUTS: +- `aws-region` - Default: "eu-west-2" +- `aws-role` - Default: Repository Name +- `aws-read-role-name` - Extra role for read only access +- `aws-write-role-name` - Extra role for read-write access +- `environment` - Default: "production" +- `use-env-as-suffix` - Default: false, Whether to use the environment as a suffix for the state file and iam roles +- `runs-on` - Default: "ubuntu-latest" +- `terraform-dir` - Default: ".", +- `terraform-lock-timeout` - Default: "30s" +- `terraform-state-key` - Default: .tfstate +- `terraform-values-file` - Default: .tfvars +- `terraform-version` - Default: "1.7.1" +- `working-directory` - Default: "." **Note:** This template may change over time, so it is recommended that you point to a tagged version rather than the main branch.