In this post, I will describe how to use a terraform plan and apply it with bitbucket pipelines using the shared-ci feature.

Shared-ci is bitbucket premium feature used to establish consistent workflows and reduce copying and pasting yml from one repo to another.

More information about shared-ci pipelines can be found on the bitbucket webpage at this link

As we can think of shared-ci as templates, we can then have a separate repo for terraform code where our bitbucket-pipelines.yml will reside.

The pipeline that should serve as a template will look like this:

export: true

image: hashicorp/terraform:1.9

definitions:
 pipelines:
 terraform-validate:
 - step:
 name: 'Validate Terraform'
 script:
 - terraform -chdir=terraform/infrastructure init -backend-config="config/$TF_ENV.init" -reconfigure -upgrade
 - terraform validate
 - terraform -chdir=terraform/infrastructure plan -out=terraform-plan.out -parallelism=15
 terraform-apply:
 - step:
 name: 'Validate Terraform'
 script:
 - terraform -chdir=terraform/infrastructure init -backend-config="config/$TF_ENV.init" -reconfigure -upgrade
 - terraform validate
 - terraform -chdir=terraform/infrastructure plan -out=terraform-plan.out -parallelism=15
 artifacts:
 - terrafrom-plan.out
 - step:
 name: 'Apply Terraform for EU'
 trigger: manual
 script:
 - terraform -chdir=terraform/infrastructure init -backend-config="config/$TF_ENV.init" -reconfigure -upgrade
 - terraform -chdir=terraform/infrastructure apply -auto-approve

The main thing that we have is export: true to say this pipeline is used as a template, and in definition part we specify our steps.

In this example, the pipeline is exporting two actions terraform-validate and terraform-plan. This will be used in other bitbucket repository where we want to run defined steps.

In the other repo where we want to run our terraform steps which we defined in a previous step, we need to create a file bitbucket-pipelines.yml and define our pipeline.

pipelines:
 branches:
 "**":
 import: <repo_name>:<branch>:terraform-validate
 main:
 import: <repo_name>:<branch>:terraform-apply

In this example, terraform-validate is run for every merge, and terraform-apply is run when we merge to the main branch.