Terraform in a pipeline - how to check for plan changes
Asked Answered
C

2

5

I’m trying to create a pipeline (in Azure Devops) that runs some Terraform code. The logic of what I’m trying to do is:

  • Run terraform plan
  • Check if terraform plan has changes
  • If so, prompt user to manually review the changes and then accept / reject
  • Proceed to terraform apply if accepted

I have the terraform plan stage all working, but I'm struggling to identify how to programmatically identify if the output of terraform plan has changes to review or not.

I was trying to use the following environment variables that are supposedly set to true/false after running ‘terraform plan’

TERRAFORM_PLAN_HAS_CHANGES
TERRAFORM_PLAN_HAS_DESTROY_CHANGES

But it doesn’t appear that they are being set, at least in the Terraform version that I’m using (v1.4.2).

What would be the best way of programmatically checking if changes are there to review? Or should I shift my logic?

Colima answered 30/3, 2023 at 15:6 Comment(0)
I
4

Environment variables are not automatically saved between steps in Azure Pipelines.

You have to use the ##vso logging commands to set output variables if you want to persist information between tasks. If you want to persist it across jobs or stages, you additionally have to set isOutput=true.

terraform plan -input=false -no-color -detailed-exitcode  

retVal=$?
if [ $retVal -eq 2 ]; then
    echo "##vso[task.setvariable variable=planChanged;isOutput=true]true"
else
    echo "##vso[task.setvariable variable=planChanged;isOutput=true]false"
fi 

Then, down-stream in another job, you'd set the condition:

condition: and(succeeded(), eq(coalesce(dependencies.Plan_${{ parameters.stage }}.outputs['Plan_${{ parameters.stage }}.planstep.planChanged'], 'true'), 'true'))

where Plan_${{ parameters.stage }} is the name of the job, and planstep is the name of the step in which you set the output variable.

Illstarred answered 30/3, 2023 at 18:8 Comment(2)
Thanks, this is helpful, I didn't consider just using $?. I'm still struggling here though - I have one step as a TerraformTaskV2 to generate the Terraform plan, and then the immediate step afterwards I have a bash step to do what you outline. The issue is that retVal gets set to nothing (I tried echoing it after assignment to check), so the following logic never kicks in. Would I have to basically include terraform plan in the same bash step instead of using the dedicated TerraformTaskV2 step to get this to work?Colima
Yes, I just use inline scripts for running Terraform. I don't use TerraformTaskV2.Illstarred
A
3

You can run terraform plan like this

terraform plan -detailed-exitcode 

If the exit code == 2, then there are changes present.

Source

Amputee answered 30/3, 2023 at 15:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.