Seven Steps from Local Change to Production
Day 20 of the 30-Day Terraform Challenge — and today I learned that infrastructure deployment should look exactly like application deployment.
The same seven steps developers trust to ship code safely can be used to ship infrastructure. No more "clicking around in the console." No more "who changed that security group?" No more "it works on my machine."
Here's how it works.
The Seven-Step Workflow
| Step | Action |
|---|---|
| 1 | Use version control |
| 2 | Run the code locally |
| 3 | Make code changes |
| 4 | Submit changes for review |
| 5 | Run automated tests |
| 6 | Merge and release |
| 7 | Deploy |
Step 1: Version Control
Every infrastructure change starts in Git. Not in the AWS Console. Not in a script. Not in a Slack message.
git init
git add .
git commit -m "Initial web server - Version 1"
git push origin main
Why this matters: Every change has an author, a timestamp, and a reason. No more mystery changes.
Step 2: Run Locally
Before proposing changes, run them locally to see what will happen.
terraform plan -out=day20.tfplan
The output shows exactly what will change:
- Which resources will be created
- Which will be modified
- Which will be destroyed
Why this matters: You catch mistakes before they reach production. Not after.
Step 3: Make Code Changes
Create a feature branch and make your change:
git checkout -b update-to-v3
# Edit main.tf
git add .
git commit -m "Update web server to Version 3"
git push origin update-to-v3
Why this matters: Changes are isolated. Main branch stays deployable. Multiple engineers can work simultaneously.
Step 4: Submit for Review
Open a pull request on GitHub. Include the terraform plan output in the description.
Why this matters: Code review catches mistakes. The plan output shows the reviewer exactly what will happen in production — without them running Terraform themselves.
Step 5: Run Automated Tests
Your CI pipeline runs terraform validate, terraform fmt, and terraform test automatically on every PR.
Why this matters: Catch syntax errors, formatting issues, and logic mistakes before a human ever looks at them.
Step 6: Merge and Release
After approval, merge the PR and tag the release:
git checkout main
git pull origin main
git tag -a "v3.0.0" -m "Version 3 release"
git push origin v3.0.0
Why this matters: Tags give you a history of what changed when. Rollback is as simple as checking out an old tag.
Step 7: Deploy
Apply the saved plan:
terraform apply day20.tfplan
Then verify:
$ curl http://my-server.com
<h1>Version 3: Day 20 workflow complete!</h1>
Why this matters: The plan was reviewed, tested, and approved before apply. No surprises.
What I Actually Deployed
A simple web server that shows its version:
| Version | Command | Result |
|---|---|---|
| v1 | terraform apply |
"Version 1: Hello from Day 20!" |
| v2 | terraform plan && apply |
Tag changed, but user_data didn't run |
| v3 | Added user_data_replace_on_change = true
|
"Version 3: Day 20 workflow complete!" |
The third attempt worked because I learned that EC2 instances don't re-run user_data unless you force replacement.
Workflow Comparison
| Step | Application Code | Infrastructure Code | Key Difference |
|---|---|---|---|
| Version control | Git for source code | Git for .tf files | State file is NOT in Git |
| Run locally |
npm start / python app.py
|
terraform plan |
Plan shows what will change, not a running app |
| Make changes | Edit source files | Edit .tf files | Changes affect real cloud resources |
| Review | Code diff in PR | Plan output in PR | Reviewer must understand cloud implications |
| Automated tests | Unit tests, linting | terraform test |
Infra tests deploy real resources → cost |
| Merge and release | Merge + tag | Merge + tag | Module consumers must pin versions |
| Deploy | CI/CD pipeline | terraform apply |
Apply must be run from trusted, locked environment |
The Biggest Difference
Application code: You run it and see if it works.
Infrastructure code: You run plan and predict what will happen. Then you trust the prediction.
That trust comes from:
- Code review
- Automated tests
- A history of successful deploys
- The ability to roll back
What I Learned
Plan output is the most powerful review tool. Include it in every PR. It shows exactly what will change.
User_data doesn't re-run on existing instances. You need user_data_replace_on_change = true or a launch template with create_before_destroy.
Git workflow works for infrastructure. The same seven steps developers trust can be used to deploy infrastructure safely.
Tags matter. Every release gets a tag. Every tag is a rollback point.
The Bottom Line
Infrastructure deployment doesn't need to be risky or mysterious.
The same seven-step workflow that engineers trust to ship application code works perfectly for Terraform.
| Before | After |
|---|---|
| Console clicks | Pull requests |
| "Who changed this?" | Git blame |
| Manual testing | Automated tests |
| Hope it works | Plan output proves it |
| Can't roll back | Tags = rollback points |
Version control. Plan. Review. Test. Merge. Tag. Deploy.
Seven steps. Every time. No exceptions.
P.S. The moment I saw terraform plan show exactly what would change, and then curl confirm it worked, I finally understood why teams adopt this workflow. It's not slower. It's safer.
Top comments (0)