You can achieve this by splitting your workflow into separate jobs (or steps) where one job runs the Terraform plan and saves the plan file as an artifact, and a later job (or step) downloads that artifact to perform the apply. This pattern ensures that the plan generated during the "plan" stage is used exactly in the "apply" stage, reducing drift between them.
Typical Workflow Steps
-
Terraform Plan Job/Step:
-
Terraform Apply Job/Step:
Example GitHub Actions Workflow
Below is an example snippet of a GitHub Actions YAML file that demonstrates this approach:
name: Terraform Workflow
on:
push:
branches:
- main
jobs:
terraform-plan:
runs-on: ubuntu-latest
outputs:
plan_artifact: ${{ steps.upload.outputs.artifact-name }}
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 1.0.0 # specify your version
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan -out=plan.tfplan
- name: Upload Plan Artifact
id: upload
uses: actions/upload-artifact@v2
with:
name: tfplan
path: plan.tfplan
terraform-apply:
needs: terraform-plan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 1.0.0
- name: Download Plan Artifact
uses: actions/download-artifact@v2
with:
name: tfplan
- name: Terraform Apply
run: terraform apply -auto-approve plan.tfplan
Key Considerations
- Environment Consistency: Make sure that both the plan and apply jobs run in environments with the same Terraform version and OS to avoid issues with plan portability.
- Approval Steps: In production scenarios, you might want to include a manual approval or additional checks between the plan and apply steps.
- Artifact Size & Security: Terraform plan files are generally lightweight, but always be cautious if your workflow might include sensitive information.
Using this pattern, you ensure that the exact plan generated is what gets applied, reducing the risk of any unexpected changes between stages.
You can achieve this by splitting your workflow into separate jobs (or steps) where one job runs the Terraform plan and saves the plan file as an artifact, and a later job (or step) downloads that artifact to perform the apply. This pattern ensures that the plan generated during the "plan" stage is used exactly in the "apply" stage, reducing drift between them.
Typical Workflow Steps
Terraform Plan Job/Step:
terraform init.terraform plan -out=plan.tfplanto output a plan file.plan.tfplan.Terraform Apply Job/Step:
terraform apply -auto-approve plan.tfplanto apply the previously generated plan.Example GitHub Actions Workflow
Below is an example snippet of a GitHub Actions YAML file that demonstrates this approach:
Key Considerations
Using this pattern, you ensure that the exact plan generated is what gets applied, reducing the risk of any unexpected changes between stages.