|
1 | | -# This file is for you! Edit it to implement your own Terraform make targets. |
| 1 | +# Terraform Make Targets for TFScaffold |
| 2 | +# NHS Notify standard for production infrastructure |
| 3 | +# Requires infrastructure/terraform/bin/terraform.sh |
2 | 4 |
|
3 | 5 | # ============================================================================== |
4 | | -# Custom implementation - implementation of a make target should not exceed 5 lines of effective code. |
5 | | -# In most cases there should be no need to modify the existing make targets. |
6 | | - |
7 | | -terraform-init: # Initialise Terraform - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform init command, default is none/empty] @Development |
8 | | - make _terraform cmd="init" \ |
9 | | - dir=$(or ${terraform_dir}, ${dir}) \ |
10 | | - opts=$(or ${terraform_opts}, ${opts}) |
11 | | - |
12 | | -terraform-plan: # Plan Terraform changes - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform plan command, default is none/empty] @Development |
13 | | - make _terraform cmd="plan" \ |
14 | | - dir=$(or ${terraform_dir}, ${dir}) \ |
15 | | - opts=$(or ${terraform_opts}, ${opts}) |
16 | | - |
17 | | -terraform-apply: # Apply Terraform changes - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform apply command, default is none/empty] @Development |
18 | | - make _terraform cmd="apply" \ |
19 | | - dir=$(or ${terraform_dir}, ${dir}) \ |
20 | | - opts=$(or ${terraform_opts}, ${opts}) |
21 | | - |
22 | | -terraform-destroy: # Destroy Terraform resources - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform destroy command, default is none/empty] @Development |
23 | | - make _terraform \ |
24 | | - cmd="destroy" \ |
25 | | - dir=$(or ${terraform_dir}, ${dir}) \ |
26 | | - opts=$(or ${terraform_opts}, ${opts}) |
27 | | - |
28 | | -terraform-fmt: # Format Terraform files - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform fmt command, default is '-recursive'] @Quality |
29 | | - make _terraform cmd="fmt" \ |
30 | | - dir=$(or ${terraform_dir}, ${dir}) \ |
31 | | - opts=$(or ${terraform_opts}, ${opts}) |
32 | | - |
33 | | -terraform-validate: # Validate Terraform configuration - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform validate command, default is none/empty] @Quality |
34 | | - make _terraform cmd="validate" \ |
35 | | - dir=$(or ${terraform_dir}, ${dir}) \ |
36 | | - opts=$(or ${terraform_opts}, ${opts}) |
37 | | - |
38 | | -clean:: # Remove Terraform files (terraform) - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set] @Operations |
39 | | - make _terraform cmd="clean" \ |
40 | | - dir=$(or ${terraform_dir}, ${dir}) \ |
41 | | - opts=$(or ${terraform_opts}, ${opts}) |
42 | | - |
43 | | -_terraform: # Terraform command wrapper - mandatory: cmd=[command to execute]; optional: dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], opts=[options to pass to the Terraform command, default is none/empty] |
44 | | - # 'TERRAFORM_STACK' is passed to the functions as environment variable |
45 | | - TERRAFORM_STACK=$(or ${TERRAFORM_STACK}, $(or ${terraform_stack}, $(or ${STACK}, ${stack}))) |
46 | | - dir=$(or ${dir}, ${TERRAFORM_STACK}) |
47 | | - . "scripts/terraform/terraform.lib.sh"; \ |
48 | | - terraform-${cmd} # 'dir' and 'opts' are accessible by the function as environment variables, if set |
| 6 | +# TFScaffold Terraform Operations |
| 7 | + |
| 8 | +terraform-plan: # Plan Terraform changes - mandatory: component=[component_name], environment=[environment]; optional: project=[default: nhs], region=[default: eu-west-2], group=[default: dev], opts=[additional options] @Development |
| 9 | + # Example: make terraform-plan component=mycomp environment=myenv group=mygroup |
| 10 | + # Args: --project nhs --region eu-west-2 --component mycomp --environment myenv --group mygroup --action plan |
| 11 | + make _terraform-scaffold action=plan \ |
| 12 | + component=$(component) \ |
| 13 | + environment=$(environment) \ |
| 14 | + project=$(or ${project}, nhs) \ |
| 15 | + region=$(or ${region}, eu-west-2) \ |
| 16 | + group=$(or ${group}, dev) \ |
| 17 | + opts=$(or ${opts}, ) |
| 18 | + |
| 19 | +terraform-plan-destroy: # Plan Terraform destroy - mandatory: component=[component_name], environment=[environment]; optional: project, region, group, opts @Development |
| 20 | + # Example: make terraform-plan-destroy component=mycomp environment=myenv group=mygroup |
| 21 | + # Args: --project nhs --region eu-west-2 --component mycomp --environment myenv --group mygroup --action plan-destroy |
| 22 | + make _terraform-scaffold action=plan-destroy \ |
| 23 | + component=$(component) \ |
| 24 | + environment=$(environment) \ |
| 25 | + project=$(or ${project}, nhs) \ |
| 26 | + region=$(or ${region}, eu-west-2) \ |
| 27 | + group=$(or ${group}, dev) \ |
| 28 | + opts=$(or ${opts}, ) |
| 29 | + |
| 30 | +terraform-apply: # Apply Terraform changes - mandatory: component=[component_name], environment=[environment]; optional: project, region, group, build_id, opts @Development |
| 31 | + # Example: make terraform-apply component=mycomp environment=myenv group=mygroup |
| 32 | + # Args: --project nhs --region eu-west-2 --component mycomp --environment myenv --group mygroup --action apply |
| 33 | + make _terraform-scaffold action=apply \ |
| 34 | + component=$(component) \ |
| 35 | + environment=$(environment) \ |
| 36 | + project=$(or ${project}, nhs) \ |
| 37 | + region=$(or ${region}, eu-west-2) \ |
| 38 | + group=$(or ${group}, dev) \ |
| 39 | + build_id=$(or ${build_id}, ) \ |
| 40 | + opts=$(or ${opts}, ) |
| 41 | + |
| 42 | +terraform-destroy: # Destroy Terraform resources - mandatory: component=[component_name], environment=[environment]; optional: project, region, group, opts @Development |
| 43 | + # Example: make terraform-destroy component=mycomp environment=myenv group=mygroup |
| 44 | + # Args: --project nhs --region eu-west-2 --component mycomp --environment myenv --group mygroup --action destroy |
| 45 | + make _terraform-scaffold action=destroy \ |
| 46 | + component=$(component) \ |
| 47 | + environment=$(environment) \ |
| 48 | + project=$(or ${project}, nhs) \ |
| 49 | + region=$(or ${region}, eu-west-2) \ |
| 50 | + group=$(or ${group}, dev) \ |
| 51 | + opts=$(or ${opts}, ) |
| 52 | + |
| 53 | +terraform-output: # Get Terraform outputs - mandatory: component=[component_name], environment=[environment]; optional: project, region, group @Development |
| 54 | + # Example: make terraform-output component=mycomp environment=myenv group=mygroup |
| 55 | + # Args: --project nhs --region eu-west-2 --component mycomp --environment myenv --group mygroup --action output |
| 56 | + make _terraform-scaffold action=output \ |
| 57 | + component=$(component) \ |
| 58 | + environment=$(environment) \ |
| 59 | + project=$(or ${project}, nhs) \ |
| 60 | + region=$(or ${region}, eu-west-2) \ |
| 61 | + group=$(or ${group}, dev) |
| 62 | + |
| 63 | +_terraform-scaffold: # Internal wrapper for terraform.sh - mandatory: action=[terraform action]; optional: component, environment, project, region, group, bootstrap, build_id, opts |
| 64 | + cd infrastructure/terraform && \ |
| 65 | + if [ "$(bootstrap)" = "true" ]; then \ |
| 66 | + ./bin/terraform.sh \ |
| 67 | + --bootstrap \ |
| 68 | + --project $(project) \ |
| 69 | + --region $(region) \ |
| 70 | + --group $(group) \ |
| 71 | + --action $(action) \ |
| 72 | + $(if $(opts),-- $(opts),); \ |
| 73 | + else \ |
| 74 | + ./bin/terraform.sh \ |
| 75 | + --project $(project) \ |
| 76 | + --region $(region) \ |
| 77 | + --component $(component) \ |
| 78 | + --environment $(environment) \ |
| 79 | + --group $(group) \ |
| 80 | + $(if $(build_id),--build-id $(build_id),) \ |
| 81 | + --action $(action) \ |
| 82 | + $(if $(opts),-- $(opts),); \ |
| 83 | + fi |
49 | 84 |
|
50 | 85 | # ============================================================================== |
51 | | -# Quality checks - please DO NOT edit this section! |
52 | | - |
53 | | -terraform-shellscript-lint: # Lint all Terraform module shell scripts @Quality |
54 | | - for file in $$(find scripts/terraform -type f -name "*.sh"); do |
55 | | - file=$${file} scripts/shellscript-linter.sh |
56 | | - done |
57 | | - |
58 | | -terraform-sec: # TFSEC check against Terraform files - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform fmt command, default is '-recursive'] @Quality |
59 | | - tfsec infrastructure/terraform \ |
60 | | - --force-all-dirs \ |
61 | | - --exclude-downloaded-modules \ |
62 | | - --config-file scripts/config/tfsec.yaml |
63 | | - |
64 | | -terraform-docs: # Terraform-docs check against Terraform files - optional: terraform_dir|dir=[path to a directory where the command will be executed, relative to the project's top-level directory, default is one of the module variables or the example directory, if not set], terraform_opts|opts=[options to pass to the Terraform fmt command, default is '-recursive'] @Quality |
65 | | - for dir in ./infrastructure/terraform/components/* ./infrastructure/terraform/modules/*; do \ |
| 86 | +# Formatting and Validation |
| 87 | + |
| 88 | +terraform-fmt: # Format Terraform files in components/ and modules/ (excludes etc/) @Quality |
| 89 | + # Example: make terraform-fmt |
| 90 | + @cd infrastructure/terraform && \ |
| 91 | + for dir in components modules; do \ |
| 92 | + [ -d "$$dir" ] && terraform fmt -recursive "$$dir"; \ |
| 93 | + done |
| 94 | + |
| 95 | +terraform-fmt-check: # Check Terraform formatting in components/ and modules/ (excludes etc/) @Quality |
| 96 | + # Example: make terraform-fmt-check |
| 97 | + @cd infrastructure/terraform && \ |
| 98 | + for dir in components modules; do \ |
| 99 | + [ -d "$$dir" ] && terraform fmt -check -recursive "$$dir"; \ |
| 100 | + done |
| 101 | + |
| 102 | +terraform-validate: # Validate Terraform configuration - mandatory: component=[component_name] @Quality |
| 103 | + # Example: make terraform-validate component=mycomp |
| 104 | + # Note: Validation does not require environment/group as it checks syntax only |
| 105 | + cd infrastructure/terraform/components/$(component) && \ |
| 106 | + terraform init -backend=false && \ |
| 107 | + terraform validate |
| 108 | + |
| 109 | +terraform-validate-all: # Validate all Terraform components @Quality |
| 110 | + # Example: make terraform-validate-all |
| 111 | + for dir in infrastructure/terraform/components/*; do \ |
66 | 112 | if [ -d "$$dir" ]; then \ |
67 | | - ./scripts/terraform/terraform-docs.sh $$dir; \ |
68 | | - fi \ |
| 113 | + echo "Validating $$(basename $$dir)..."; \ |
| 114 | + cd $$dir && \ |
| 115 | + terraform init -backend=false && \ |
| 116 | + terraform validate && \ |
| 117 | + cd - > /dev/null; \ |
| 118 | + fi; \ |
69 | 119 | done |
70 | 120 |
|
71 | | -# ============================================================================== |
72 | | -# Module tests and examples - please DO NOT edit this section! |
| 121 | +terraform-sec: # Run Trivy IaC security scanning on Terraform code @Quality |
| 122 | + # Example: make terraform-sec |
| 123 | + ./scripts/terraform/trivy-scan.sh --mode iac infrastructure/terraform |
| 124 | + |
| 125 | +terraform-docs: # Generate Terraform documentation - optional: component=[specific component, or all if omitted] @Quality |
| 126 | + # Example: make terraform-docs component=mycomp |
| 127 | + # Example: make terraform-docs (generates for all components) |
| 128 | + @if [ -n "$(component)" ]; then \ |
| 129 | + ./scripts/terraform/terraform-docs.sh infrastructure/terraform/components/$(component); \ |
| 130 | + else \ |
| 131 | + for dir in infrastructure/terraform/components/* infrastructure/terraform/modules/*; do \ |
| 132 | + if [ -d "$$dir" ]; then \ |
| 133 | + ./scripts/terraform/terraform-docs.sh $$dir; \ |
| 134 | + fi; \ |
| 135 | + done; \ |
| 136 | + fi |
73 | 137 |
|
74 | | -terraform-example-provision-aws-infrastructure: # Provision example of AWS infrastructure @ExamplesAndTests |
75 | | - make terraform-init |
76 | | - make terraform-plan opts="-out=terraform.tfplan" |
77 | | - make terraform-apply opts="-auto-approve terraform.tfplan" |
78 | | - |
79 | | -terraform-example-destroy-aws-infrastructure: # Destroy example of AWS infrastructure @ExamplesAndTests |
80 | | - make terraform-destroy opts="-auto-approve" |
| 138 | +# ============================================================================== |
| 139 | +# Cleanup |
81 | 140 |
|
82 | | -terraform-example-clean: # Remove Terraform example files @ExamplesAndTests |
83 | | - dir=$(or ${dir}, ${TERRAFORM_STACK}) |
84 | | - . "scripts/terraform/terraform.lib.sh"; \ |
85 | | - terraform-clean |
86 | | - rm -f ${TERRAFORM_STACK}/.terraform.lock.hcl |
| 141 | +clean:: # Remove Terraform build artifacts and cache @Operations |
| 142 | + # Example: make clean |
| 143 | + rm -rf infrastructure/terraform/components/*/build |
| 144 | + rm -rf infrastructure/terraform/components/*/.terraform |
| 145 | + rm -rf infrastructure/terraform/components/*/.terraform.lock.hcl |
| 146 | + rm -rf infrastructure/terraform/bootstrap/.terraform |
| 147 | + rm -rf infrastructure/terraform/bootstrap/.terraform.lock.hcl |
| 148 | + rm -rf infrastructure/terraform/plugin-cache/* |
87 | 149 |
|
88 | 150 | # ============================================================================== |
89 | | -# Configuration - please DO NOT edit this section! |
| 151 | +# Installation |
90 | 152 |
|
91 | | -terraform-install: # Install Terraform @Installation |
| 153 | +terraform-install: # Install Terraform using asdf @Installation |
| 154 | + # Example: make terraform-install |
92 | 155 | make _install-dependency name="terraform" |
93 | 156 |
|
94 | 157 | # ============================================================================== |
95 | 158 |
|
96 | 159 | ${VERBOSE}.SILENT: \ |
97 | | - _terraform \ |
| 160 | + _terraform-scaffold \ |
98 | 161 | clean \ |
99 | 162 | terraform-apply \ |
100 | 163 | terraform-destroy \ |
101 | | - terraform-example-clean \ |
102 | | - terraform-example-destroy-aws-infrastructure \ |
103 | | - terraform-example-provision-aws-infrastructure \ |
104 | | - terraform-fmt \ |
105 | 164 | terraform-docs \ |
106 | | - terraform-init \ |
| 165 | + terraform-fmt \ |
| 166 | + terraform-fmt-check \ |
107 | 167 | terraform-install \ |
| 168 | + terraform-output \ |
108 | 169 | terraform-plan \ |
109 | | - terraform-shellscript-lint \ |
| 170 | + terraform-plan-destroy \ |
| 171 | + terraform-sec \ |
110 | 172 | terraform-validate \ |
| 173 | + terraform-validate-all \ |
0 commit comments