-
-
Save pbnj/2db32dcea4901d77c2c126f387d9abda to your computer and use it in GitHub Desktop.
Makefile for managing a Terraform project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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