This project demonstrates how to use Terraform + GitHub Actions + AWS OIDC to create ephemeral environments for every Pull Request (PR).
The benefits:
- Faster feedback – every PR spins up a live testable environment.
- Isolation – no more shared staging collisions.
- Cost control – resources are cleaned up automatically, avoiding cloud bill sprawl.
- Governance – every resource is tagged to its PR for traceability.
This approach makes infrastructure testing safe, efficient, and cost-aware by treating environments as short-lived features rather than permanent setups.
When a contributor opens a PR that contains new Terraform resources (like EC2, S3, etc.), the pipeline will:
- Automatically create an isolated environment named after the PR number (e.g.,
pr-42
). - Deploy resources with that PR number tagged.
- When the PR is merged or closed, the destroy pipeline automatically runs and cleans up all resources tied to that PR.
- Trigger: when a PR is opened/reopened/synchronized
- Steps:
- Checkout repo
- Authenticate to AWS via OIDC
- Run
terraform init
using the backend (S3 + DynamoDB) - Create/select a workspace named
pr-<number>
- Run
terraform apply -auto-approve -var="pr_number=<number>"
- Trigger: when a PR is closed
- Steps:
- Checkout repo
- Authenticate to AWS via OIDC
- Run
terraform init
- Select the workspace
pr-<number>
- Run
terraform destroy -auto-approve -var="pr_number=<number>"
- Delete the workspace
In the main
branch, include a bootstrap module that creates:
- An S3 bucket for state
- A DynamoDB table for state locking
- An IAM role for GitHub OIDC
This bootstrap step outputs a backend.tf
file like:
terraform {
backend "s3" {
bucket = "terraform-ephemeral-envs-state-24a14f93"
key = "envs/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-ephemeral-envs-locks-24a14f93"
encrypt = true
}
}
Then commit:
backend.tf
versions.tf
providers.tf
to your main
branch.
- Developers or testers create a new branch (for example):
git checkout -b feature/test-s3
- Add a new Terraform resource, for example an S3 bucket (see the branch feature/test-s3)
Commit and push the branch.
- Open a PR against
main
. - The
PR Create – Ephemeral Env
workflow runs automatically. - Terraform provisions the bucket with
PR=<number>
as a tag.
- Reviewers can approve the request once the tester has completed their work.
- Once testing is done → merge or close the PR.
- The
PR Destroy – Ephemeral Env
workflow runs. - All resources tied to that PR (workspace + tags) are destroyed.
- No orphaned resources.
- PR #10 opened → creates S3 bucket
test-pr-10
- PR #11 opened → creates EC2 instance
ephemeral-pr-11
- PR #10 merged → bucket destroyed
- PR #11 closed → EC2 destroyed
Every PR manages its own short-lived environment.
With this setup, project managers and teams get full control over testing resources without worrying about cost sprawl or forgotten environments.