Skip to content

Instantly share code, notes, and snippets.

@Andor
Last active February 28, 2023 15:03
Show Gist options
  • Save Andor/01b3c211e68a1892947acb09237582bf to your computer and use it in GitHub Desktop.
Save Andor/01b3c211e68a1892947acb09237582bf to your computer and use it in GitHub Desktop.
terraform .gitlab-ci.yml
---
variables:
terraform_image: terraform-vault-jq
default:
image:
name: $terraform_image
cache:
key: terraform
paths:
- .terraform
interruptible: true
stages:
- init
- check
- plan
- comment
- apply
terraform init:
stage: init
script:
- terraform version
- terraform init -input=false -upgrade=true
rules:
- when: always
terraform fmt:
stage: check
cache: {}
script:
- terraform fmt -recursive -diff -check
rules:
- when: on_success
terraform validate:
stage: check
script:
- terraform validate
needs:
- terraform init
rules:
- when: on_success
terraform build plan:
stage: plan
before_script:
- vault write -field=token auth/approle/login role_id="$VAULT_APPROLE_ID" secret_id="$VAULT_APPROLE_SECRET_ID" > ~/.vault-token
script:
# build the plan
- terraform plan -lock-timeout=120s -input=false -out=plan.zip
# plan's text representation
- terraform show -no-color plan.zip > plan.txt
# count resources planned to change
- terraform show -json plan.zip | jq '[.resource_changes[] | select(.change.actions[0] != "no-op")] | length' > plan.changes
# convert plan to json expected in gitlab-ci
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26830/diffs
- terraform show -json plan.zip | jq -r '([.resource_changes[].change.actions?]|flatten)|{"create":(map(select(.=="create"))|length),"update":(map(select(.=="update"))|length),"delete":(map(select(.=="delete"))|length)}' > tfplan.json
artifacts:
name: plan
expire_in: 1 day
paths:
- plan.zip
- plan.txt
- plan.changes
reports:
terraform:
- tfplan.json
rules:
# run on merge_requests
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME'
# run on master branch
- if: '$CI_COMMIT_REF_NAME == "master"'
interruptible: false
post plan to comments:
stage: comment
variables:
GIT_STRATEGY: none
image: alpine
cache: {}
before_script:
- apk add --no-cache bash curl sed
script:
- cat plan.txt
- >-
cat ${plan}.txt | sed 's/^ //' | if test "$(cat ${plan}.changes)" -ne 0; then
./.gitlab/merge-request-discussion.sh;
else
./.gitlab/merge-request-note.sh;
fi
dependencies:
- terraform build plan
rules:
# run only on merge requests
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME'
terraform apply:
stage: apply
before_script:
- vault write -field=token auth/approle/login role_id="$VAULT_APPROLE_ID" secret_id="$VAULT_APPROLE_SECRET_ID" > ~/.vault-token
script:
- terraform apply -lock-timeout=120s -input=false plan.zip
rules:
# apply automatically on master branch when the pipeline is triggered normally
- if: '$CI_COMMIT_REF_NAME == "master" && $CI_PIPELINE_SOURCE == "push"'
when: on_success
# apply manually on master in any other case (i.e. run from schedules)
- if: '$CI_COMMIT_REF_NAME == "master"'
when: manual
interruptible: false
#!/bin/bash
set -euo pipefail
MESSAGE=$'```diff\n'
MESSAGE+="$(cat)"
MESSAGE+=$'\n```'
echo "$MESSAGE"
curl -X POST -g \
--data-urlencode "body=${MESSAGE}" \
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/discussions?private_token=${GITLAB_TOKEN}"
#!/bin/bash
set -euo pipefail
MESSAGE=$'```diff\n'
MESSAGE+="$(cat)"
MESSAGE+=$'\n```'
echo "$MESSAGE"
curl -X POST -g \
--data-urlencode "body=${MESSAGE}" \
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes?private_token=${GITLAB_TOKEN}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment