Skip to content

Instantly share code, notes, and snippets.

@pbnj
Forked from SteveByerly/Makefile
Created December 6, 2022 20:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbnj/2db32dcea4901d77c2c126f387d9abda to your computer and use it in GitHub Desktop.
Save pbnj/2db32dcea4901d77c2c126f387d9abda to your computer and use it in GitHub Desktop.
Makefile for managing a Terraform project
MAKEFLAGS += --warn-undefined-variables
SHELL := bash
.SHELLFLAGS := -eu -o pipefail -c
.DEFAULT_GOAL := help
.SUFFIXES:
# ---------------------------------------------------------
# Local Variables
# ---------------------------------------------------------
# Will setup when there are multiple environments
TF_ENV ?= $(shell read -p "Environment: ";echo $$REPLY)
env_name := $(TF_ENV)
# Current directory of the Makefile
current_dir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
# Directory for environment config files
config_dir := $(current_dir)config
# Directory for the root terraform application
root_module_dir := $(current_dir)root
# Directory for saved plans
plan_dir := $(current_dir)/tf_plans
# Directory for caching reused Terraform plugins
plugin_cache_dir := $(current_dir)/.terraform.d/plugin-cache
# Directory for the specified environment
env_dir := $(config_dir)/$(env_name)
# Directory for the environment's data
data_dir := $(env_dir)/.terraform
# Absolute paths to config files
backend_config := $(env_dir)/backend.tfvars
default_vars := $(env_dir)/default.tfvars
# ---------------------------------------------------------
# Environment Variables
# ---------------------------------------------------------
# Global TF env vars
export TF_DATA_DIR=$(data_dir)
export TF_PLUGIN_CACHE_DIR=$(plugin_cache_dir)
# Argument-specific env vars
export TF_CLI_ARGS_apply=-var-file=$(default_vars) -no-color
export TF_CLI_ARGS_destroy=-var-file=$(default_vars)
export TF_CLI_ARGS_graph=-draw-cycles -module-depth=-1
export TF_CLI_ARGS_import=-config=$(root_module_dir) -no-color
export TF_CLI_ARGS_init=-backend-config=$(backend_config) -no-color
export TF_CLI_ARGS_plan=-input=false -var-file=$(default_vars) -no-color
export TF_CLI_ARGS_refresh=-var-file=$(default_vars) -no-color
export TF_CLI_ARGS_state=-var-file=$(default_vars)
export TF_CLI_ARGS_validate=-check-variables=true -var-file=$(default_vars) -no-color
.PHONY: all
all: validate format plan #help: Validates, formats, and plans the environment
.PHONY: help
help:
@grep -E '^[a-zA-Z_-]+:.*?#help: .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?#help: "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
# ---------------------------------------------------------
# Config
# ---------------------------------------------------------
.PHONY: init
init: #help: Initializes the environment, downloading modules and remote state
terraform init $(root_module_dir)
.PHONY: update
update: #help: Updates the modules for the environment
terraform get --update=true $(root_module_dir)
# ---------------------------------------------------------
# Formatting
# ---------------------------------------------------------
.PHONY: lint
lint: #help: Checks that all files have been properly formatted
terraform fmt --diff --check --recursive
.PHONY: format
format: #help: Formats all files in the provided directory
terraform fmt --diff --recursive
.PHONY: validate
validate: #help: Validates terraform files and whether all required variables have been declared
terraform validate $(root_module_dir)
# ---------------------------------------------------------
# Create
# ---------------------------------------------------------
.PHONY: plan
plan: update #help: Generates the execution plan for the environment
terraform plan $(root_module_dir)
.PHONY: plan-ci
plan-ci: update #help: Generates the execution plan for the environment
terraform plan -out=./tf_plan $(root_module_dir)
.PHONY: plan-show
plan-show: plan-ci #help: Generates the execution plan for the environment
cd $(root_module_dir); \
terraform show -json ../tf_plan > ../tf_plan.json
.PHONY: apply
apply: #help: Applies the execution plan for the environment
terraform apply -auto-approve $(root_module_dir)
.PHONY: import
import: #help: Imports the specified resource
address=$(shell read -p "Resource Address: ";echo $$REPLY); \
resource_id=$(shell read -p "Resource ID: ";echo $$REPLY); \
terraform import $$address $$resource_id
# ---------------------------------------------------------
# Destroy
# ---------------------------------------------------------
.PHONY: plan-destroy
plan-destroy: init #help: Generates the destruction plan for the environment
terraform plan -destroy=true $(root_module_dir) | landscape
.PHONY: destroy
destroy: #help: Destroys the resources from the execution plan
terraform destroy -auto-approve $(root_module_dir)
# ---------------------------------------------------------
# State
# ---------------------------------------------------------
.PHONY: refresh
refresh: #help: Update state with metadata from the physical resources
terraform refresh $(root_module_dir)
.PHONY: output
output: update #help: Show outputs of a module or the entire state
@if [ -z $(MODULE) ]; then terraform output ; else terraform output -module=$(MODULE) ; fi
.PHONY: graph
graph: #help: Produces a visual graph of all resources
terraform graph $(root_module_dir) | dot -Tpng > graph.png
open graph.png
.PHONY: move
move: #help: Moves the specified resource within the state file
old=$(shell read -p "Previous Resource: ";echo $$REPLY); \
new=$(shell read -p "New Resource: ";echo $$REPLY); \
cd $(root_module_dir) && terraform state mv $$old $$new
.PHONY: remove
remove: #help: Removes the specified resource from the state file
old=$(shell read -p "Resource to Remove: ";echo $$REPLY); \
cd $(root_module_dir) && terraform state rm $$old
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment