12 Bash Scripts That Replace Tedious Terraform Commands
speed up your Terraform workflow with these Bash helpers
12 Bash Scripts That Replace Tedious Terraform Commands
speed up your Terraform workflow with these Bash helpers
1. tf-init-all.sh
Initializes every module in a repo with a single command.
#!/usr/bin/env bash
# tf-init-all.sh
# Usage: ./tf-init-all.sh [workspace-name]
set -e
WORKSPACE=${1:-default}
echo "Switching to workspace: $WORKSPACE"
terraform workspace select "$WORKSPACE" || terraform workspace new "$WORKSPACE"
echo "Initializing root and child modules..."
find . -maxdepth 2 -type f -name '*.tf' -execdir terraform init \;
echo "All modules initialized in workspace '$WORKSPACE'."
-We pick (or create) the workspace you pass in.
-find scans each subdirectory for .tf files and runs terraform init there.
- Saves you from cd‑ing into each module folder.
2. tf-plan-diff.sh
Runs a plan and opens the diff in your default pager.
#!/usr/bin/env bash
# tf-plan-diff.sh
set -euo pipefail
PLAN_FILE="tfplan.out"
terraform plan -out="$PLAN_FILE" "$@"
echo "Plan saved to $PLAN_FILE. Showing diff:"
terraform show -no-color "$PLAN_FILE" | less -R
- Runs
terraform plan, capturing the plan to a file. - Pipes
terraform showintoless, so you can scroll and search changes.
3. tf-apply-auto.sh
Applies the last plan without prompting.
#!/usr/bin/env bash
# tf-apply-auto.sh
set -euo pipefail
PLAN_FILE="tfplan.out"
if [[ ! -f "$PLAN_FILE" ]]; then
echo "Plan file '$PLAN_FILE' not found. Run tf-plan-diff.sh first."
exit 1
fi
echo "Applying plan from $PLAN_FILE without prompt..."
terraform apply -auto-approve "$PLAN_FILE"
echo "Terraform apply completed."
- Ensures a plan exists, then hands it off to Terraform with
-auto-approve. - Perfect for CI pipelines or trusted environments.
4. tf-destroy-quick.sh
Destroys all resources in a workspace with confirmation.
#!/usr/bin/env bash
# tf-destroy-quick.sh
set -euo pipefail
echo " WARNING: This will destroy ALL resources in the CURRENT workspace."
read -rp "Type DESTROY to continue: " CONFIRM
if [[ "$CONFIRM" != "DESTROY" ]]; then
echo "Destruction aborted."
exit 0
fi
terraform destroy -auto-approve
echo "All resources destroyed."
- Adds a guard to prevent accidental destruction.
- Uses
-auto-approveonce you type the magic word.
5. tf-show-state.sh
Quickly shows the current Terraform state in JSON.
#!/usr/bin/env bash
# tf-show-state.sh
set -euo pipefail
terraform state pull | jq .
terraform state pullfetches the current state.- Piped into jq for pretty‑printing JSON.
6. tf-state-remove.sh
Removes a resource from the state without touching real infra.
#!/usr/bin/env bash
# tf-state-remove.sh
# Usage: ./tf-state-remove.sh <resource_address>
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <resource_address>"
exit 1
fi
terraform state rm "$1"
echo "Removed $1 from state."
- Takes a Terraform resource address (e.g., module.db.aws_db_instance.main).
- Uses
terraform state rmto “forget” it which can come in handy for cleanups that aren’t autonated.
7. tf-output-all.sh
Prints all outputs with names.
#!/usr/bin/env bash
# tf-output-all.sh
set -euo pipefail
terraform output -json | jq -r 'to_entries[] | "\(.key): \(.value.value)"'
Queries outputs in JSON, then uses ‘jq’ to list each key/value pair neatly.
8. tf-validate-each.sh
Validates every child module’s syntax.
#!/usr/bin/env bash
# tf-validate-each.sh
set -euo pipefail
echo "Validating all modules..."
find . -maxdepth 2 -type f -name '*.tf' -execdir terraform validate \; || {
echo "Validation failed in one or more modules."
exit 1
}
echo "All modules are syntactically valid."
- Similar to tf-init-all.sh ’s find logic, but runs
terraform validate. - Prevents module‑level syntax errors before you plan.
9. tf-backup-state.sh
Backs up the remote state file locally with a timestamp.
#!/usr/bin/env bash
# tf-backup-state.sh
set -euo pipefail
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="terraform-state-backup-$TIMESTAMP.tfstate"
echo "Backing up remote state to $BACKUP_FILE..."
terraform state pull > "$BACKUP_FILE"
echo "State backup created at $BACKUP_FILE."
- Grabs remote state via
state pull. - Saves it with a timestamp so you can archive or diff later.
10. tf-workspace-list.sh
Lists all workspaces with “current” highlighted.
#!/usr/bin/env bash
# tf-workspace-list.sh
set -euo pipefail
terraform workspace list | sed -e 's/^\*/ current/' -e 's/^[[:space:]]*//'
- Runs
terraform workspace list. - Uses
sedto mark the current workspace with an asterisk or custom label.
11. tf-plan-drift.sh
Checks for drift by comparing current infra to state.
#!/usr/bin/env bash
# tf-plan-drift.sh
set -euo pipefail
echo "Checking for drift..."
terraform plan -detailed-exitcode -no-color
EXIT_CODE=$?
case $EXIT_CODE in
0)
echo "No drift – infrastructure matches the state."
;;
2)
echo " Drift detected – changes required."
;;
*)
echo "Error during plan. Exit code: $EXIT_CODE"
exit $EXIT_CODE
;;
esac
-detailed-exitcodereturns ‘2' if changes are needed (drift), ‘0’ if clean.- Great for automated drift detection scripts.
12. tf-apply-tagging.sh
Applies a global tag to all resources before apply.
#!/usr/bin/env bash
# tf-apply-tagging.sh
# Usage: ./tf-apply-tagging.sh key=value
set -euo pipefail
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <tag_key>=<tag_value>"
exit 1
fi
export TF_VAR_global_tag="$1"
echo "Global tag set to $TF_VAR_global_tag"
terraform apply -auto-approve
- Exports a variable (
global_tag) that your Terraform code picks up in resource blocks. - Handy if you tag all resources (e.g., cost center, owner) via a single script.
P.S. I recently released a DevOps Starter Kit — a bundle of 20+ Bash scripts, cron jobs, and Docker templates to speed up your infrastructure setup. If you do a lot of server work, you might find it useful.
메타데이터
- post_id
- 1558106567df
- slug
- 12-bash-scripts-that-replace-tedious-terraform-commands-1558106567df
- url
- https://medium.com/@obaff/12-bash-scripts-that-replace-tedious-terraform-commands-1558106567df
- canonical_url
- https://medium.com/@obaff/12-bash-scripts-that-replace-tedious-terraform-commands-1558106567df
- author_url
- https://medium.com/@obaff
- status
- ok
- fetched_at
- 2026-07-29 18:39:55