diff --git a/.commitlintrc.yaml b/.commitlintrc.yaml new file mode 100644 index 0000000..70a3ab0 --- /dev/null +++ b/.commitlintrc.yaml @@ -0,0 +1,19 @@ +--- +rules: + body-leading-blank: [1, always] + body-max-line-length: [2, always, 100] + footer-leading-blank: [1, always] + footer-max-line-length: [2, always, 100] + header-max-length: [2, always, 100] + subject-case: + - 2 + - never + - [sentence-case, start-case, pascal-case, upper-case] + subject-empty: [2, never] + subject-full-stop: [2, never, "."] + type-case: [2, always, lower-case] + type-empty: [2, never] + type-enum: + - 2 + - always + - [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] diff --git a/.tflint.hcl b/.tflint.hcl index 6f180df..31a4e68 100644 --- a/.tflint.hcl +++ b/.tflint.hcl @@ -1,13 +1,18 @@ plugin "aws" { enabled = true - version = "0.30.0" + version = "0.32.0" source = "github.com/terraform-linters/tflint-ruleset-aws" } +plugin "terraform" { + enabled = true + version = "0.7.0" + source = "github.com/terraform-linters/tflint-ruleset-terraform" +} + config { call_module_type = "local" - module = true - force = false + force = false } rule "terraform_required_providers" { @@ -62,8 +67,3 @@ rule "terraform_standard_module_structure" { rule "terraform_workspace_remote" { enabled = true } - -# seems to be a bug when a resource is not created -rule "aws_route_not_specified_target" { - enabled = false -} diff --git a/Makefile b/Makefile index ceecd6d..9458065 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,4 @@ # -# Copyright (C) 2024 Appvia Ltd -# # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 @@ -14,59 +12,150 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -AUTHOR_EMAIL=info@appvia.io - -.PHONY: all security lint format documentation documentation-examples validate-all validate validate-examples init +.PHONY: all security lint format documentation documentation-examples validate-all validate validate-examples init examples tests default: all all: $(MAKE) init $(MAKE) validate - $(MAKE) security + $(MAKE) tests $(MAKE) lint + $(MAKE) security $(MAKE) format $(MAKE) documentation - $(MAKE) documentation-examples -security: - @echo "--> Running Security checks" - @trivy config . +examples: + $(MAKE) validate-examples + $(MAKE) tests + $(MAKE) lint-examples + $(MAKE) lint + $(MAKE) security + $(MAKE) format + $(MAKE) documentation documentation: @echo "--> Generating documentation" @terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject . + $(MAKE) documentation-modules + $(MAKE) documentation-examples + +documentation-modules: + @echo "--> Generating documentation for modules" + @if [ -d modules ]; then \ + find modules -type d -mindepth 1 -maxdepth 1 -exec terraform-docs markdown table --output-file README.md --output-mode inject {} \; ; \ + fi documentation-examples: @echo "--> Generating documentation examples" - @find examples -type d -mindepth 1 -maxdepth 1 -exec terraform-docs markdown table --output-file README.md --output-mode inject {} \; + @if [ -d examples ]; then \ + find examples -type d -mindepth 1 -maxdepth 1 -exec terraform-docs markdown table --output-file README.md --output-mode inject {} \; ; \ + fi + +upgrade-terraform-providers: + @printf "%s Upgrading Terraform providers for %-24s" "-->" "." + @terraform init -upgrade >/dev/null && echo "[OK]" || echo "[FAILED]" + @$(MAKE) upgrade-terraform-example-providers + +upgrade-terraform-example-providers: + @if [ -d examples ]; then \ + find examples -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ + printf "%s Upgrading Terraform providers for %-24s" "-->" "$$dir"; \ + terraform -chdir=$$dir init -upgrade >/dev/null && echo "[OK]" || echo "[FAILED]"; \ + done; \ + fi init: @echo "--> Running terraform init" @terraform init -backend=false -validate-all: - @echo "--> Running all validation checks" - $(MAKE) validate - $(MAKE) validate-examples +security: + @echo "--> Running Security checks" + @trivy config . + $(MAKE) security-modules + $(MAKE) security-examples + +security-modules: + @echo "--> Running Security checks on modules" + @if [ -d modules ]; then \ + find modules -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ + echo "--> Validating $$dir"; \ + trivy config --format table --exit-code 1 --severity CRITICAL,HIGH --ignorefile .trivyignore $$dir; \ + done; \ + fi + +security-examples: + @echo "--> Running Security checks on examples" + @if [ -d examples ]; then \ + find examples -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ + echo "--> Validating $$dir"; \ + trivy config --format table --exit-code 1 --severity CRITICAL,HIGH --ignorefile .trivyignore $$dir; \ + done; \ + fi + +tests: + @echo "--> Running Terraform Tests" + @terraform test validate: @echo "--> Running terraform validate" @terraform init -backend=false @terraform validate + $(MAKE) validate-modules + $(MAKE) validate-examples + $(MAKE) validate-commits + +validate-modules: + @echo "--> Running terraform validate on modules" + @if [ -d modules ]; then \ + find modules -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ + echo "--> Validating $$dir"; \ + terraform -chdir=$$dir init -backend=false; \ + terraform -chdir=$$dir validate; \ + done; \ + fi validate-examples: @echo "--> Running terraform validate on examples" - @find examples -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ - echo "--> Validating $$dir"; \ - terraform -chdir=$$dir init; \ - terraform -chdir=$$dir validate; \ - done + @if [ -d examples ]; then \ + find examples -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ + echo "--> Validating $$dir"; \ + terraform -chdir=$$dir init -backend=false; \ + terraform -chdir=$$dir validate; \ + done; \ + fi + +validate-commits: + @echo "--> Running commitlint against the main branch" + @command -v commitlint >/dev/null 2>&1 || { echo "commitlint is not installed. Please install it by running 'npm install -g commitlint'"; exit 1; } + @git log --pretty=format:"%s" origin/main..HEAD | commitlint --from=origin/main lint: @echo "--> Running tflint" @tflint --init @tflint -f compact + $(MAKE) lint-modules + $(MAKE) lint-examples + +lint-modules: + @echo "--> Running tflint on modules" + @if [ -d modules ]; then \ + find modules -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ + echo "--> Linting $$dir"; \ + tflint --chdir=$$dir --init; \ + tflint --chdir=$$dir -f compact; \ + done; \ + fi + +lint-examples: + @echo "--> Running tflint on examples" + @if [ -d examples ]; then \ + find examples -type d -mindepth 1 -maxdepth 1 | while read -r dir; do \ + echo "--> Linting $$dir"; \ + tflint --chdir=$$dir --init; \ + tflint --chdir=$$dir -f compact; \ + done; \ + fi format: @echo "--> Running terraform fmt" diff --git a/README.md b/README.md index 4f3f265..f1de6b2 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,6 @@ The `terraform-docs` utility is used to generate this README. Follow the below s | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [name](#input\_name) | Is the name of the network to provision | `string` | n/a | yes | -| [private\_subnet\_netmask](#input\_private\_subnet\_netmask) | The netmask for the private subnets | `number` | n/a | yes | | [tags](#input\_tags) | Tags to apply to all resources | `map(string)` | n/a | yes | | [additional\_subnets](#input\_additional\_subnets) | Additional subnets to create in the network | `map(any)` | `null` | no | | [availability\_zones](#input\_availability\_zones) | The number of availability zone the network should be deployed into | `number` | `2` | no | @@ -94,11 +93,12 @@ The `terraform-docs` utility is used to generate this README. Follow the below s | [exclude\_route53\_resolver\_rules](#input\_exclude\_route53\_resolver\_rules) | List of resolver rules to exclude from association | `list(string)` | `[]` | no | | [ipam\_pool\_id](#input\_ipam\_pool\_id) | An optional pool id to use for IPAM pool to use | `string` | `null` | no | | [nat\_gateway\_mode](#input\_nat\_gateway\_mode) | The configuration mode of the NAT gateways | `string` | `"none"` | no | +| [private\_subnet\_netmask](#input\_private\_subnet\_netmask) | The netmask for the private subnets | `number` | `0` | no | | [private\_subnet\_tags](#input\_private\_subnet\_tags) | Additional tags for the private subnets | `map(string)` | `{}` | no | | [public\_subnet\_netmask](#input\_public\_subnet\_netmask) | The netmask for the public subnets | `number` | `0` | no | | [public\_subnet\_tags](#input\_public\_subnet\_tags) | Additional tags for the public subnets | `map(string)` | `{}` | no | | [transit\_gateway\_id](#input\_transit\_gateway\_id) | If enabled, and not lookup is disabled, the transit gateway id to connect to | `string` | `""` | no | -| [transit\_gateway\_routes](#input\_transit\_gateway\_routes) | If enabled, this is the cidr block to route down the transit gateway | `map(string)` |
{
"private": "10.0.0.0/8"
}
| no | +| [transit\_gateway\_routes](#input\_transit\_gateway\_routes) | If enabled, this is the cidr block to route down the transit gateway | `map(string)` |
{
"private": "10.0.0.0/8"
}
| no | | [transit\_subnet\_tags](#input\_transit\_subnet\_tags) | Additional tags for the transit subnets | `map(string)` | `{}` | no | | [vpc\_cidr](#input\_vpc\_cidr) | An optional cidr block to assign to the VPC (if not using IPAM) | `string` | `null` | no | | [vpc\_instance\_tenancy](#input\_vpc\_instance\_tenancy) | The name of the VPC to create | `string` | `"default"` | no | diff --git a/examples/basic/README.md b/examples/basic/README.md index dfad1ec..c26e658 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -5,7 +5,6 @@ |------|---------| | [terraform](#requirement\_terraform) | >= 1.0.0 | | [aws](#requirement\_aws) | >= 5.0.0 | -| [awscc](#requirement\_awscc) | >= 0.11.0 | ## Providers @@ -25,19 +24,44 @@ No resources. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [name](#input\_name) | Is the name of the network to provision | `string` | n/a | yes | -| [tags](#input\_tags) | Tags to apply to all resources | `map(string)` | n/a | yes | | [availability\_zones](#input\_availability\_zones) | The number of availability zone the network should be deployed into | `number` | `2` | no | -| [enable\_ipam](#input\_enable\_ipam) | Indicates the cidr block for the network should be assigned from IPAM | `bool` | `true` | no | +| [enable\_ipam](#input\_enable\_ipam) | Indicates the cidr block for the network should be assigned from IPAM | `bool` | `false` | no | | [enable\_ssm](#input\_enable\_ssm) | Indicates we should provision SSM private endpoints | `bool` | `false` | no | -| [enable\_transit\_gateway](#input\_enable\_transit\_gateway) | Indicates the network should provison nat gateways | `bool` | `false` | no | +| [enable\_transit\_gateway](#input\_enable\_transit\_gateway) | Indicates the network should provison nat gateways | `bool` | `true` | no | | [ipam\_pool\_id](#input\_ipam\_pool\_id) | The id of the IPAM pool to use for the network | `string` | `null` | no | +| [name](#input\_name) | Is the name of the network to provision | `string` | `"test-vpc"` | no | | [private\_subnet\_netmask](#input\_private\_subnet\_netmask) | The netmask for the private subnets | `number` | `24` | no | | [public\_subnet\_netmask](#input\_public\_subnet\_netmask) | The netmask for the public subnets | `number` | `0` | no | -| [transit\_gateway\_id](#input\_transit\_gateway\_id) | If enabled, and not lookup is disabled, the transit gateway id to connect to | `string` | `null` | no | -| [vpc\_cidr](#input\_vpc\_cidr) | An optional cidr block to assign to the VPC (if not using IPAM) | `string` | `null` | no | +| [tags](#input\_tags) | Tags to apply to all resources | `map(string)` |
{
"Environment": "test",
"GitRepo": "https://github.com/appvia/terraform-aws-network",
"Terraform": "true"
}
| no | +| [transit\_gateway\_id](#input\_transit\_gateway\_id) | If enabled, and not lookup is disabled, the transit gateway id to connect to | `string` | `"tgw-04ad8f026be8b7eb6"` | no | +| [vpc\_cidr](#input\_vpc\_cidr) | An optional cidr block to assign to the VPC (if not using IPAM) | `string` | `"10.88.0.0/21"` | no | +| [vpc\_netmask](#input\_vpc\_netmask) | The netmask for the VPC when using IPAM | `number` | `null` | no | ## Outputs -No outputs. +| Name | Description | +|------|-------------| +| [nat\_public\_ips](#output\_nat\_public\_ips) | The public IPs of the NAT Gateways i.e [public\_ip, public\_ip] | +| [natgw\_id\_per\_az](#output\_natgw\_id\_per\_az) | The IDs of the NAT Gateways (see aws-ia/vpc/aws for details) | +| [private\_route\_table\_ids](#output\_private\_route\_table\_ids) | The IDs of the private route tables ie. [route\_table\_id, route\_table\_id] | +| [private\_subnet\_attributes\_by\_az](#output\_private\_subnet\_attributes\_by\_az) | The attributes of the private subnets (see aws-ia/vpc/aws for details) | +| [private\_subnet\_cidr\_by\_id](#output\_private\_subnet\_cidr\_by\_id) | A map of the private subnet ID to CIDR block i.e. us-west-2a => subnet\_cidr | +| [private\_subnet\_cidrs](#output\_private\_subnet\_cidrs) | A list of the CIDRs for the private subnets | +| [private\_subnet\_id\_by\_az](#output\_private\_subnet\_id\_by\_az) | A map of availability zone to subnet id of the private subnets i.e. eu-west-2a => subnet\_id | +| [private\_subnet\_ids](#output\_private\_subnet\_ids) | The IDs of the private subnets i.e. [subnet\_id, subnet\_id] | +| [public\_route\_table\_ids](#output\_public\_route\_table\_ids) | The IDs of the public route tables ie. [route\_table\_id, route\_table\_id] | +| [public\_subnet\_attributes\_by\_az](#output\_public\_subnet\_attributes\_by\_az) | The attributes of the public subnets (see aws-ia/vpc/aws for details) | +| [public\_subnet\_cidr\_by\_id](#output\_public\_subnet\_cidr\_by\_id) | A map of the public subnet ID to CIDR block i.e. us-west-2a => subnet\_cidr | +| [public\_subnet\_cidrs](#output\_public\_subnet\_cidrs) | A list of the CIDRs for the public subnets i.e. [subnet\_cidr, subnet\_cidr] | +| [public\_subnet\_id\_by\_az](#output\_public\_subnet\_id\_by\_az) | A map of availability zone to subnet id of the public subnets i.e. eu-west-2a => subnet\_id | +| [public\_subnet\_ids](#output\_public\_subnet\_ids) | The IDs of the public subnets i.e. [subnet\_id, subnet\_id] | +| [rt\_attributes\_by\_type\_by\_az](#output\_rt\_attributes\_by\_type\_by\_az) | The attributes of the route tables (see aws-ia/vpc/aws for details) | +| [transit\_gateway\_attachment\_id](#output\_transit\_gateway\_attachment\_id) | The ID of the transit gateway attachment if enabled | +| [transit\_route\_table\_by\_az](#output\_transit\_route\_table\_by\_az) | A map of availability zone to transit gateway route table ID i.e eu-west-2a => route\_table\_id | +| [transit\_route\_table\_ids](#output\_transit\_route\_table\_ids) | The IDs of the transit gateway route tables ie. [route\_table\_id, route\_table\_id] | +| [transit\_subnet\_attributes\_by\_az](#output\_transit\_subnet\_attributes\_by\_az) | The attributes of the transit gateway subnets (see aws-ia/vpc/aws for details) | +| [transit\_subnet\_ids](#output\_transit\_subnet\_ids) | The IDs of the transit gateway subnets ie. [subnet\_id, subnet\_id] | +| [vpc\_attributes](#output\_vpc\_attributes) | The attributes of the VPC (see aws-ia/vpc/aws for details) | +| [vpc\_cidr](#output\_vpc\_cidr) | The CIDR block of the VPC | +| [vpc\_id](#output\_vpc\_id) | The ID of the VPC | \ No newline at end of file diff --git a/variables.tf b/variables.tf index 22998cb..6bc4b14 100644 --- a/variables.tf +++ b/variables.tf @@ -101,11 +101,7 @@ variable "nat_gateway_mode" { variable "private_subnet_netmask" { description = "The netmask for the private subnets" type = number - - validation { - condition = var.private_subnet_netmask > 0 && var.private_subnet_netmask <= 28 - error_message = "private_subnet_netmask must be between 1 and 28" - } + default = 0 } variable "public_subnet_netmask" {