This repository holds code that demonstrates a progression of ever more sophisticated use cases for orchestrating Terraform. We use Temporal with golang for the orchestration.
This was orginally developed for a workshop delivered at PlatformCon 2025 (live in London and virtual) (will add links the the recordings when available).
This code orchestrates the provisioning and management of an AWS EC2 instance and then a Cloudflare DNS record for the newly created server. It does support multiple running environments with a very simple state file storage mechanism - it stores them in subdirectories under terraform-configs/*-terraform/state
.
Please see the session recordings (coming soon) for more details.
- temporal cli installed
- terraform cli installed
- You will need a domain to which you can add DNS entries in Cloudflare and you will need to set the following env vars:
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
export CLOUDFLARE_ZONE_ID="..."
export CLOUDFLARE_API_TOKEN="..."
You will need three command windows.
In the first, run the Temporal service locally with temporal server start-dev
. You will then find the Temporal UI at http://localhost:8233/
You will use the other two to perform the demos
git checkout demo1
- Run the orchstration in the first terminal:
go run ./cmd/worker/main.go
- Run the starter in the second terminal:
go run ./cmd/starter/main.go -action=create
- To destroy
go run ./cmd/starter/main.go -action=destroy -environment=env-id
- Show the workflow in the UI - just the two activity calls.
- Show the workflow code.
git checkout demo2
- Run the orchstration:
go run ./cmd/worker/main.go
- Run the starter:
go run ./cmd/starter/main.go -action=create -dns-approved=false
- To approve
go run ./cmd/starter/main.go -action=approve -environment=env-id
- To destroy
go run ./cmd/starter/main.go -action=destroy -environment=env-id
- To approve
- In the UI show the signal coming in.
- In the code show the selectors that allow for signals to come into the workflow
- Kill the orchestration while it's waiting on approval. Let the timer fire. Bring the orchestration back.
- Use the
shouldfail
flag in the activity. If you do it for DNS you'll have the opportunity to point out that the AWS infra provisioning is not retried.
git checkout demo3
- Run the orchstration:
go run ./cmd/worker/main.go
- Run the starter:
go run ./cmd/starter/main.go -action=create -dns-approved=false
- To approve
go run ./cmd/starter/main.go -action=approve -environment=env-id
- To destroy
go run ./cmd/starter/main.go -action=destroy -environment=env-id
- To approve
- Show the timer
- Show the durability of the timer by running again and killing the orchstration right after the timer starts.
- Start a creation:
go run ./cmd/starter/main.go -action=create
- Kill the orchstration before the AWS provisioning is finished.
- Restart the orchstration
- After the start to close timeout, it will retry which doesn't recreate because terraform is usually idempotent.
- Start a creation:
go run ./cmd/starter/main.go -action=create
- Note that after the steps finish the workfow is still running
- Update:
go run ./cmd/starter/main.go -action=update -environment=env-id
- if done with no change to the
main.tf
it will be a no op. - if ami is changed in the
main.tf
terraform will cause old instance to shut down and a new one to be created.
- if done with no change to the
- To approve
go run ./cmd/starter/main.go -action=approve -environment=env-id
- To destroy
go run ./cmd/starter/main.go -action=destroy -environment=env-id
- this will end the workflow (after deprovisioning)