How to Mock Terraform Plan and Apply in Python
This code provides a lightweight Python mock of Terraform's plan and apply commands, helping you simulate infrastructure changes without real cloud resources.
Python code
30 linesclass MockTerraform:
def __init__(self):
self.plans = [
{"id": 1, "action": "create", "resource": "aws_instance.web"},
{"id": 2, "action": "update", "resource": "aws_s3_bucket.data"},
{"id": 3, "action": "destroy", "resource": "aws_iam_user.legacy"}
]
self.applied = []
def plan(self):
print("Terraform plan:")
for item in self.plans:
print(f" {item['action']:8} {item['resource']}")
return self.plans
def apply(self, confirmed=False):
if not confirmed:
print("Apply cancelled — pass confirmed=True to apply.")
return
for item in self.plans:
print(f"Applying {item['action']} {item['resource']}...")
self.applied.append(item)
print(f"Apply complete! {len(self.applied)} changes applied.")
if __name__ == "__main__":
tf = MockTerraform()
tf.plan()
tf.apply()
print("---")
tf.apply(confirmed=True)
Output
Terraform plan:
create aws_instance.web
update aws_s3_bucket.data
destroy aws_iam_user.legacy
Apply cancelled — pass confirmed=True to apply.
---
Applying create aws_instance.web...
Applying update aws_s3_bucket.data...
Applying destroy aws_iam_user.legacy...
Apply complete! 3 changes applied.
How it works
The class holds a predefined list of changes representing a Terraform plan. The plan method prints a formatted list of actions and resources, mimicking the terraform plan command. The apply method checks a confirmed flag to avoid accidental changes, reflecting Terraform's interactive approval workflow. When confirmed, it iterates over the plan and appends each item to applied, simulating a real apply. This pattern is valuable for testing deployment scripts without touching actual infrastructure.
Common mistakes
- Forgetting to reset the `applied` list between apply calls, causing incorrect counts in repeated runs.
- Hardcoding the plan data inside the class instead of passing it in, making the mock less reusable.
- Not including a confirmation safeguard, which defeats the purpose of simulating Terraform's safety.
Variations
- Use a dataclass for each change and a list passed to the constructor for more flexibility.
- Add a `dry_run` parameter that logs actions without storing them, similar to `terraform plan -out`.
Real-world use cases
- Unit testing CI/CD scripts that must react to `terraform plan` output without provisioning resources.
- Building a staging environment simulator for demos or training where real infrastructure is too costly.
- Validating internal tooling that orchestrates Terraform runs, ensuring correct sequencing and rollback logic.
Sponsored
More from Production deployment patterns
- Auto Rollback on Error Rate Exceeded in Python medium
- Automate Semantic Versioning with Conventional Commits in Python medium
- Design a Data Helper for Beginners in Python easy
- Docker healthcheck CMD mock in Python easy
- Generate a Mock Artifact Version Tag in Python easy
- Generate a docker-compose.yml with mock services in Python easy
Keep learning
Related tutorials and quizzes for this topic.