Terraform in Drone CI is less about a specific "problem" and more about understanding how to integrate a declarative infrastructure-as-code tool into an automated workflow. The surprising truth is that Drone’s container-native approach actually makes running Terraform simpler than you might expect, provided you grasp how its execution model maps to Terraform’s state management and credential handling.
Let’s see it in action. Imagine you have a main.tf file like this, setting up a simple AWS S3 bucket:
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "example" {
bucket = "my-drone-terraform-example-bucket-12345" # Must be globally unique
acl = "private"
tags = {
Environment = "Dev"
ManagedBy = "Terraform"
}
}
And you want to deploy this using Drone. Your .drone.yml might look something like this:
kind: pipeline
type: docker
name: terraform-deploy
steps:
- name: init-configure
image: hashicorp/terraform:1.5.7
commands:
- terraform init -backend-config="bucket=my-terraform-state-bucket-unique" -backend-config="key=terraform/state.tfstate" -backend-config="region=us-east-1"
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
- name: plan
image: hashicorp/terraform:1.5.7
commands:
- terraform plan -out=tfplan
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
- name: apply
image: hashicorp/terraform:1.5.7
commands:
- terraform apply -auto-approve tfplan
environment:
AWS_ACCESS_KEY_ID:
from_secret: aws_access_key_id
AWS_SECRET_ACCESS_KEY:
from_secret: aws_secret_access_key
when:
branch: main
This pipeline defines three steps: init-configure, plan, and apply.
-
init-configure: This step runsterraform init. The critical part here is the-backend-configarguments. We’re telling Terraform to use an S3 bucket (my-terraform-state-bucket-unique) to store its state file (terraform/state.tfstate) inus-east-1. This is essential for any CI/CD workflow. Without a remote backend, Terraform state would be stored locally within the ephemeral build container, lost after the pipeline runs, and impossible to coordinate across multiple runs or developers. TheAWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYare pulled from Drone secrets, providing the necessary AWS credentials. -
plan: This step executesterraform plan, generating an execution plan and saving it to a file namedtfplan. This step also requires AWS credentials. -
apply: This step runsterraform apply -auto-approve tfplan. It takes the plan generated in the previous step and applies it to your infrastructure. The-auto-approveflag is common in CI/CD to avoid interactive confirmation. This step is conditionally executed only when the pipeline runs on themainbranch.
The mental model here is that each Drone step is an isolated container. Terraform commands are executed within these containers. The hashicorp/terraform image provides the necessary tooling. The key to making this work is:
- Remote State: Always configure a remote backend (like S3, GCS, Azure Blob Storage, or Terraform Cloud) so that Terraform state is persisted outside the build agent.
- Credentials: Inject cloud provider credentials securely via environment variables, using Drone’s secret management.
- Workflow: Structure your pipeline logically – init, plan, apply. For more complex workflows, you might add steps for formatting (
terraform fmt), validation (terraform validate), or even destroy operations. - Locking: Remote backends typically handle state locking automatically, preventing concurrent runs from corrupting your state.
What most people don’t realize is that Terraform’s init command is not just about downloading providers; it’s also about configuring the state backend. If you try to run terraform plan or apply without a properly configured remote backend in a CI environment, you’ll either fail due to missing state or, worse, end up with a local state file that’s immediately discarded, leading to Terraform wanting to recreate everything on the next run. The init step’s configuration is paramount.
The next concept to explore is managing different environments (dev, staging, prod) with Terraform within Drone, likely involving separate state files and potentially different variable sets.