How to integrated terraform plan in gitlab CI with Azure infrastructure

Kun-Hung Tsai
3 min readNov 24, 2019

--

Recently, I try to integrate terraform in gitlab CI to help my colleague to review terraform configuration. My target is show the terraform plan result on the merge request page to help reviewers check the updated infrastructure.

The cloud provider used in my example is Azure. To use Azure in terraform, first you need to authenticate via a Service Principal and a Client Certificate. You can follow the tutorial to below to create Service Principal.

You also have to create a gitlab api access token in User Settings->Access Tokens for updating the result back to gitlab CI.

After that, you will need to set all the credentials into gitlab settings->CI/CD->variables for gitlab CI to access the variables.

Finally, you can create a .gitlab-ci.yml in your terraform project. There are two stages in my gitlab CI configuration. The test stage is used to check the format and whether the terraform config is valid or not. The plan stage will output the terraform plan result to merge request comment through gitlab API.

The whole .gitlab-ci.yml file will be like:

stages:
- test
- plan
variables:
PLAN: plan.tfplan
INFRA_DIR: infra
terraform-fmt:
stage: test
image:
name: hashicorp/terraform:0.12.0
entrypoint: [""]
script:
- terraform fmt -diff=true -write=false -check=true
terraform-validate:
stage: test
image:
name: hashicorp/terraform:0.12.0
entrypoint: [""]
script:
- terraform validate
plan:
stage: plan
image:
name: hashicorp/terraform:0.12.0
entrypoint: [""]
before_script:
- apk update
- apk add bash py-pip curl
- apk add --virtual=build gcc libffi-dev musl-dev openssl-dev python-dev make && \
- pip --no-cache-dir install -U pip && \
- pip --no-cache-dir install azure-cli && \
- apk del --purge build
- cd ./${INFRA_DIR}
script:
- az login --service-principal -u ${AZURE_CLIENT_ID} -p ${AZURE_CLIENT_SECRET} -t ${AZURE_TENANT_ID}
- export ARM_CLIENT_ID=${AZURE_CLIENT_ID}
- export ARM_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
- export ARM_SUBSCRIPTION_ID=$(az account show --query id | xargs)
- export ARM_TENANT_ID=$(az account show --query tenantId | xargs)
- terraform init
- echo \`\`\`diff > plan.txt
- terraform plan -no-color | tee -a plan.txt
- echo \`\`\` >> plan.txt
- sed -i -e 's/ +/+/g' plan.txt
- sed -i -e 's/ ~/~/g' plan.txt
- sed -i -e 's/ -/-/g' plan.txt
- MESSAGE=$(cat plan.txt)
- echo ${MESSAGE}
- >-
curl -X POST -g -H "PRIVATE-TOKEN: ${GITLAB_ACCESS_TOKEN}"
--data-urlencode "body=${MESSAGE}"
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/discussions"
artifacts:
name: plan
paths:
- ./${INFRA_DIR}/${PLAN}
only:
- merge_requests

Every time you make a new merge request, gitlab CI will do terraform plan and output plan result in comment. Here I added a new role assignment for my Azure subscription. Now you can check the plan result in merge request page without fetching the branch and planning by yourself.

The content of this post was mainly derived from these two articles. Please take a look if you need further information.

Thanks for reading and feel free to share your thoughts.

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Kun-Hung Tsai
Kun-Hung Tsai

No responses yet

Write a response