├── VERSION ├── .github ├── CODEOWNERS ├── dependabot.yml ├── workflows │ ├── yaml.integration.yaml │ ├── github.repo.yaml │ ├── github.pr.yaml │ └── terraform.integration.yaml ├── auto-assign.yaml ├── labeler.yaml ├── labels.yaml └── labels.common.yaml ├── examples ├── nlb-with-ip-target-group │ ├── outputs.tf │ ├── versions.tf │ └── main.tf ├── gwlb-with-ip-target-group │ ├── outputs.tf │ ├── versions.tf │ └── main.tf ├── nlb-with-instance-target-group │ ├── outputs.tf │ ├── versions.tf │ └── main.tf ├── gwlb-with-instance-target-group │ ├── outputs.tf │ ├── versions.tf │ └── main.tf ├── nlb-with-alb-target-group │ ├── outputs.tf │ ├── versions.tf │ ├── main.tf │ └── alb.tf ├── alb-with-ip-target-group │ ├── versions.tf │ ├── outputs.tf │ └── main.tf └── alb-with-instance-target-group │ ├── versions.tf │ ├── outputs.tf │ └── main.tf ├── modules ├── gwlb │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── outputs.tf │ ├── main.tf │ ├── variables.tf │ └── README.md ├── nlb │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── security-groups.tf │ ├── outputs.tf │ └── main.tf ├── alb-listener │ ├── migrations.tf │ ├── versions.tf │ └── resource-group.tf ├── nlb-listener │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── outputs.tf │ ├── main.tf │ ├── variables.tf │ └── README.md ├── alb-ip-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── outputs.tf │ └── main.tf ├── gwlb-ip-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── outputs.tf │ ├── main.tf │ └── variables.tf ├── nlb-alb-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── nlb-ip-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── outputs.tf │ └── main.tf ├── alb-instance-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── main.tf │ └── outputs.tf ├── alb-lambda-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── outputs.tf │ ├── main.tf │ └── variables.tf ├── gwlb-instance-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── outputs.tf │ ├── main.tf │ ├── variables.tf │ └── README.md ├── nlb-instance-target-group │ ├── migrations.tf │ ├── versions.tf │ ├── resource-group.tf │ ├── main.tf │ └── outputs.tf └── alb │ ├── versions.tf │ ├── migrations.tf │ ├── resource-group.tf │ ├── security-group.tf │ ├── outputs.tf │ └── main.tf ├── .editorconfig ├── .pre-commit-config.yaml ├── .yamllint.yaml ├── .gitignore ├── .tflint.hcl └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 1.4.0 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @posquit0 2 | -------------------------------------------------------------------------------- /examples/nlb-with-ip-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "nlb" { 2 | value = module.nlb 3 | } 4 | 5 | output "target_group" { 6 | value = module.target_group 7 | } 8 | -------------------------------------------------------------------------------- /examples/gwlb-with-ip-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "gwlb" { 2 | value = module.gwlb 3 | } 4 | 5 | output "target_group" { 6 | value = module.target_group 7 | } 8 | -------------------------------------------------------------------------------- /examples/nlb-with-instance-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "nlb" { 2 | value = module.nlb 3 | } 4 | 5 | output "target_group" { 6 | value = module.target_group 7 | } 8 | -------------------------------------------------------------------------------- /examples/gwlb-with-instance-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "gwlb" { 2 | value = module.gwlb 3 | } 4 | 5 | output "target_group" { 6 | value = module.target_group 7 | } 8 | -------------------------------------------------------------------------------- /modules/gwlb/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/nlb/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/alb-listener/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/nlb-listener/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/alb-ip-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/gwlb-ip-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/nlb-alb-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/nlb-ip-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/alb-instance-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/alb-lambda-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/gwlb-instance-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/nlb-instance-target-group/migrations.tf: -------------------------------------------------------------------------------- 1 | # 2022-10-20 2 | moved { 3 | from = aws_resourcegroups_group.this[0] 4 | to = module.resource_group[0].aws_resourcegroups_group.this 5 | } 6 | -------------------------------------------------------------------------------- /modules/alb/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.30" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/gwlb/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.30" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/nlb/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.30" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/alb-listener/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.30" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/nlb-listener/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.30" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/nlb-with-alb-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "nlb" { 2 | value = module.nlb 3 | } 4 | 5 | output "alb" { 6 | value = module.alb 7 | } 8 | 9 | output "target_group" { 10 | value = module.target_group 11 | } 12 | -------------------------------------------------------------------------------- /modules/alb-ip-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/nlb-ip-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/alb-with-ip-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 5.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/nlb-with-ip-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 5.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/alb-lambda-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/gwlb-ip-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/nlb-alb-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/gwlb-with-ip-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 5.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/nlb-with-alb-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 5.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/alb-instance-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/gwlb-instance-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /modules/nlb-instance-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = ">= 5.38" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/alb-with-instance-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 5.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/alb-with-ip-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "alb" { 2 | value = module.alb 3 | } 4 | 5 | output "target_group" { 6 | value = { 7 | alpha = module.target_group_alpha 8 | beta = module.target_group_beta 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/gwlb-with-instance-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 5.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/nlb-with-instance-target-group/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.6" 3 | 4 | required_providers { 5 | aws = { 6 | source = "hashicorp/aws" 7 | version = "~> 5.0" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/alb-with-instance-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "alb" { 2 | value = module.alb 3 | } 4 | 5 | output "target_groups" { 6 | value = { 7 | alpha = module.target_group_alpha 8 | beta = module.target_group_beta 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: github-actions 5 | directory: / 6 | schedule: 7 | interval: daily 8 | 9 | - package-ecosystem: terraform 10 | directories: 11 | - /modules/* 12 | schedule: 13 | interval: weekly 14 | -------------------------------------------------------------------------------- /modules/alb/migrations.tf: -------------------------------------------------------------------------------- 1 | # INFO: 2023-12-11 - Make optional `security_group` module 2 | moved { 3 | from = module.security_group 4 | to = module.security_group[0] 5 | } 6 | 7 | # 2022-10-20 8 | moved { 9 | from = aws_resourcegroups_group.this[0] 10 | to = module.resource_group[0].aws_resourcegroups_group.this 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.{tf,tfvars}] 13 | indent_size = 2 14 | indent_style = space 15 | 16 | [.gitignore] 17 | end_of_line = 18 | -------------------------------------------------------------------------------- /.github/workflows/yaml.integration.yaml: -------------------------------------------------------------------------------- 1 | name: Integration - YAML 2 | 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - "**.yaml" 10 | - "**.yml" 11 | 12 | pull_request: 13 | paths: 14 | - "**.yaml" 15 | - "**.yml" 16 | 17 | workflow_dispatch: {} 18 | 19 | 20 | concurrency: 21 | group: integration-yaml-${{ github.ref }} 22 | cancel-in-progress: true 23 | 24 | 25 | jobs: 26 | lint: 27 | name: Lint (yamllint) 28 | uses: tedilabs/github-actions/.github/workflows/yaml.yamllint.yaml@main 29 | 30 | with: 31 | yamllint_version: latest 32 | yamllint_config_file: .yamllint.yaml 33 | yamllint_target_dir: ./ 34 | secrets: 35 | token: ${{ secrets.GITHUB_TOKEN }} 36 | -------------------------------------------------------------------------------- /modules/alb/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/gwlb/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/nlb/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/alb-listener/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/nlb-listener/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/alb-ip-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/gwlb-ip-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/nlb-alb-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/nlb-ip-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/alb-instance-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/alb-lambda-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/nlb-instance-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /modules/gwlb-instance-target-group/resource-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | resource_group_name = (var.resource_group.name != "" 3 | ? var.resource_group.name 4 | : join(".", [ 5 | local.metadata.package, 6 | local.metadata.module, 7 | replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), 8 | ]) 9 | ) 10 | } 11 | 12 | 13 | module "resource_group" { 14 | source = "tedilabs/misc/aws//modules/resource-group" 15 | version = "~> 0.12.0" 16 | 17 | count = (var.resource_group.enabled && var.module_tags_enabled) ? 1 : 0 18 | 19 | name = local.resource_group_name 20 | description = var.resource_group.description 21 | 22 | query = { 23 | resource_tags = local.module_tags 24 | } 25 | 26 | module_tags_enabled = false 27 | tags = merge( 28 | local.module_tags, 29 | var.tags, 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/github.repo.yaml: -------------------------------------------------------------------------------- 1 | name: GitHub - Repository 2 | 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - .github/labels*.yaml 10 | - .github/workflows/github.repo.yaml 11 | 12 | pull_request: 13 | paths: 14 | - .github/labels*.yaml 15 | - .github/workflows/github.repo.yaml 16 | 17 | workflow_dispatch: {} 18 | 19 | 20 | jobs: 21 | sync-labels: 22 | name: Sync Labels 23 | strategy: 24 | matrix: 25 | config_file: 26 | - .github/labels.yaml 27 | - .github/labels.common.yaml 28 | uses: tedilabs/github-actions/.github/workflows/github.repo.sync-labels.yaml@main 29 | 30 | permissions: 31 | contents: read 32 | issues: write 33 | 34 | with: 35 | config_file: ${{ matrix.config_file }} 36 | skip_delete: true 37 | dry_run: ${{ github.event_name == 'pull_request' }} 38 | secrets: 39 | token: ${{ secrets.GITHUB_TOKEN }} 40 | -------------------------------------------------------------------------------- /.github/auto-assign.yaml: -------------------------------------------------------------------------------- 1 | runOnDraft: false 2 | # A list of keywords to be skipped the process that add reviewers if pull requests include it 3 | skipKeywords: 4 | - wip 5 | 6 | # Set to true to add reviewers to pull requests 7 | addReviewers: true 8 | # A number of reviewers added to the pull request 9 | # Set 0 to add all the reviewers (default: 0) 10 | numberOfReviewers: 1 11 | useReviewGroups: true 12 | reviewGroups: 13 | owners: 14 | - posquit0 15 | maintainers: 16 | - posquit0 17 | 18 | # true: Add assignees to pull requests 19 | # 'author': Set the PR creator as the assignee. 20 | addAssignees: 'author' 21 | # A number of assignees to add to the pull request 22 | # Set to 0 to add all of the assignees. 23 | # Uses numberOfReviewers if unset. 24 | # numberOfAssignees: 2 25 | useAssigneeGroups: false 26 | # assigneeGroups: 27 | # groupA: 28 | # - assigneeA 29 | # - assigneeB 30 | # - assigneeC 31 | # groupB: 32 | # - assigneeD 33 | # - assigneeE 34 | # - assigneeF 35 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_install_hook_types: 2 | - pre-commit 3 | - commit-msg 4 | 5 | repos: 6 | - repo: https://github.com/antonbabenko/pre-commit-terraform 7 | rev: v1.104.0 8 | hooks: 9 | - id: terraform_fmt 10 | name: (terraform) Format .tf files with `terraform fmt` 11 | args: 12 | - --args=-diff 13 | - id: terraform_validate 14 | name: (terraform) Check with `terraform validate` 15 | args: 16 | - --hook-config=--retry-once-with-cleanup=true 17 | - --tf-init-args=-upgrade 18 | - id: terraform_tflint 19 | name: (terraform) Check with `tflint` 20 | args: 21 | - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl 22 | files: ^modules/ 23 | - id: terraform_docs 24 | name: (terraform) Generate docs with `terraform-docs` 25 | args: ["--args=--sort-by required"] 26 | 27 | - repo: https://github.com/pre-commit/pre-commit-hooks 28 | rev: v6.0.0 29 | hooks: 30 | - id: trailing-whitespace 31 | 32 | - repo: https://github.com/adrienverge/yamllint 33 | rev: v1.37.1 34 | hooks: 35 | - id: yamllint 36 | name: (yaml) Check with `yamllint` 37 | 38 | - repo: https://github.com/compilerla/conventional-pre-commit 39 | rev: v4.3.0 40 | hooks: 41 | - id: conventional-pre-commit 42 | name: (commit-message) Check conventional commit 43 | stages: [commit-msg] 44 | args: [] 45 | -------------------------------------------------------------------------------- /.yamllint.yaml: -------------------------------------------------------------------------------- 1 | yaml-files: 2 | - '*.yaml' 3 | - '*.yml' 4 | 5 | rules: 6 | braces: 7 | min-spaces-inside: 0 8 | max-spaces-inside: 1 9 | min-spaces-inside-empty: 0 10 | max-spaces-inside-empty: 0 11 | brackets: 12 | min-spaces-inside: 0 13 | max-spaces-inside: 1 14 | min-spaces-inside-empty: 0 15 | max-spaces-inside-empty: 0 16 | colons: 17 | max-spaces-before: 0 18 | max-spaces-after: 1 19 | commas: 20 | max-spaces-before: 0 21 | comments: 22 | level: warning 23 | require-starting-space: true 24 | min-spaces-from-content: 1 25 | comments-indentation: disable 26 | document-end: disable 27 | document-start: disable 28 | empty-lines: 29 | level: warning 30 | max: 2 31 | max-start: 0 32 | max-end: 1 33 | empty-values: 34 | forbid-in-block-mappings: true 35 | forbid-in-flow-mappings: true 36 | hyphens: 37 | max-spaces-after: 1 38 | indentation: 39 | spaces: consistent 40 | indent-sequences: false 41 | key-duplicates: enable 42 | key-ordering: disable 43 | line-length: disable 44 | new-line-at-end-of-file: enable 45 | # Use UNIX new line characters `\n` instead of DOS new line characters `\r\n` 46 | new-lines: 47 | type: unix 48 | octal-values: disable 49 | quoted-strings: 50 | quote-type: any 51 | required: false 52 | trailing-spaces: enable 53 | truthy: disable 54 | -------------------------------------------------------------------------------- /.github/workflows/github.pr.yaml: -------------------------------------------------------------------------------- 1 | name: GitHub - Pull Request 2 | 3 | 4 | on: 5 | pull_request_target: {} 6 | 7 | 8 | jobs: 9 | auto-assign: 10 | name: Auto Assign 11 | uses: tedilabs/github-actions/.github/workflows/github.pr.auto-assign.yaml@main 12 | if: ${{ github.event_name == 'pull_request_target' }} 13 | 14 | permissions: 15 | contents: read 16 | pull-requests: write 17 | 18 | with: 19 | config_file: .github/auto-assign.yaml 20 | secrets: 21 | token: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | auto-label: 24 | name: Auto Label 25 | uses: tedilabs/github-actions/.github/workflows/github.pr.auto-label.yaml@main 26 | if: ${{ github.event_name == 'pull_request_target' }} 27 | 28 | permissions: 29 | contents: read 30 | issues: write 31 | pull-requests: write 32 | 33 | with: 34 | labeler_config_file: .github/labeler.yaml 35 | labeler_dot_included: true 36 | labeler_sync_labels: true 37 | pr_size_xs_label: 'size/XS' 38 | pr_size_s_label: 'size/S' 39 | pr_size_m_label: 'size/M' 40 | pr_size_l_label: 'size/L' 41 | pr_size_xl_label: 'size/XL' 42 | secrets: 43 | token: ${{ secrets.GITHUB_TOKEN }} 44 | 45 | welcome: 46 | name: Welcome for First Pull Request 47 | uses: tedilabs/github-actions/.github/workflows/github.issue.welcome.yaml@main 48 | if: ${{ github.event_name == 'pull_request_target' && github.event.action == 'opened' }} 49 | 50 | secrets: 51 | token: ${{ secrets.GITHUB_TOKEN }} 52 | -------------------------------------------------------------------------------- /.github/labeler.yaml: -------------------------------------------------------------------------------- 1 | # Modules 2 | ":floppy_disk: alb": 3 | - changed-files: 4 | - any-glob-to-any-file: 5 | - modules/alb/**/* 6 | 7 | ":floppy_disk: nlb": 8 | - changed-files: 9 | - any-glob-to-any-file: 10 | - modules/nlb/**/* 11 | 12 | ":floppy_disk: gwlb": 13 | - changed-files: 14 | - any-glob-to-any-file: 15 | - modules/gwlb/**/* 16 | 17 | ":floppy_disk: alb-listener": 18 | - changed-files: 19 | - any-glob-to-any-file: 20 | - modules/alb-listener/**/* 21 | 22 | ":floppy_disk: nlb-listener": 23 | - changed-files: 24 | - any-glob-to-any-file: 25 | - modules/nlb-listener/**/* 26 | 27 | ":floppy_disk: alb-instance-target-group": 28 | - changed-files: 29 | - any-glob-to-any-file: 30 | - modules/alb-instance-target-group/**/* 31 | 32 | ":floppy_disk: alb-ip-target-group": 33 | - changed-files: 34 | - any-glob-to-any-file: 35 | - modules/alb-ip-target-group/**/* 36 | 37 | ":floppy_disk: alb-lambda-target-group": 38 | - changed-files: 39 | - any-glob-to-any-file: 40 | - modules/alb-lambda-target-group/**/* 41 | 42 | ":floppy_disk: nlb-instance-target-group": 43 | - changed-files: 44 | - any-glob-to-any-file: 45 | - modules/nlb-instance-target-group/**/* 46 | 47 | ":floppy_disk: nlb-ip-target-group": 48 | - changed-files: 49 | - any-glob-to-any-file: 50 | - modules/nlb-ip-target-group/**/* 51 | 52 | ":floppy_disk: nlb-alb-target-group": 53 | - changed-files: 54 | - any-glob-to-any-file: 55 | - modules/nlb-alb-target-group/**/* 56 | 57 | ":floppy_disk: gwlb-instance-target-group": 58 | - changed-files: 59 | - any-glob-to-any-file: 60 | - modules/gwlb-instance-target-group/**/* 61 | 62 | ":floppy_disk: gwlb-ip-target-group": 63 | - changed-files: 64 | - any-glob-to-any-file: 65 | - modules/gwlb-ip-target-group/**/* 66 | -------------------------------------------------------------------------------- /.github/labels.yaml: -------------------------------------------------------------------------------- 1 | # Warning 2 | - color: "ee0701" 3 | description: "Categorize to note any change that requires extra attention." 4 | name: ":warning: breaking change" 5 | - color: "ee0701" 6 | description: "Categorize bug reports." 7 | name: ":warning: bug" 8 | - color: "ee0701" 9 | description: "Categorize vulnerability reports." 10 | name: ":warning: vulnerability" 11 | 12 | # Task Types 13 | - color: "1d76db" 14 | description: "Improvements or additions to documentation." 15 | name: ":pencil2: documentation" 16 | - color: "1d76db" 17 | description: "A new feature of the project." 18 | name: ":pencil2: feature" 19 | - color: "1d76db" 20 | description: "Any dependency updates, housekeeping, or maintenance work." 21 | name: ":pencil2: maintenance" 22 | 23 | # Highlight 24 | - color: "0e8a16" 25 | description: "Good for newcomers." 26 | name: ":fire: good first issue" 27 | - color: "0e8a16" 28 | description: "Extra attention is needed." 29 | name: ":fire: help wanted" 30 | 31 | # Cancel 32 | - color: "b60205" 33 | description: "This issue or pull request already exists." 34 | name: ":pray: duplicate" 35 | - color: "b60205" 36 | description: "This issue or pull request is invalid." 37 | name: ":pray: invalid" 38 | - color: "b60205" 39 | description: "This will not be worked on." 40 | name: ":pray: wontfix" 41 | 42 | # Size 43 | - color: "cfd3d7" 44 | description: "Extra Small size issue or PR." 45 | name: "size/XS" 46 | - color: "cfd3d7" 47 | description: "Small size issue or PR." 48 | name: "size/S" 49 | - color: "cfd3d7" 50 | description: "Medium size issue or PR." 51 | name: "size/M" 52 | - color: "cfd3d7" 53 | description: "Large size issue or PR." 54 | name: "size/L" 55 | - color: "cfd3d7" 56 | description: "Extra Large size issue or PR." 57 | name: "size/XL" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### OSX ### 2 | # General 3 | .DS_Store 4 | .AppleDouble 5 | .LSOverride 6 | 7 | # Icon must end with two \r 8 | Icon 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear in the root of a volume 14 | .DocumentRevisions-V100 15 | .fseventsd 16 | .Spotlight-V100 17 | .TemporaryItems 18 | .Trashes 19 | .VolumeIcon.icns 20 | .com.apple.timemachine.donotpresent 21 | 22 | # Directories potentially created on remote AFP share 23 | .AppleDB 24 | .AppleDesktop 25 | Network Trash Folder 26 | Temporary Items 27 | .apdisk 28 | 29 | 30 | ### Terraform ### 31 | # Lock file 32 | .terraform.lock.hcl 33 | 34 | # Local .terraform directories 35 | **/.terraform/* 36 | 37 | # .tfstate files 38 | *.tfstate 39 | *.tfstate.* 40 | 41 | # Crash log files 42 | crash.log 43 | 44 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 45 | # .tfvars files are managed as part of configuration and so should be included in 46 | # version control. 47 | # 48 | # example.tfvars 49 | 50 | # Ignore override files as they are usually used to override resources locally and so 51 | # are not checked in 52 | override.tf 53 | override.tf.json 54 | *_override.tf 55 | *_override.tf.json 56 | 57 | # Include override files you do wish to add to version control using negated pattern 58 | # !example_override.tf 59 | 60 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 61 | # example: *tfplan* 62 | 63 | 64 | ### Vim ### 65 | # Swap 66 | [._]*.s[a-v][a-z] 67 | !*.svg # comment out if you don't need vector files 68 | [._]*.sw[a-p] 69 | [._]s[a-rt-v][a-z] 70 | [._]ss[a-gi-z] 71 | [._]sw[a-p] 72 | 73 | # Session 74 | Session.vim 75 | Sessionx.vim 76 | 77 | # Temporary 78 | .netrwhist 79 | *~ 80 | # Auto-generated tag files 81 | tags 82 | # Persistent undo 83 | [._]*.un~ 84 | -------------------------------------------------------------------------------- /modules/nlb-listener/outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | description = "The Amazon Resource Name (ARN) of the listener." 3 | value = aws_lb_listener.this.arn 4 | } 5 | 6 | output "id" { 7 | description = "The ID of the listener." 8 | value = aws_lb_listener.this.id 9 | } 10 | 11 | output "name" { 12 | description = "The name of the listener." 13 | value = local.metadata.name 14 | } 15 | 16 | output "port" { 17 | description = "The port number on which the listener of load balancer is listening." 18 | value = aws_lb_listener.this.port 19 | } 20 | 21 | output "protocol" { 22 | description = "The protocol for connections of the listener." 23 | value = aws_lb_listener.this.protocol 24 | } 25 | 26 | output "default_action" { 27 | description = "The default action for traffic on this listener." 28 | value = { 29 | type = "FORWARD" 30 | forward = { 31 | arn = var.target_group 32 | name = split("/", var.target_group)[1] 33 | } 34 | } 35 | } 36 | 37 | output "tls" { 38 | description = "TLS configurations of the listener." 39 | value = local.tls_enabled ? { 40 | certificate = aws_lb_listener.this.certificate_arn 41 | additional_certificates = [ 42 | for certificate in values(aws_lb_listener_certificate.this) : 43 | certificate.certificate_arn 44 | ] 45 | security_policy = aws_lb_listener.this.ssl_policy 46 | alpn_policy = aws_lb_listener.this.alpn_policy 47 | } : null 48 | } 49 | 50 | output "resource_group" { 51 | description = "The resource group created to manage resources in this module." 52 | value = merge( 53 | { 54 | enabled = var.resource_group.enabled && var.module_tags_enabled 55 | }, 56 | (var.resource_group.enabled && var.module_tags_enabled 57 | ? { 58 | arn = module.resource_group[0].arn 59 | name = module.resource_group[0].name 60 | } 61 | : {} 62 | ) 63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /examples/gwlb-with-ip-target-group/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | 6 | data "aws_vpc" "default" { 7 | default = true 8 | } 9 | 10 | data "aws_subnet" "default" { 11 | for_each = toset(["use1-az1", "use1-az2"]) 12 | 13 | availability_zone_id = each.key 14 | default_for_az = true 15 | } 16 | 17 | 18 | ################################################### 19 | # Gateway Load Balancer 20 | ################################################### 21 | 22 | module "gwlb" { 23 | source = "../../modules/gwlb" 24 | # source = "tedilabs/load-balancer/aws//modules/gwlb" 25 | # version = "~> 1.0.0" 26 | 27 | name = "tedilabs-gwlb-ip" 28 | network_mapping = { 29 | for az, subnet in data.aws_subnet.default : 30 | az => { 31 | subnet = subnet.id 32 | } 33 | } 34 | 35 | ## Attributes 36 | cross_zone_load_balancing_enabled = true 37 | deletion_protection_enabled = false 38 | 39 | listeners = [{ 40 | port = 6081 41 | target_group = module.target_group.arn 42 | }] 43 | 44 | tags = { 45 | "project" = "terraform-aws-load-balancer-examples" 46 | } 47 | } 48 | 49 | 50 | ################################################### 51 | # IP Target Group for Gateway Load Balancer 52 | ################################################### 53 | 54 | module "target_group" { 55 | source = "../../modules/gwlb-ip-target-group" 56 | # source = "tedilabs/load-balancer/aws//modules/gwlb-ip-target-group" 57 | # version = "~> 1.0.0" 58 | 59 | name = "tedilabs-gwlb-ip-tg" 60 | 61 | vpc_id = data.aws_vpc.default.id 62 | 63 | targets = [ 64 | { 65 | ip_address = "10.234.123.8" 66 | }, 67 | ] 68 | 69 | health_check = { 70 | protocol = "TCP" 71 | port = 80 72 | port_override = true 73 | path = "/" 74 | 75 | interval = 10 76 | timeout = 5 77 | healthy_threshold = 3 78 | unhealthy_threshold = 3 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/gwlb-with-instance-target-group/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | 6 | data "aws_vpc" "default" { 7 | default = true 8 | } 9 | 10 | data "aws_subnet" "default" { 11 | for_each = toset(["use1-az1", "use1-az2"]) 12 | 13 | availability_zone_id = each.key 14 | default_for_az = true 15 | } 16 | 17 | 18 | ################################################### 19 | # Gateway Load Balancer 20 | ################################################### 21 | 22 | module "gwlb" { 23 | source = "../../modules/gwlb" 24 | # source = "tedilabs/load-balancer/aws//modules/gwlb" 25 | # version = "~> 1.0.0" 26 | 27 | name = "tedilabs-gwlb-instance" 28 | network_mapping = { 29 | for az, subnet in data.aws_subnet.default : 30 | az => { 31 | subnet = subnet.id 32 | } 33 | } 34 | 35 | ## Attributes 36 | cross_zone_load_balancing_enabled = true 37 | deletion_protection_enabled = false 38 | 39 | listeners = [{ 40 | port = 6081 41 | target_group = module.target_group.arn 42 | }] 43 | 44 | tags = { 45 | "project" = "terraform-aws-load-balancer-examples" 46 | } 47 | } 48 | 49 | 50 | ################################################### 51 | # Instance Target Group for Gateway Load Balancer 52 | ################################################### 53 | 54 | module "target_group" { 55 | source = "../../modules/gwlb-instance-target-group" 56 | # source = "tedilabs/load-balancer/aws//modules/gwlb-instance-target-group" 57 | # version = "~> 1.0.0" 58 | 59 | name = "tedilabs-gwlb-instance-tg" 60 | 61 | vpc_id = data.aws_vpc.default.id 62 | 63 | targets = [ 64 | # { 65 | # instance = "i-xxxx" 66 | # }, 67 | ] 68 | 69 | health_check = { 70 | protocol = "HTTP" 71 | port = 80 72 | port_override = true 73 | path = "/health" 74 | 75 | interval = 10 76 | timeout = 5 77 | healthy_threshold = 3 78 | unhealthy_threshold = 3 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /modules/nlb-listener/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = "${local.load_balancer_name}/${var.protocol}:${var.port}" 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | locals { 18 | load_balancer_name = split("/", var.load_balancer)[2] 19 | tls_enabled = var.protocol == "TLS" 20 | } 21 | 22 | 23 | ################################################### 24 | # NLB Listener 25 | ################################################### 26 | 27 | resource "aws_lb_listener" "this" { 28 | load_balancer_arn = var.load_balancer 29 | 30 | port = var.port 31 | protocol = var.protocol 32 | 33 | ## TLS 34 | certificate_arn = local.tls_enabled ? var.tls.certificate : null 35 | ssl_policy = local.tls_enabled ? var.tls.security_policy : null 36 | alpn_policy = local.tls_enabled ? var.tls.alpn_policy : null 37 | 38 | default_action { 39 | type = "forward" 40 | target_group_arn = var.target_group 41 | } 42 | 43 | tags = merge( 44 | { 45 | "Name" = local.metadata.name 46 | }, 47 | local.module_tags, 48 | var.tags, 49 | ) 50 | } 51 | 52 | 53 | ################################################### 54 | # Additional Certificates for Listeners 55 | ################################################### 56 | 57 | resource "aws_lb_listener_certificate" "this" { 58 | for_each = toset(local.tls_enabled ? var.tls.additional_certificates : []) 59 | 60 | listener_arn = aws_lb_listener.this.arn 61 | certificate_arn = each.key 62 | } 63 | -------------------------------------------------------------------------------- /.github/labels.common.yaml: -------------------------------------------------------------------------------- 1 | # Warning 2 | - color: "ee0701" 3 | description: "Categorize to note any change that requires extra attention." 4 | name: ":warning: breaking change" 5 | - color: "ee0701" 6 | description: "Categorize bug reports." 7 | name: ":warning: bug" 8 | from_name: "bug" 9 | - color: "ee0701" 10 | description: "Categorize vulnerability reports." 11 | name: ":warning: vulnerability" 12 | 13 | # Task Types 14 | - color: "1d76db" 15 | description: "Improvements or additions to documentation." 16 | name: ":pencil2: documentation" 17 | from_name: "documentation" 18 | - color: "1d76db" 19 | description: "A new feature of the project." 20 | name: ":pencil2: feature" 21 | from_name: "enhancement" 22 | - color: "1d76db" 23 | description: "Any dependency updates, housekeeping, or maintenance work." 24 | name: ":pencil2: maintenance" 25 | 26 | # Highlight 27 | - color: "0e8a16" 28 | description: "Good for newcomers." 29 | name: ":fire: good first issue" 30 | from_name: "good first issue" 31 | - color: "0e8a16" 32 | description: "Extra attention is needed." 33 | name: ":fire: help wanted" 34 | from_name: "help wanted" 35 | 36 | # Cancel 37 | - color: "b60205" 38 | description: "This issue or pull request already exists." 39 | name: ":pray: duplicate" 40 | from_name: "duplicate" 41 | - color: "b60205" 42 | description: "This issue or pull request is invalid." 43 | name: ":pray: invalid" 44 | from_name: "invalid" 45 | - color: "b60205" 46 | description: "This will not be worked on." 47 | name: ":pray: wontfix" 48 | from_name: "wontfix" 49 | 50 | # Size 51 | - color: "cfd3d7" 52 | description: "Extra Small size issue or PR." 53 | name: "size/XS" 54 | - color: "cfd3d7" 55 | description: "Small size issue or PR." 56 | name: "size/S" 57 | - color: "cfd3d7" 58 | description: "Medium size issue or PR." 59 | name: "size/M" 60 | - color: "cfd3d7" 61 | description: "Large size issue or PR." 62 | name: "size/L" 63 | - color: "cfd3d7" 64 | description: "Extra Large size issue or PR." 65 | name: "size/XL" 66 | -------------------------------------------------------------------------------- /modules/alb/security-group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | security_groups = concat( 3 | (var.default_security_group.enabled 4 | ? module.security_group[*].id 5 | : [] 6 | ), 7 | var.security_groups, 8 | ) 9 | } 10 | 11 | 12 | ################################################### 13 | # Security Group for Application Load Balancer 14 | ################################################### 15 | 16 | module "security_group" { 17 | source = "tedilabs/network/aws//modules/security-group" 18 | version = "~> 0.32.0" 19 | 20 | count = var.default_security_group.enabled ? 1 : 0 21 | 22 | name = coalesce(var.default_security_group.name, local.metadata.name) 23 | description = var.default_security_group.description 24 | vpc_id = values(data.aws_subnet.this)[0].vpc_id 25 | 26 | ingress_rules = concat( 27 | var.default_security_group.ingress_rules, 28 | [ 29 | for listener in var.listeners : { 30 | id = "listener-${listener.port}" 31 | description = "Default rule for the load balancer listener." 32 | protocol = "tcp" 33 | from_port = listener.port 34 | to_port = listener.port 35 | 36 | ipv4_cidrs = var.default_security_group.listener_ingress_ipv4_cidrs 37 | ipv6_cidrs = var.default_security_group.listener_ingress_ipv6_cidrs 38 | prefix_lists = var.default_security_group.listener_ingress_prefix_lists 39 | security_groups = var.default_security_group.listener_ingress_security_groups 40 | } 41 | if anytrue([ 42 | length(var.default_security_group.listener_ingress_ipv4_cidrs) > 0, 43 | length(var.default_security_group.listener_ingress_ipv6_cidrs) > 0, 44 | length(var.default_security_group.listener_ingress_prefix_lists) > 0, 45 | length(var.default_security_group.listener_ingress_security_groups) > 0, 46 | ]) 47 | ] 48 | ) 49 | egress_rules = concat( 50 | var.default_security_group.egress_rules, 51 | # TODO: Limit egress rules 52 | # TODO: Target Ports 53 | # TODO: Target Health Check Ports 54 | ) 55 | 56 | revoke_rules_on_delete = true 57 | resource_group_enabled = false 58 | module_tags_enabled = false 59 | 60 | tags = merge( 61 | local.module_tags, 62 | var.tags, 63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /.tflint.hcl: -------------------------------------------------------------------------------- 1 | config { 2 | plugin_dir = "~/.tflint.d/plugins" 3 | 4 | format = "compact" 5 | call_module_type = "local" 6 | force = false 7 | disabled_by_default = false 8 | 9 | ignore_module = {} 10 | } 11 | 12 | 13 | ################################################### 14 | # Rule Sets - Terraform 15 | ################################################### 16 | 17 | plugin "terraform" { 18 | enabled = true 19 | preset = "recommended" 20 | } 21 | 22 | rule "terraform_comment_syntax" { 23 | enabled = true 24 | } 25 | 26 | rule "terraform_documented_variables" { 27 | enabled = true 28 | } 29 | 30 | rule "terraform_documented_outputs" { 31 | enabled = true 32 | } 33 | 34 | rule "terraform_naming_convention" { 35 | enabled = true 36 | format = "snake_case" 37 | 38 | custom_formats = { 39 | extended_snake_case = { 40 | description = "Extended snake_case Format which allows double underscore like `a__b`." 41 | regex = "^[a-z][a-z0-9]+([_]{1,2}[a-z0-9]+)*$" 42 | } 43 | } 44 | 45 | module { 46 | format = "extended_snake_case" 47 | } 48 | 49 | resource { 50 | format = "extended_snake_case" 51 | } 52 | 53 | data { 54 | format = "extended_snake_case" 55 | } 56 | 57 | locals { 58 | format = "extended_snake_case" 59 | } 60 | 61 | variable { 62 | format = "extended_snake_case" 63 | } 64 | 65 | output { 66 | format = "extended_snake_case" 67 | } 68 | 69 | check { 70 | format = "extended_snake_case" 71 | } 72 | } 73 | 74 | rule "terraform_unused_declarations" { 75 | enabled = false 76 | } 77 | 78 | rule "terraform_unused_required_providers" { 79 | enabled = true 80 | } 81 | 82 | 83 | ################################################### 84 | # Rule Sets - AWS 85 | ################################################### 86 | 87 | plugin "aws" { 88 | source = "github.com/terraform-linters/tflint-ruleset-aws" 89 | version = "0.44.0" 90 | 91 | enabled = true 92 | deep_check = false 93 | } 94 | 95 | rule "aws_iam_policy_attachment_exclusive_attachment" { 96 | enabled = true 97 | } 98 | 99 | rule "aws_iam_role_deprecated_policy_attributes" { 100 | enabled = true 101 | } 102 | 103 | rule "aws_security_group_inline_rules" { 104 | enabled = true 105 | } 106 | 107 | rule "aws_security_group_rule_deprecated" { 108 | enabled = true 109 | } 110 | -------------------------------------------------------------------------------- /examples/nlb-with-alb-target-group/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | 6 | data "aws_vpc" "default" { 7 | default = true 8 | } 9 | 10 | data "aws_subnet" "default" { 11 | for_each = toset(["use1-az1", "use1-az2"]) 12 | 13 | availability_zone_id = each.key 14 | default_for_az = true 15 | } 16 | 17 | 18 | ################################################### 19 | # Network Load Balancer 20 | ################################################### 21 | 22 | module "nlb" { 23 | source = "../../modules/nlb" 24 | # source = "tedilabs/load-balancer/aws//modules/nlb" 25 | # version = "~> 1.0.0" 26 | 27 | name = "tedilabs-nlb-alb" 28 | 29 | is_public = false 30 | ip_address_type = "IPV4" 31 | network_mapping = { 32 | for az, subnet in data.aws_subnet.default : 33 | az => { 34 | subnet = subnet.id 35 | } 36 | } 37 | 38 | ## Attributes 39 | cross_zone_load_balancing_enabled = true 40 | deletion_protection_enabled = false 41 | 42 | listeners = [{ 43 | port = 80 44 | protocol = "TCP" 45 | target_group = module.target_group.arn 46 | }] 47 | 48 | ## Access Log 49 | access_log = { 50 | enabled = false 51 | s3_bucket = { 52 | name = "my-bucket" 53 | key_prefix = "/tedilabs-nlb-alb/" 54 | } 55 | } 56 | 57 | tags = { 58 | "project" = "terraform-aws-load-balancer-examples" 59 | } 60 | } 61 | 62 | 63 | ################################################### 64 | # ALB Target Group for Network Load Balancer 65 | ################################################### 66 | 67 | module "target_group" { 68 | source = "../../modules/nlb-alb-target-group" 69 | # source = "tedilabs/load-balancer/aws//modules/nlb-alb-target-group" 70 | # version = "~> 1.0.0" 71 | 72 | name = "tedilabs-nlb-alb-tg" 73 | 74 | vpc_id = data.aws_vpc.default.id 75 | port = 80 76 | 77 | targets = [ 78 | { 79 | alb = module.alb.arn 80 | } 81 | ] 82 | 83 | health_check = { 84 | protocol = "HTTP" 85 | port = 80 86 | port_override = false 87 | path = "/ping" 88 | 89 | interval = 10 90 | healthy_threshold = 3 91 | unhealthy_threshold = 3 92 | } 93 | 94 | tags = { 95 | "project" = "terraform-aws-load-balancer-examples" 96 | } 97 | 98 | depends_on = [ 99 | module.alb, 100 | ] 101 | } 102 | -------------------------------------------------------------------------------- /modules/alb-lambda-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "type" { 27 | description = "The target type of the target group." 28 | value = upper(aws_lb_target_group.this.target_type) 29 | } 30 | 31 | output "targets" { 32 | description = "A list of targets in the target group. The Lambda target group is limited to a single Lambda function target." 33 | value = [ 34 | for target in aws_lb_target_group_attachment.this : { 35 | lambda_function = { 36 | arn = target.target_id 37 | } 38 | } 39 | ] 40 | } 41 | 42 | output "attributes" { 43 | description = "Attributes of the Lambda target group of application load balancer." 44 | value = { 45 | multi_value_headers_enabled = aws_lb_target_group.this.lambda_multi_value_headers_enabled 46 | } 47 | } 48 | 49 | output "health_check" { 50 | description = "Health Check configuration of the target group." 51 | value = { 52 | enabled = aws_lb_target_group.this.health_check[0].enabled 53 | 54 | path = aws_lb_target_group.this.health_check[0].path 55 | success_codes = aws_lb_target_group.this.health_check[0].matcher 56 | 57 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 58 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 59 | interval = aws_lb_target_group.this.health_check[0].interval 60 | timeout = aws_lb_target_group.this.health_check[0].timeout 61 | } 62 | } 63 | 64 | output "resource_group" { 65 | description = "The resource group created to manage resources in this module." 66 | value = merge( 67 | { 68 | enabled = var.resource_group.enabled && var.module_tags_enabled 69 | }, 70 | (var.resource_group.enabled && var.module_tags_enabled 71 | ? { 72 | arn = module.resource_group[0].arn 73 | name = module.resource_group[0].name 74 | } 75 | : {} 76 | ) 77 | ) 78 | } 79 | -------------------------------------------------------------------------------- /modules/nlb-alb-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | 18 | ################################################### 19 | # NLB ALB Target Group 20 | ################################################### 21 | 22 | # INFO: Not supported attributes 23 | # - `connection_termination` 24 | # - `ip_address_type` 25 | # - `lambda_multi_value_headers_enabled` 26 | # - `load_balancing_algorithm_type` 27 | # - `load_balancing_anomaly_mitigation` 28 | # - `load_balancing_cross_zone_enabled` 29 | # - `protocol_version` 30 | # - `proxy_protocol_v2` 31 | # - `slow_start` 32 | resource "aws_lb_target_group" "this" { 33 | name = var.name 34 | 35 | vpc_id = var.vpc_id 36 | 37 | target_type = "alb" 38 | port = var.port 39 | protocol = "TCP" 40 | 41 | ## Attributes 42 | ## INFO: Not supported to edit 43 | # deregistration_delay = 300 44 | # preserve_client_ip = true 45 | # stickiness { 46 | # enabled = false 47 | # type = "source_ip" 48 | # } 49 | 50 | ## INFO: Not supported attributes 51 | # - `timeout` 52 | health_check { 53 | enabled = true 54 | 55 | protocol = var.health_check.protocol 56 | port = (var.health_check.port_override 57 | ? coalesce(var.health_check.port, var.port) 58 | : "traffic-port" 59 | ) 60 | path = var.health_check.path 61 | matcher = "200-399" 62 | 63 | healthy_threshold = var.health_check.healthy_threshold 64 | unhealthy_threshold = var.health_check.unhealthy_threshold 65 | interval = var.health_check.interval 66 | } 67 | 68 | tags = merge( 69 | { 70 | "Name" = local.metadata.name 71 | }, 72 | local.module_tags, 73 | var.tags, 74 | ) 75 | } 76 | 77 | 78 | ################################################### 79 | # Attachment for NLB ALB Target Group 80 | ################################################### 81 | 82 | # INFO: Not supported attributes 83 | # - `availability_zone` 84 | resource "aws_lb_target_group_attachment" "this" { 85 | count = length(var.targets) > 0 ? 1 : 0 86 | 87 | target_group_arn = aws_lb_target_group.this.arn 88 | 89 | target_id = tolist(var.targets)[0].alb 90 | port = var.port 91 | } 92 | -------------------------------------------------------------------------------- /examples/nlb-with-alb-target-group/alb.tf: -------------------------------------------------------------------------------- 1 | ################################################### 2 | # Application Load Balancer 3 | ################################################### 4 | 5 | module "alb" { 6 | source = "../../modules/alb" 7 | # source = "tedilabs/load-balancer/aws//modules/alb" 8 | # version = "~> 1.0.0" 9 | 10 | name = "tedilabs-nlb-alb-alb" 11 | 12 | is_public = false 13 | ip_address_type = "IPV4" 14 | vpc_id = data.aws_vpc.default.id 15 | network_mapping = { 16 | for az, subnet in data.aws_subnet.default : 17 | az => { 18 | subnet = subnet.id 19 | } 20 | } 21 | 22 | default_security_group = { 23 | enabled = true 24 | name = "tedilabs-nlb-alb-alb" 25 | description = "Managed by Terraform." 26 | 27 | listener_ingress_ipv4_cidrs = ["10.0.0.0/8", "172.31.0.0/16"] 28 | } 29 | security_groups = [] 30 | 31 | ## Attributes 32 | desync_mitigation_mode = "DEFENSIVE" 33 | drop_invalid_header_fields = false 34 | deletion_protection_enabled = false 35 | http2_enabled = true 36 | waf_fail_open_enabled = false 37 | idle_timeout = 60 38 | 39 | listeners = [ 40 | { 41 | port = 80 42 | protocol = "HTTP" 43 | default_action_type = "REDIRECT_301" 44 | default_action_parameters = { 45 | protocol = "HTTPS" 46 | port = 443 47 | } 48 | rules = [ 49 | { 50 | priority = 10 51 | conditions = [ 52 | { 53 | type = "PATH" 54 | values = ["/ping"] 55 | } 56 | ] 57 | action_type = "FIXED_RESPONSE" 58 | action_parameters = { 59 | status_code = 200 60 | content_type = "application/json" 61 | data = < { 34 | subnet = subnet.id 35 | } 36 | } 37 | 38 | ## Attributes 39 | cross_zone_load_balancing_enabled = true 40 | deletion_protection_enabled = false 41 | 42 | listeners = [{ 43 | port = 80 44 | protocol = "TCP" 45 | target_group = module.target_group.arn 46 | }] 47 | 48 | ## Access Log 49 | access_log = { 50 | enabled = false 51 | s3_bucket = { 52 | name = "my-bucket" 53 | key_prefix = "/tedilabs-nlb-instance/" 54 | } 55 | } 56 | 57 | tags = { 58 | "project" = "terraform-aws-load-balancer-examples" 59 | } 60 | } 61 | 62 | 63 | ################################################### 64 | # Instance Target Group for Network Load Balancer 65 | ################################################### 66 | 67 | module "target_group" { 68 | source = "../../modules/nlb-instance-target-group" 69 | # source = "tedilabs/load-balancer/aws//modules/nlb-instance-target-group" 70 | # version = "~> 1.0.0" 71 | 72 | name = "tedilabs-nlb-instance-tg" 73 | 74 | vpc_id = data.aws_vpc.default.id 75 | 76 | port = 80 77 | protocol = "TCP" 78 | 79 | ## Attributes 80 | terminate_connection_on_deregistration = false 81 | deregistration_delay = 300 82 | preserve_client_ip = true 83 | proxy_protocol_v2 = false 84 | stickiness_enabled = true 85 | 86 | targets = [ 87 | # { 88 | # instance = "i-xxxx" 89 | # }, 90 | ] 91 | 92 | health_check = { 93 | protocol = "HTTP" 94 | port = 80 95 | port_override = true 96 | path = "/health" 97 | 98 | interval = 10 99 | timeout = 5 100 | healthy_threshold = 3 101 | unhealthy_threshold = 3 102 | } 103 | 104 | tags = { 105 | "project" = "terraform-aws-load-balancer-examples" 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /modules/gwlb/outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | description = "The Amazon Resource Name (ARN) of the load balancer." 3 | value = aws_lb.this.arn 4 | } 5 | 6 | output "arn_suffix" { 7 | description = "The ARN suffix for use with CloudWatch Metrics." 8 | value = aws_lb.this.arn_suffix 9 | } 10 | 11 | output "id" { 12 | description = "The ID of the load balancer." 13 | value = aws_lb.this.id 14 | } 15 | 16 | output "name" { 17 | description = "The name of the load balancer." 18 | value = aws_lb.this.name 19 | } 20 | 21 | output "type" { 22 | description = "The type of the load balancer. Always return `GATEWAY`." 23 | value = local.load_balancer_type 24 | } 25 | 26 | output "availability_zone_ids" { 27 | description = "A list of the Availability Zone IDs which are used by the load balancer." 28 | value = local.availability_zone_ids 29 | } 30 | 31 | output "vpc_id" { 32 | description = "The VPC ID of the load balancer." 33 | value = aws_lb.this.vpc_id 34 | } 35 | 36 | output "subnets" { 37 | description = "A list of subnet IDs attached to the load balancer." 38 | value = aws_lb.this.subnets 39 | } 40 | 41 | output "network_mapping" { 42 | description = "The configuration for the load balancer how routes traffic to targets in which subnets and IP address settings." 43 | value = local.network_mapping 44 | } 45 | 46 | output "attributes" { 47 | description = "Load Balancer Attributes that applied to the gateway load balancer." 48 | value = { 49 | cross_zone_load_balancing_enabled = aws_lb.this.enable_cross_zone_load_balancing 50 | deletion_protection_enabled = aws_lb.this.enable_deletion_protection 51 | } 52 | } 53 | 54 | output "listeners" { 55 | description = "Listeners of the load balancer." 56 | value = length(var.listeners) > 0 ? { 57 | (var.listeners[0].port) = { 58 | id = aws_lb_listener.this[0].id 59 | arn = aws_lb_listener.this[0].arn 60 | name = "${var.name}/GENEVE:${var.listeners[0].port}" 61 | 62 | port = var.listeners[0].port 63 | protocol = "GENEVE" 64 | 65 | default_action = { 66 | type = "FORWARD" 67 | forward = { 68 | target_group = { 69 | arn = var.listeners[0].target_group 70 | name = split("/", var.listeners[0].target_group)[1] 71 | } 72 | } 73 | } 74 | } 75 | } : {} 76 | } 77 | 78 | output "resource_group" { 79 | description = "The resource group created to manage resources in this module." 80 | value = merge( 81 | { 82 | enabled = var.resource_group.enabled && var.module_tags_enabled 83 | }, 84 | (var.resource_group.enabled && var.module_tags_enabled 85 | ? { 86 | arn = module.resource_group[0].arn 87 | name = module.resource_group[0].name 88 | } 89 | : {} 90 | ) 91 | ) 92 | } 93 | -------------------------------------------------------------------------------- /examples/nlb-with-ip-target-group/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | 6 | data "aws_vpc" "default" { 7 | default = true 8 | } 9 | 10 | data "aws_subnet" "default" { 11 | for_each = toset(["use1-az1", "use1-az2"]) 12 | 13 | availability_zone_id = each.key 14 | default_for_az = true 15 | } 16 | 17 | 18 | ################################################### 19 | # Network Load Balancer 20 | ################################################### 21 | 22 | module "nlb" { 23 | source = "../../modules/nlb" 24 | # source = "tedilabs/load-balancer/aws//modules/nlb" 25 | # version = "~> 1.0.0" 26 | 27 | name = "tedilabs-nlb-ip" 28 | 29 | is_public = false 30 | ip_address_type = "IPV4" 31 | network_mapping = { 32 | for az, subnet in data.aws_subnet.default : 33 | az => { 34 | subnet = subnet.id 35 | } 36 | } 37 | 38 | ## Attributes 39 | cross_zone_load_balancing_enabled = true 40 | deletion_protection_enabled = false 41 | 42 | listeners = [{ 43 | port = 80 44 | protocol = "TCP" 45 | target_group = module.target_group.arn 46 | }] 47 | 48 | ## Access Log 49 | access_log = { 50 | enabled = false 51 | s3_bucket = { 52 | name = "my-bucket" 53 | key_prefix = "/tedilabs-nlb-ip/" 54 | } 55 | } 56 | 57 | tags = { 58 | "project" = "terraform-aws-load-balancer-examples" 59 | } 60 | } 61 | 62 | 63 | ################################################### 64 | # IP Target Group for Network Load Balancer 65 | ################################################### 66 | 67 | module "target_group" { 68 | source = "../../modules/nlb-ip-target-group" 69 | # source = "tedilabs/load-balancer/aws//modules/nlb-ip-target-group" 70 | # version = "~> 1.0.0" 71 | 72 | name = "tedilabs-nlb-ip-tg" 73 | 74 | vpc_id = data.aws_vpc.default.id 75 | 76 | ip_address_type = "IPV4" 77 | port = 80 78 | protocol = "TCP" 79 | 80 | ## Attributes 81 | terminate_connection_on_deregistration = false 82 | deregistration_delay = 300 83 | preserve_client_ip = true 84 | proxy_protocol_v2 = false 85 | stickiness_enabled = true 86 | 87 | targets = [ 88 | { 89 | ip_address = "10.123.123.234" 90 | }, 91 | { 92 | ip_address = "10.0.103.34" 93 | port = 999 94 | }, 95 | ] 96 | 97 | health_check = { 98 | protocol = "HTTP" 99 | port = 443 100 | port_override = false 101 | path = "/health" 102 | 103 | interval = 10 104 | timeout = 5 105 | healthy_threshold = 3 106 | unhealthy_threshold = 3 107 | } 108 | 109 | tags = { 110 | "project" = "terraform-aws-load-balancer-examples" 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-aws-load-balancer 2 | 3 | ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/tedilabs/terraform-aws-load-balancer?color=blue&sort=semver&style=flat-square) 4 | ![GitHub](https://img.shields.io/github/license/tedilabs/terraform-aws-load-balancer?color=blue&style=flat-square) 5 | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=flat-square)](https://github.com/pre-commit/pre-commit) 6 | 7 | Terraform module which creates security related resources on AWS. 8 | 9 | - [alb](./modules/alb) 10 | - [alb-instance-target-group](./modules/alb-instance-target-group) 11 | - [alb-ip-target-group](./modules/alb-ip-target-group) 12 | - [alb-lambda-target-group](./modules/alb-lambda-target-group) 13 | - [alb-listener](./modules/alb-listener) 14 | - [gwlb](./modules/gwlb) 15 | - [gwlb-instance-target-group](./modules/gwlb-instance-target-group) 16 | - [gwlb-ip-target-group](./modules/gwlb-ip-target-group) 17 | - [nlb](./modules/nlb) 18 | - [nlb-alb-target-group](./modules/nlb-alb-target-group) 19 | - [nlb-instance-target-group](./modules/nlb-instance-target-group) 20 | - [nlb-ip-target-group](./modules/nlb-ip-target-group) 21 | - [nlb-listener](./modules/nlb-listener) 22 | 23 | 24 | ## Target AWS Services 25 | 26 | Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws-load-balancer) were written to manage the following AWS Services with Terraform. 27 | 28 | - **AWS ELB (Elastic Load Balancing)** 29 | - ALB (Application Load Balancer) 30 | - Load Balancer 31 | - Listener 32 | - Target Group (Instance / IP / Lambda) 33 | - NLB (Network Load Balancer) 34 | - Load Balancer 35 | - Listener 36 | - Target Group (Instance / IP / ALB) 37 | - GWLB (Gateway Load Balancer) 38 | - Load Balancer 39 | - Listener 40 | - Target Group (Instance / IP) 41 | 42 | 43 | ## Examples 44 | 45 | ### ALB (Application Load Balancer) 46 | 47 | - [ALB with Instance Target Group](./examples/alb-with-instance-target-group) 48 | - [ALB with IP Target Group](./examples/alb-with-ip-target-group) 49 | 50 | ### NLB (Network Load Balancer) 51 | 52 | - [NLB with Instance Target Group](./examples/nlb-with-instance-target-group) 53 | - [NLB with IP Target Group](./examples/nlb-with-ip-target-group) 54 | - [NLB with ALB Target Group](./examples/nlb-with-alb-target-group) 55 | 56 | ### GWLB (Gateway Load Balancer) 57 | 58 | - [GWLB with Instance Target Group](./examples/gwlb-with-instance-target-group) 59 | - [GWLB with IP Target Group](./examples/gwlb-with-ip-target-group) 60 | 61 | 62 | ## Self Promotion 63 | 64 | Like this project? Follow the repository on [GitHub](https://github.com/tedilabs/terraform-aws-load-balancer). And if you're feeling especially charitable, follow **[posquit0](https://github.com/posquit0)** on GitHub. 65 | 66 | 67 | ## License 68 | 69 | Provided under the terms of the [Apache License](LICENSE). 70 | 71 | Copyright © 2022-2025, [Byungjin Park](https://www.posquit0.com). -------------------------------------------------------------------------------- /modules/gwlb-instance-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the VPC which the target group belongs to." 28 | value = aws_lb_target_group.this.vpc_id 29 | } 30 | 31 | output "type" { 32 | description = "The target type of the target group." 33 | value = upper(aws_lb_target_group.this.target_type) 34 | } 35 | 36 | output "port" { 37 | description = "The port number on which the target receive trrafic." 38 | value = aws_lb_target_group.this.port 39 | } 40 | 41 | output "protocol" { 42 | description = "The protocol to use to connect with the target." 43 | value = aws_lb_target_group.this.protocol 44 | } 45 | 46 | output "targets" { 47 | description = "A set of targets in the target group." 48 | value = [ 49 | for target in aws_lb_target_group_attachment.this : { 50 | instance = target.target_id 51 | port = target.port 52 | } 53 | ] 54 | } 55 | 56 | output "attributes" { 57 | description = "Attributes of the Instance target group of gateway load balancer." 58 | value = { 59 | deregistration_delay = aws_lb_target_group.this.deregistration_delay 60 | } 61 | } 62 | 63 | output "health_check" { 64 | description = "Health Check configuration of the target group." 65 | value = { 66 | protocol = aws_lb_target_group.this.health_check[0].protocol 67 | port = aws_lb_target_group.this.health_check[0].port 68 | path = aws_lb_target_group.this.health_check[0].path 69 | success_codes = aws_lb_target_group.this.health_check[0].matcher 70 | 71 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 72 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 73 | interval = aws_lb_target_group.this.health_check[0].interval 74 | timeout = aws_lb_target_group.this.health_check[0].timeout 75 | } 76 | } 77 | 78 | output "resource_group" { 79 | description = "The resource group created to manage resources in this module." 80 | value = merge( 81 | { 82 | enabled = var.resource_group.enabled && var.module_tags_enabled 83 | }, 84 | (var.resource_group.enabled && var.module_tags_enabled 85 | ? { 86 | arn = module.resource_group[0].arn 87 | name = module.resource_group[0].name 88 | } 89 | : {} 90 | ) 91 | ) 92 | } 93 | -------------------------------------------------------------------------------- /modules/gwlb-ip-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the VPC which the target group belongs to." 28 | value = aws_lb_target_group.this.vpc_id 29 | } 30 | 31 | output "type" { 32 | description = "The target type of the target group." 33 | value = upper(aws_lb_target_group.this.target_type) 34 | } 35 | 36 | output "port" { 37 | description = "The port number on which the target receive trrafic." 38 | value = aws_lb_target_group.this.port 39 | } 40 | 41 | output "protocol" { 42 | description = "The protocol to use to connect with the target." 43 | value = aws_lb_target_group.this.protocol 44 | } 45 | 46 | output "targets" { 47 | description = "A set of targets in the target group." 48 | value = [ 49 | for target in aws_lb_target_group_attachment.this : { 50 | ip_address = target.target_id 51 | port = target.port 52 | is_external = target.availability_zone == "all" 53 | } 54 | ] 55 | } 56 | 57 | output "attributes" { 58 | description = "Attributes of the IP target group of gateway load balancer." 59 | value = { 60 | deregistration_delay = aws_lb_target_group.this.deregistration_delay 61 | } 62 | } 63 | 64 | output "health_check" { 65 | description = "Health Check configuration of the target group." 66 | value = { 67 | protocol = aws_lb_target_group.this.health_check[0].protocol 68 | port = aws_lb_target_group.this.health_check[0].port 69 | path = aws_lb_target_group.this.health_check[0].path 70 | success_codes = aws_lb_target_group.this.health_check[0].matcher 71 | 72 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 73 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 74 | interval = aws_lb_target_group.this.health_check[0].interval 75 | timeout = aws_lb_target_group.this.health_check[0].timeout 76 | } 77 | } 78 | 79 | output "resource_group" { 80 | description = "The resource group created to manage resources in this module." 81 | value = merge( 82 | { 83 | enabled = var.resource_group.enabled && var.module_tags_enabled 84 | }, 85 | (var.resource_group.enabled && var.module_tags_enabled 86 | ? { 87 | arn = module.resource_group[0].arn 88 | name = module.resource_group[0].name 89 | } 90 | : {} 91 | ) 92 | ) 93 | } 94 | -------------------------------------------------------------------------------- /modules/alb-lambda-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | 18 | ################################################### 19 | # ALB Lambda Target Group 20 | ################################################### 21 | 22 | # INFO: Not supported attributes 23 | # - `connection_termination` 24 | # - `deregistration_delay` 25 | # - `ip_address_type` 26 | # - `load_balancing_algorithm_type` 27 | # - `load_balancing_anomaly_mitigation` 28 | # - `load_balancing_cross_zone_enabled` 29 | # - `preserve_client_ip` 30 | # - `protocol` 31 | # - `protocol_version` 32 | # - `proxy_protocol_v2` 33 | # - `port` 34 | # - `slow_start` 35 | # - `stickiness` 36 | # - `vpc_id` 37 | resource "aws_lb_target_group" "this" { 38 | name = var.name 39 | 40 | target_type = "lambda" 41 | 42 | ## Attributes 43 | lambda_multi_value_headers_enabled = var.multi_value_headers_enabled 44 | 45 | ## INFO: Not supported attributes 46 | # - `port` 47 | # - `protocol` 48 | health_check { 49 | enabled = try(var.health_check.enabled, false) 50 | 51 | path = var.health_check.path 52 | matcher = var.health_check.success_codes 53 | 54 | healthy_threshold = var.health_check.healthy_threshold 55 | unhealthy_threshold = var.health_check.unhealthy_threshold 56 | interval = var.health_check.interval 57 | timeout = var.health_check.timeout 58 | } 59 | 60 | tags = merge( 61 | { 62 | "Name" = local.metadata.name 63 | }, 64 | local.module_tags, 65 | var.tags, 66 | ) 67 | } 68 | 69 | 70 | ################################################### 71 | # Attachment for ALB Lambda Target Group 72 | ################################################### 73 | 74 | # INFO: Not supported attributes 75 | # - `port` 76 | resource "aws_lb_target_group_attachment" "this" { 77 | count = length(var.targets) > 0 ? 1 : 0 78 | 79 | target_group_arn = aws_lb_target_group.this.arn 80 | 81 | # TODO: divide function name and alias 82 | target_id = tolist(var.targets)[0].lambda_function 83 | availability_zone = "all" 84 | 85 | depends_on = [ 86 | aws_lambda_permission.this, 87 | ] 88 | } 89 | 90 | 91 | ################################################### 92 | # Permission for ALB Lambda Target Group 93 | ################################################### 94 | 95 | resource "aws_lambda_permission" "this" { 96 | count = length(var.targets) > 0 ? 1 : 0 97 | 98 | function_name = tolist(var.targets)[0].lambda_function 99 | 100 | statement_id_prefix = "AllowExecutionFromALB-" 101 | principal = "elasticloadbalancing.amazonaws.com" 102 | action = "lambda:InvokeFunction" 103 | source_arn = aws_lb_target_group.this.arn 104 | } 105 | -------------------------------------------------------------------------------- /modules/nlb/security-groups.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | security_groups = concat( 3 | (var.default_security_group.enabled 4 | ? module.security_group[*].id 5 | : [] 6 | ), 7 | var.security_groups, 8 | ) 9 | } 10 | 11 | 12 | ################################################### 13 | # Security Group for Network Load Balancer 14 | ################################################### 15 | 16 | module "security_group" { 17 | source = "tedilabs/network/aws//modules/security-group" 18 | version = "~> 0.32.0" 19 | 20 | count = var.default_security_group.enabled ? 1 : 0 21 | 22 | name = coalesce(var.default_security_group.name, local.metadata.name) 23 | description = var.default_security_group.description 24 | vpc_id = values(data.aws_subnet.this)[0].vpc_id 25 | 26 | ingress_rules = concat( 27 | var.default_security_group.ingress_rules, 28 | [ 29 | for listener in var.listeners : { 30 | id = "listener-${listener.port}" 31 | description = "Default rule for the load balancer listener." 32 | protocol = "tcp" 33 | from_port = listener.port 34 | to_port = listener.port 35 | 36 | ipv4_cidrs = var.default_security_group.listener_ingress_ipv4_cidrs 37 | ipv6_cidrs = var.default_security_group.listener_ingress_ipv6_cidrs 38 | prefix_lists = var.default_security_group.listener_ingress_prefix_lists 39 | security_groups = var.default_security_group.listener_ingress_security_groups 40 | } 41 | if contains(["TCP", "TLS", "TCP_UDP"], listener.protocol) && anytrue([ 42 | length(var.default_security_group.listener_ingress_ipv4_cidrs) > 0, 43 | length(var.default_security_group.listener_ingress_ipv6_cidrs) > 0, 44 | length(var.default_security_group.listener_ingress_prefix_lists) > 0, 45 | length(var.default_security_group.listener_ingress_security_groups) > 0, 46 | ]) 47 | ], 48 | [ 49 | for listener in var.listeners : { 50 | id = "listener-${listener.port}-udp" 51 | description = "Default rule for the load balancer listener." 52 | protocol = "udp" 53 | from_port = listener.port 54 | to_port = listener.port 55 | 56 | ipv4_cidrs = var.default_security_group.listener_ingress_ipv4_cidrs 57 | ipv6_cidrs = var.default_security_group.listener_ingress_ipv6_cidrs 58 | prefix_lists = var.default_security_group.listener_ingress_prefix_lists 59 | security_groups = var.default_security_group.listener_ingress_security_groups 60 | } 61 | if contains(["UDP"], listener.protocol) && anytrue([ 62 | length(var.default_security_group.listener_ingress_ipv4_cidrs) > 0, 63 | length(var.default_security_group.listener_ingress_ipv6_cidrs) > 0, 64 | length(var.default_security_group.listener_ingress_prefix_lists) > 0, 65 | length(var.default_security_group.listener_ingress_security_groups) > 0, 66 | ]) 67 | ], 68 | ) 69 | egress_rules = concat( 70 | var.default_security_group.egress_rules, 71 | # TODO: Limit egress rules 72 | # TODO: Target Ports 73 | # TODO: Target Health Check Ports 74 | ) 75 | 76 | revoke_rules_on_delete = true 77 | resource_group_enabled = false 78 | module_tags_enabled = false 79 | 80 | tags = merge( 81 | local.module_tags, 82 | var.tags, 83 | ) 84 | } 85 | -------------------------------------------------------------------------------- /modules/nlb-alb-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the VPC which the target group belongs to." 28 | value = aws_lb_target_group.this.vpc_id 29 | } 30 | 31 | output "type" { 32 | description = "The target type of the target group." 33 | value = upper(aws_lb_target_group.this.target_type) 34 | } 35 | 36 | output "port" { 37 | description = "The port number on which the target receive trrafic." 38 | value = aws_lb_target_group.this.port 39 | } 40 | 41 | output "protocol" { 42 | description = "The protocol to use to connect with the target." 43 | value = aws_lb_target_group.this.protocol 44 | } 45 | 46 | output "targets" { 47 | description = "A list of targets in the target group. The ALB target group is limited to a single Application Load Balancer target." 48 | value = [ 49 | for idx, target in aws_lb_target_group_attachment.this : { 50 | alb = { 51 | arn = target.target_id 52 | name = split("/", target.target_id)[2] 53 | } 54 | port = target.port 55 | } 56 | ] 57 | } 58 | 59 | output "attributes" { 60 | description = "Attributes of the ALB target group of network load balancer." 61 | value = { 62 | deregistration_delay = aws_lb_target_group.this.deregistration_delay 63 | preserve_client_ip = aws_lb_target_group.this.preserve_client_ip 64 | stickiness = { 65 | enabled = aws_lb_target_group.this.stickiness[0].enabled 66 | type = upper(aws_lb_target_group.this.stickiness[0].type) 67 | } 68 | } 69 | } 70 | 71 | output "health_check" { 72 | description = "Health Check configuration of the target group." 73 | value = { 74 | protocol = aws_lb_target_group.this.health_check[0].protocol 75 | port = aws_lb_target_group.this.health_check[0].port 76 | path = aws_lb_target_group.this.health_check[0].path 77 | success_codes = aws_lb_target_group.this.health_check[0].matcher 78 | 79 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 80 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 81 | interval = aws_lb_target_group.this.health_check[0].interval 82 | timeout = aws_lb_target_group.this.health_check[0].timeout 83 | } 84 | } 85 | 86 | output "resource_group" { 87 | description = "The resource group created to manage resources in this module." 88 | value = merge( 89 | { 90 | enabled = var.resource_group.enabled && var.module_tags_enabled 91 | }, 92 | (var.resource_group.enabled && var.module_tags_enabled 93 | ? { 94 | arn = module.resource_group[0].arn 95 | name = module.resource_group[0].name 96 | } 97 | : {} 98 | ) 99 | ) 100 | } 101 | -------------------------------------------------------------------------------- /.github/workflows/terraform.integration.yaml: -------------------------------------------------------------------------------- 1 | name: Integration (Terraform) 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: {} 8 | 9 | concurrency: 10 | group: terraform-integration-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | changed: 15 | name: Filter Changed Files and Directories 16 | runs-on: ubuntu-latest 17 | 18 | outputs: 19 | changed: ${{ steps.set-outputs.outputs.changed }} 20 | modified: ${{ steps.set-outputs.outputs.modified }} 21 | changed_files: ${{ steps.set-outputs.outputs.changed_files }} 22 | modified_files: ${{ steps.set-outputs.outputs.modified_files }} 23 | changed_directories: ${{ steps.set-outputs.outputs.changed_directories }} 24 | modified_directories: ${{ steps.set-outputs.outputs.modified_directories }} 25 | 26 | steps: 27 | - name: Checkout 28 | uses: actions/checkout@v4 29 | with: 30 | fetch-depth: 0 31 | 32 | - name: Get Changed Files 33 | id: changed-files 34 | uses: tj-actions/changed-files@v44 35 | with: 36 | files: | 37 | modules/** 38 | examples/** 39 | json: true 40 | 41 | - name: Get Changed Directories 42 | id: changed-directories 43 | uses: tj-actions/changed-files@v44 44 | with: 45 | files: | 46 | modules/** 47 | examples/** 48 | dir_names: "true" 49 | dir_names_max_depth: 2 50 | json: true 51 | 52 | - name: Set outputs 53 | id: set-outputs 54 | run: | 55 | echo "changed=${{ steps.changed-directories.outputs.any_changed }}" >> $GITHUB_OUTPUT 56 | echo "modified=${{ steps.changed-directories.outputs.any_modified }}" >> $GITHUB_OUTPUT 57 | 58 | echo "changed_files=${{ steps.changed-files.outputs.all_changed_files }}" >> $GITHUB_OUTPUT 59 | echo "modified_files=${{ steps.changed-files.outputs.all_modified_files }}" >> $GITHUB_OUTPUT 60 | 61 | echo "changed_directories=${{ steps.changed-directories.outputs.all_changed_files }}" >> $GITHUB_OUTPUT 62 | echo "modified_directories=${{ steps.changed-directories.outputs.all_modified_files }}" >> $GITHUB_OUTPUT 63 | 64 | 65 | terraform: 66 | name: Lint (terraform) 67 | needs: 68 | - changed 69 | if: ${{ needs.changed.outputs.modified == 'true' }} 70 | uses: tedilabs/.github/.github/workflows/terraform.terraform.yaml@main 71 | 72 | strategy: 73 | matrix: 74 | path: ${{ fromJson(needs.changed.outputs.modified_directories) }} 75 | 76 | with: 77 | terraform_target_dir: ${{ matrix.path }} 78 | terraform_version: latest 79 | terraform_host: app.terraform.io 80 | secrets: 81 | gh_token: ${{ secrets.GITHUB_TOKEN }} 82 | token: ${{ secrets.GITHUB_TOKEN }} 83 | terraform_token: ${{ secrets.TERRAFORM_TOKEN }} 84 | 85 | 86 | tflint: 87 | name: Lint (tflint) 88 | needs: 89 | - changed 90 | if: ${{ needs.changed.outputs.modified == 'true' }} 91 | uses: tedilabs/.github/.github/workflows/terraform.tflint.yaml@main 92 | 93 | strategy: 94 | matrix: 95 | path: ${{ fromJson(needs.changed.outputs.modified_directories) }} 96 | 97 | with: 98 | tflint_version: latest 99 | tflint_config_file: .tflint.hcl 100 | tflint_target_dir: ${{ matrix.path }} 101 | tflint_recursive_enabled: false 102 | tflint_terraform_init_enabled: true 103 | terraform_version: latest 104 | terraform_host: app.terraform.io 105 | secrets: 106 | gh_token: ${{ secrets.GITHUB_TOKEN }} 107 | token: ${{ secrets.GITHUB_TOKEN }} 108 | terraform_token: ${{ secrets.TERRAFORM_TOKEN }} 109 | -------------------------------------------------------------------------------- /modules/nlb-instance-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | locals { 18 | cross_zone_strategy = { 19 | "ENABLED" = "true" 20 | "DISABLED" = "false" 21 | "INHERIT" = "use_load_balancer_configuration" 22 | } 23 | } 24 | 25 | 26 | ################################################### 27 | # NLB Instance Target Group 28 | ################################################### 29 | 30 | # INFO: Not supported attributes 31 | # - `ip_address_type` 32 | # - `lambda_multi_value_headers_enabled` 33 | # - `load_balancing_algorithm_type` 34 | # - `load_balancing_anomaly_mitigation` 35 | # - `protocol_version` 36 | # - `slow_start` 37 | resource "aws_lb_target_group" "this" { 38 | name = var.name 39 | 40 | vpc_id = var.vpc_id 41 | 42 | target_type = "instance" 43 | port = var.port 44 | protocol = var.protocol 45 | 46 | ## Attributes 47 | connection_termination = var.terminate_connection_on_deregistration 48 | deregistration_delay = var.deregistration_delay 49 | load_balancing_cross_zone_enabled = local.cross_zone_strategy[var.load_balancing.cross_zone_strategy] 50 | preserve_client_ip = var.preserve_client_ip 51 | proxy_protocol_v2 = var.proxy_protocol_v2 52 | 53 | ## INFO: Not supported attributes 54 | # - `cookie_duration` 55 | # - `cookie_name` 56 | stickiness { 57 | enabled = var.stickiness_enabled 58 | type = "source_ip" 59 | } 60 | 61 | ## INFO: Not supported attributes 62 | # - `timeout` 63 | dynamic "health_check" { 64 | for_each = [merge( 65 | var.health_check, 66 | var.health_check.protocol != "TCP" 67 | ? { 68 | success_codes = "200-399" 69 | } 70 | : { 71 | success_codes = null 72 | path = null 73 | }, 74 | )] 75 | 76 | content { 77 | enabled = true 78 | 79 | protocol = health_check.value.protocol 80 | port = (health_check.value.port_override 81 | ? coalesce(health_check.value.port, var.port) 82 | : "traffic-port" 83 | ) 84 | path = health_check.value.path 85 | matcher = health_check.value.success_codes 86 | 87 | healthy_threshold = health_check.value.healthy_threshold 88 | unhealthy_threshold = health_check.value.unhealthy_threshold 89 | interval = health_check.value.interval 90 | } 91 | } 92 | 93 | tags = merge( 94 | { 95 | "Name" = local.metadata.name 96 | }, 97 | local.module_tags, 98 | var.tags, 99 | ) 100 | } 101 | 102 | 103 | ################################################### 104 | # Attachment for NLB Instance Target Group 105 | ################################################### 106 | 107 | # INFO: Not supported attributes 108 | # - `availability_zone` 109 | resource "aws_lb_target_group_attachment" "this" { 110 | for_each = { 111 | for target in var.targets : 112 | target.instance => target 113 | } 114 | 115 | target_group_arn = aws_lb_target_group.this.arn 116 | 117 | target_id = each.key 118 | port = try(each.value.port, var.port) 119 | } 120 | -------------------------------------------------------------------------------- /modules/nlb-instance-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the VPC which the target group belongs to." 28 | value = aws_lb_target_group.this.vpc_id 29 | } 30 | 31 | output "type" { 32 | description = "The target type of the target group." 33 | value = upper(aws_lb_target_group.this.target_type) 34 | } 35 | 36 | output "port" { 37 | description = "The port number on which the target receive trrafic." 38 | value = aws_lb_target_group.this.port 39 | } 40 | 41 | output "protocol" { 42 | description = "The protocol to use to connect with the target." 43 | value = aws_lb_target_group.this.protocol 44 | } 45 | 46 | output "targets" { 47 | description = "A set of targets in the target group." 48 | value = [ 49 | for target in aws_lb_target_group_attachment.this : { 50 | instance = target.target_id 51 | port = target.port 52 | } 53 | ] 54 | } 55 | 56 | output "attributes" { 57 | description = "Attributes of the Instance target group of network load balancer." 58 | value = { 59 | terminate_connection_on_deregistration = aws_lb_target_group.this.connection_termination 60 | deregistration_delay = aws_lb_target_group.this.deregistration_delay 61 | load_balancing = { 62 | cross_zone_strategy = var.load_balancing.cross_zone_strategy 63 | } 64 | preserve_client_ip = aws_lb_target_group.this.preserve_client_ip 65 | proxy_protocol_v2 = aws_lb_target_group.this.proxy_protocol_v2 66 | stickiness = { 67 | enabled = aws_lb_target_group.this.stickiness[0].enabled 68 | type = upper(aws_lb_target_group.this.stickiness[0].type) 69 | } 70 | } 71 | } 72 | 73 | output "health_check" { 74 | description = "Health Check configuration of the target group." 75 | value = { 76 | protocol = aws_lb_target_group.this.health_check[0].protocol 77 | port = aws_lb_target_group.this.health_check[0].port 78 | path = aws_lb_target_group.this.health_check[0].path 79 | success_codes = aws_lb_target_group.this.health_check[0].matcher 80 | 81 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 82 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 83 | interval = aws_lb_target_group.this.health_check[0].interval 84 | timeout = aws_lb_target_group.this.health_check[0].timeout 85 | } 86 | } 87 | 88 | output "resource_group" { 89 | description = "The resource group created to manage resources in this module." 90 | value = merge( 91 | { 92 | enabled = var.resource_group.enabled && var.module_tags_enabled 93 | }, 94 | (var.resource_group.enabled && var.module_tags_enabled 95 | ? { 96 | arn = module.resource_group[0].arn 97 | name = module.resource_group[0].name 98 | } 99 | : {} 100 | ) 101 | ) 102 | } 103 | -------------------------------------------------------------------------------- /modules/gwlb-instance-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | locals { 18 | port = 6081 19 | targets = [ 20 | for target in var.targets : { 21 | instance = target.instance 22 | port = local.port 23 | } 24 | ] 25 | } 26 | 27 | 28 | ################################################### 29 | # GWLB Instance Target Group 30 | ################################################### 31 | 32 | # INFO: Not supported attributes 33 | # - `connection_termination` 34 | # - `ip_address_type` 35 | # - `lambda_multi_value_headers_enabled` 36 | # - `load_balancing_algorithm_type` 37 | # - `load_balancing_anomaly_mitigation` 38 | # - `load_balancing_cross_zone_enabled` 39 | # - `preserve_client_ip` 40 | # - `protocol_version` 41 | # - `proxy_protocol_v2` 42 | # - `slow_start` 43 | # - `stickiness` 44 | # - `tags` 45 | resource "aws_lb_target_group" "this" { 46 | name = var.name 47 | 48 | vpc_id = var.vpc_id 49 | 50 | target_type = "instance" 51 | port = local.port 52 | protocol = "GENEVE" 53 | 54 | ## Attributes 55 | deregistration_delay = var.deregistration_delay 56 | 57 | ## INFO: Too many bugs in terraform provider 58 | # - `healthy_threshold` doesn't need to be same with `unhealthy_threashold` 59 | # - `interval` doesn't apply to the acutal resource 60 | # - `timeout` is not supported 61 | dynamic "health_check" { 62 | for_each = [merge( 63 | var.health_check, 64 | var.health_check.protocol != "TCP" 65 | ? { 66 | success_codes = "200-399" 67 | } 68 | : { 69 | interval = null 70 | timeout = null 71 | success_codes = null 72 | path = null 73 | }, 74 | )] 75 | 76 | content { 77 | enabled = true 78 | 79 | protocol = health_check.value.protocol 80 | port = (health_check.value.port_override 81 | ? health_check.value.port 82 | : "traffic-port" 83 | ) 84 | path = health_check.value.path 85 | matcher = health_check.value.success_codes 86 | 87 | healthy_threshold = health_check.value.healthy_threshold 88 | unhealthy_threshold = health_check.value.unhealthy_threshold 89 | interval = health_check.value.interval 90 | timeout = health_check.value.timeout 91 | } 92 | } 93 | 94 | # INFO: Not supported on creation time. Only available on modification time. 95 | tags = merge( 96 | # { 97 | # "Name" = local.metadata.name 98 | # }, 99 | # local.module_tags, 100 | var.tags, 101 | ) 102 | } 103 | 104 | 105 | ################################################### 106 | # Attachment for GWLB Instance Target Group 107 | ################################################### 108 | 109 | # INFO: Not supported attributes 110 | # - `availability_zone` 111 | resource "aws_lb_target_group_attachment" "this" { 112 | for_each = { 113 | for target in local.targets : 114 | target.instance => target 115 | } 116 | 117 | target_group_arn = aws_lb_target_group.this.arn 118 | 119 | target_id = each.key 120 | port = each.value.port 121 | } 122 | -------------------------------------------------------------------------------- /modules/alb-instance-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | locals { 18 | cross_zone_strategy = { 19 | "ENABLED" = "true" 20 | "DISABLED" = "false" 21 | "INHERIT" = "use_load_balancer_configuration" 22 | } 23 | } 24 | 25 | 26 | ################################################### 27 | # ALB Instance Target Group 28 | ################################################### 29 | 30 | # INFO: Not supported attributes 31 | # - `connection_termination` 32 | # - `ip_address_type` 33 | # - `lambda_multi_value_headers_enabled` 34 | # - `preserve_client_ip` 35 | # - `proxy_protocol_v2` 36 | resource "aws_lb_target_group" "this" { 37 | name = var.name 38 | 39 | vpc_id = var.vpc_id 40 | 41 | target_type = "instance" 42 | port = var.port 43 | protocol = var.protocol 44 | protocol_version = var.protocol_version 45 | 46 | ## Attributes 47 | deregistration_delay = var.deregistration_delay 48 | load_balancing_algorithm_type = lower(var.load_balancing.algorithm) 49 | load_balancing_anomaly_mitigation = (var.load_balancing.algorithm == "WEIGHTED_RANDOM" 50 | ? var.load_balancing.anomaly_mitigation_enabled ? "on" : "off" 51 | : null 52 | ) 53 | load_balancing_cross_zone_enabled = local.cross_zone_strategy[var.load_balancing.cross_zone_strategy] 54 | slow_start = var.slow_start_duration 55 | 56 | stickiness { 57 | enabled = var.stickiness_enabled 58 | type = lower(var.stickiness_type) 59 | cookie_duration = var.stickiness_duration 60 | cookie_name = var.stickiness_type == "APP_COOKIE" ? var.stickiness_cookie : null 61 | } 62 | 63 | health_check { 64 | enabled = true 65 | 66 | protocol = var.health_check.protocol 67 | port = (var.health_check.port_override 68 | ? coalesce(var.health_check.port, var.port) 69 | : "traffic-port" 70 | ) 71 | path = (var.protocol_version != "GRPC" 72 | ? coalesce(var.health_check.path, "/") 73 | : coalesce(var.health_check.path, "/AWS.ALB/healthcheck") 74 | ) 75 | matcher = (var.protocol_version != "GRPC" 76 | ? coalesce(var.health_check.success_codes, "200") 77 | : coalesce(var.health_check.success_codes, "12") 78 | ) 79 | 80 | healthy_threshold = var.health_check.healthy_threshold 81 | unhealthy_threshold = var.health_check.unhealthy_threshold 82 | interval = var.health_check.interval 83 | timeout = var.health_check.timeout 84 | } 85 | 86 | tags = merge( 87 | { 88 | "Name" = local.metadata.name 89 | }, 90 | local.module_tags, 91 | var.tags, 92 | ) 93 | } 94 | 95 | 96 | ################################################### 97 | # Attachment for ALB Instance Target Group 98 | ################################################### 99 | 100 | # INFO: Not supported attributes 101 | # - `availability_zone` 102 | resource "aws_lb_target_group_attachment" "this" { 103 | for_each = { 104 | for target in var.targets : 105 | target.instance => target 106 | } 107 | 108 | target_group_arn = aws_lb_target_group.this.arn 109 | 110 | target_id = each.key 111 | port = try(each.value.port, var.port) 112 | } 113 | -------------------------------------------------------------------------------- /modules/nlb/outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | description = "The Amazon Resource Name (ARN) of the load balancer." 3 | value = aws_lb.this.arn 4 | } 5 | 6 | output "arn_suffix" { 7 | description = "The ARN suffix for use with CloudWatch Metrics." 8 | value = aws_lb.this.arn_suffix 9 | } 10 | 11 | output "id" { 12 | description = "The ID of the load balancer." 13 | value = aws_lb.this.id 14 | } 15 | 16 | output "name" { 17 | description = "The name of the load balancer." 18 | value = aws_lb.this.name 19 | } 20 | 21 | output "type" { 22 | description = "The type of the load balancer. Always return `NETWORK`." 23 | value = local.load_balancer_type 24 | } 25 | 26 | output "zone_id" { 27 | description = "The canonical hosted zone ID of the load balancer to be used in a Route 53 Alias record." 28 | value = aws_lb.this.zone_id 29 | } 30 | 31 | output "domain" { 32 | description = "The DNS name of the load balancer." 33 | value = aws_lb.this.dns_name 34 | } 35 | 36 | output "is_public" { 37 | description = "Indicates whether the load balancer is public." 38 | value = !aws_lb.this.internal 39 | } 40 | 41 | output "ip_address_type" { 42 | description = "The type of IP addresses used by the subnets for your load balancer." 43 | value = upper(aws_lb.this.ip_address_type) 44 | } 45 | 46 | output "availability_zone_ids" { 47 | description = "A list of the Availability Zone IDs which are used by the load balancer." 48 | value = local.availability_zone_ids 49 | } 50 | 51 | output "vpc_id" { 52 | description = "The VPC ID of the load balancer." 53 | value = aws_lb.this.vpc_id 54 | } 55 | 56 | output "subnets" { 57 | description = "A list of subnet IDs attached to the load balancer." 58 | value = aws_lb.this.subnets 59 | } 60 | 61 | output "network_mapping" { 62 | description = "The configuration for the load balancer how routes traffic to targets in which subnets and IP address settings." 63 | value = local.network_mapping 64 | } 65 | 66 | output "security_group_evaluation_on_privatelink_enabled" { 67 | description = "Whether to evaluate inbound security group rules for traffic sent to a Network Load Balancer through AWS PrivateLink." 68 | value = aws_lb.this.enforce_security_group_inbound_rules_on_private_link_traffic == "on" 69 | } 70 | 71 | output "default_security_group" { 72 | description = "The default security group ID of the load balancer." 73 | value = one(module.security_group[*].id) 74 | } 75 | 76 | output "security_groups" { 77 | description = "A set of security group IDs which is assigned to the load balancer." 78 | value = aws_lb.this.security_groups 79 | } 80 | 81 | output "access_log" { 82 | description = "The configuration for access logs of the load balancer." 83 | value = var.access_log 84 | } 85 | 86 | output "attributes" { 87 | description = "Load Balancer Attributes that applied to the network load balancer." 88 | value = { 89 | cross_zone_load_balancing_enabled = aws_lb.this.enable_cross_zone_load_balancing 90 | deletion_protection_enabled = aws_lb.this.enable_deletion_protection 91 | route53_resolver_availability_zone_affinity = var.route53_resolver_availability_zone_affinity 92 | } 93 | } 94 | 95 | output "listeners" { 96 | description = "The listeners of the network load balancer." 97 | value = module.listener 98 | } 99 | 100 | output "resource_group" { 101 | description = "The resource group created to manage resources in this module." 102 | value = merge( 103 | { 104 | enabled = var.resource_group.enabled && var.module_tags_enabled 105 | }, 106 | (var.resource_group.enabled && var.module_tags_enabled 107 | ? { 108 | arn = module.resource_group[0].arn 109 | name = module.resource_group[0].name 110 | } 111 | : {} 112 | ) 113 | ) 114 | } 115 | -------------------------------------------------------------------------------- /modules/gwlb/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | 18 | data "aws_availability_zones" "available" { 19 | state = "available" 20 | } 21 | 22 | data "aws_subnet" "this" { 23 | for_each = var.network_mapping 24 | 25 | id = each.value.subnet 26 | } 27 | 28 | locals { 29 | load_balancer_type = "GATEWAY" 30 | 31 | available_availability_zone_ids = data.aws_availability_zones.available.zone_ids 32 | network_mapping = { 33 | for zone_id in local.available_availability_zone_ids : 34 | zone_id => (contains(keys(var.network_mapping), zone_id) 35 | ? { 36 | subnet = data.aws_subnet.this[zone_id].id 37 | 38 | ipv4_cidr = data.aws_subnet.this[zone_id].cidr_block != "" ? data.aws_subnet.this[zone_id].cidr_block : null 39 | ipv6_cidr = data.aws_subnet.this[zone_id].ipv6_cidr_block != "" ? data.aws_subnet.this[zone_id].ipv6_cidr_block : null 40 | } 41 | : null 42 | ) 43 | } 44 | enabled_network_mapping = { 45 | for zone_id, config in local.network_mapping : 46 | zone_id => config 47 | if config != null 48 | } 49 | availability_zone_ids = keys(local.enabled_network_mapping) 50 | } 51 | 52 | 53 | ################################################### 54 | # Gateway Load Balancer 55 | ################################################### 56 | 57 | # INFO: Not supported attributes 58 | # - `access_logs` 59 | # - `customer_owned_ipv4_pool` 60 | # - `desync_mitigation_mode` 61 | # - `dns_record_client_routing_policy` 62 | # - `drop_invalid_header_fields` 63 | # - `enable_http2` 64 | # - `enable_tls_version_and_cipher_suite_headers` 65 | # - `enable_waf_fail_open` 66 | # - `enable_xff_client_port` 67 | # - `enforce_security_group_inbound_rules_on_private_link_traffic` 68 | # - `idle_timeout` 69 | # - `internal` 70 | # - `ip_address_type` 71 | # - `preserve_host_header` 72 | # - `security_groups` 73 | # - `subnets` 74 | # - `xff_header_processing_mode` 75 | resource "aws_lb" "this" { 76 | name = var.name 77 | 78 | load_balancer_type = lower(local.load_balancer_type) 79 | 80 | dynamic "subnet_mapping" { 81 | for_each = local.enabled_network_mapping 82 | 83 | content { 84 | subnet_id = subnet_mapping.value.subnet 85 | } 86 | } 87 | 88 | 89 | ## Attributes 90 | enable_cross_zone_load_balancing = var.cross_zone_load_balancing_enabled 91 | enable_deletion_protection = var.deletion_protection_enabled 92 | 93 | 94 | timeouts { 95 | create = var.timeouts.create 96 | update = var.timeouts.update 97 | delete = var.timeouts.delete 98 | } 99 | 100 | tags = merge( 101 | { 102 | "Name" = local.metadata.name 103 | }, 104 | local.module_tags, 105 | var.tags, 106 | ) 107 | } 108 | 109 | 110 | ################################################### 111 | # Listeners for Gateway Load Balancer 112 | ################################################### 113 | 114 | # INFO: Not supported attributes 115 | # - `alpn_policy` 116 | # - `certificate_arn` 117 | # - `port` 118 | # - `protocol` 119 | # - `ssl_policy` 120 | # - `tags` 121 | resource "aws_lb_listener" "this" { 122 | count = length(var.listeners) > 0 ? 1 : 0 123 | 124 | load_balancer_arn = aws_lb.this.arn 125 | 126 | default_action { 127 | type = "forward" 128 | target_group_arn = var.listeners[0].target_group 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /modules/nlb-ip-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the VPC which the target group belongs to." 28 | value = aws_lb_target_group.this.vpc_id 29 | } 30 | 31 | output "type" { 32 | description = "The target type of the target group." 33 | value = upper(aws_lb_target_group.this.target_type) 34 | } 35 | 36 | output "ip_address_type" { 37 | description = "The type of IP addresses used by the target group." 38 | value = upper(aws_lb_target_group.this.ip_address_type) 39 | } 40 | 41 | output "port" { 42 | description = "The port number on which the target receive trrafic." 43 | value = aws_lb_target_group.this.port 44 | } 45 | 46 | output "protocol" { 47 | description = "The protocol to use to connect with the target." 48 | value = aws_lb_target_group.this.protocol 49 | } 50 | 51 | output "targets" { 52 | description = "A set of targets in the target group." 53 | value = [ 54 | for target in aws_lb_target_group_attachment.this : { 55 | ip_address = target.target_id 56 | port = target.port 57 | is_external = target.availability_zone == "all" 58 | } 59 | ] 60 | } 61 | 62 | output "attributes" { 63 | description = "Attributes of the Instance target group of network load balancer." 64 | value = { 65 | terminate_connection_on_deregistration = aws_lb_target_group.this.connection_termination 66 | deregistration_delay = aws_lb_target_group.this.deregistration_delay 67 | load_balancing = { 68 | cross_zone_strategy = var.load_balancing.cross_zone_strategy 69 | } 70 | preserve_client_ip = aws_lb_target_group.this.preserve_client_ip 71 | proxy_protocol_v2 = aws_lb_target_group.this.proxy_protocol_v2 72 | stickiness = { 73 | enabled = aws_lb_target_group.this.stickiness[0].enabled 74 | type = upper(aws_lb_target_group.this.stickiness[0].type) 75 | } 76 | } 77 | } 78 | 79 | output "health_check" { 80 | description = "Health Check configuration of the target group." 81 | value = { 82 | protocol = aws_lb_target_group.this.health_check[0].protocol 83 | port = aws_lb_target_group.this.health_check[0].port 84 | path = aws_lb_target_group.this.health_check[0].path 85 | success_codes = aws_lb_target_group.this.health_check[0].matcher 86 | 87 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 88 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 89 | interval = aws_lb_target_group.this.health_check[0].interval 90 | timeout = aws_lb_target_group.this.health_check[0].timeout 91 | } 92 | } 93 | 94 | output "resource_group" { 95 | description = "The resource group created to manage resources in this module." 96 | value = merge( 97 | { 98 | enabled = var.resource_group.enabled && var.module_tags_enabled 99 | }, 100 | (var.resource_group.enabled && var.module_tags_enabled 101 | ? { 102 | arn = module.resource_group[0].arn 103 | name = module.resource_group[0].name 104 | } 105 | : {} 106 | ) 107 | ) 108 | } 109 | -------------------------------------------------------------------------------- /modules/alb-instance-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the VPC which the target group belongs to." 28 | value = aws_lb_target_group.this.vpc_id 29 | } 30 | 31 | output "type" { 32 | description = "The target type of the target group." 33 | value = upper(aws_lb_target_group.this.target_type) 34 | } 35 | 36 | output "port" { 37 | description = "The port number on which the target receive trrafic." 38 | value = aws_lb_target_group.this.port 39 | } 40 | 41 | output "protocol" { 42 | description = "The protocol to use to connect with the target." 43 | value = aws_lb_target_group.this.protocol 44 | } 45 | 46 | output "protocol_version" { 47 | description = "The protocol version to use to send requests to targets." 48 | value = aws_lb_target_group.this.protocol_version 49 | } 50 | 51 | output "targets" { 52 | description = "A set of targets in the target group." 53 | value = [ 54 | for target in aws_lb_target_group_attachment.this : { 55 | instance = target.target_id 56 | port = target.port 57 | } 58 | ] 59 | } 60 | 61 | output "attributes" { 62 | description = "Attributes of the Instance target group of network load balancer." 63 | value = { 64 | deregistration_delay = aws_lb_target_group.this.deregistration_delay 65 | load_balancing = { 66 | algorithm = upper(aws_lb_target_group.this.load_balancing_algorithm_type) 67 | anomaly_mitigation_enabled = (var.load_balancing.algorithm == "WEIGHTED_RANDOM" 68 | ? var.load_balancing.anomaly_mitigation_enabled 69 | : null 70 | ) 71 | cross_zone_strategy = var.load_balancing.cross_zone_strategy 72 | } 73 | slow_start_duration = aws_lb_target_group.this.slow_start 74 | stickiness = { 75 | enabled = aws_lb_target_group.this.stickiness[0].enabled 76 | type = upper(aws_lb_target_group.this.stickiness[0].type) 77 | duration = aws_lb_target_group.this.stickiness[0].cookie_duration 78 | cookie = var.stickiness_cookie 79 | } 80 | } 81 | } 82 | 83 | output "health_check" { 84 | description = "Health Check configuration of the target group." 85 | value = { 86 | protocol = aws_lb_target_group.this.health_check[0].protocol 87 | port = aws_lb_target_group.this.health_check[0].port 88 | path = aws_lb_target_group.this.health_check[0].path 89 | success_codes = aws_lb_target_group.this.health_check[0].matcher 90 | 91 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 92 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 93 | interval = aws_lb_target_group.this.health_check[0].interval 94 | timeout = aws_lb_target_group.this.health_check[0].timeout 95 | } 96 | } 97 | 98 | output "resource_group" { 99 | description = "The resource group created to manage resources in this module." 100 | value = merge( 101 | { 102 | enabled = var.resource_group.enabled && var.module_tags_enabled 103 | }, 104 | (var.resource_group.enabled && var.module_tags_enabled 105 | ? { 106 | arn = module.resource_group[0].arn 107 | name = module.resource_group[0].name 108 | } 109 | : {} 110 | ) 111 | ) 112 | } 113 | -------------------------------------------------------------------------------- /modules/gwlb-ip-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | data "aws_vpc" "this" { 18 | id = var.vpc_id 19 | } 20 | 21 | locals { 22 | ipv4_regex = "^(\\d+).(\\d+).(\\d+).(\\d+)$" 23 | 24 | ipv4_vpc_cidrs = data.aws_vpc.this.cidr_block_associations[*].cidr_block 25 | ipv6_vpc_cidrs = [data.aws_vpc.this.ipv6_cidr_block] 26 | 27 | port = 6081 28 | targets = [ 29 | for target in var.targets : { 30 | ip_address = target.ip_address 31 | port = local.port 32 | az = anytrue([ 33 | for cidr in(length(regexall(local.ipv4_regex, target.ip_address)) > 0 ? local.ipv4_vpc_cidrs : local.ipv6_vpc_cidrs) : 34 | cidr == cidrsubnet(format("%s/%s", target.ip_address, split("/", cidr)[1]), 0, 0) 35 | ]) ? null : "all" 36 | } 37 | ] 38 | } 39 | 40 | 41 | ################################################### 42 | # GWLB IP Target Group 43 | ################################################### 44 | 45 | # INFO: Not supported attributes 46 | # - `connection_termination` 47 | # - `ip_address_type` 48 | # - `lambda_multi_value_headers_enabled` 49 | # - `load_balancing_algorithm_type` 50 | # - `load_balancing_anomaly_mitigation` 51 | # - `load_balancing_cross_zone_enabled` 52 | # - `preserve_client_ip` 53 | # - `protocol_version` 54 | # - `proxy_protocol_v2` 55 | # - `slow_start` 56 | # - `stickiness` 57 | # - `tags` 58 | resource "aws_lb_target_group" "this" { 59 | name = var.name 60 | 61 | vpc_id = var.vpc_id 62 | 63 | target_type = "ip" 64 | port = local.port 65 | protocol = "GENEVE" 66 | 67 | ## Attributes 68 | deregistration_delay = var.deregistration_delay 69 | 70 | ## INFO: Too many bugs in terraform provider 71 | # - `healthy_threshold` doesn't need to be same with `unhealthy_threashold` 72 | # - `interval` doesn't apply to the acutal resource 73 | # - `timeout` is not supported 74 | dynamic "health_check" { 75 | for_each = [merge( 76 | var.health_check, 77 | var.health_check.protocol != "TCP" 78 | ? { 79 | success_codes = "200-399" 80 | } 81 | : { 82 | interval = null 83 | timeout = null 84 | success_codes = null 85 | path = null 86 | }, 87 | )] 88 | 89 | content { 90 | enabled = true 91 | 92 | protocol = health_check.value.protocol 93 | port = (health_check.value.port_override 94 | ? health_check.value.port 95 | : "traffic-port" 96 | ) 97 | path = health_check.value.path 98 | matcher = health_check.value.success_codes 99 | 100 | healthy_threshold = health_check.value.healthy_threshold 101 | unhealthy_threshold = health_check.value.unhealthy_threshold 102 | interval = health_check.value.interval 103 | timeout = health_check.value.timeout 104 | } 105 | } 106 | 107 | # INFO: Not supported on creation time. Only available on modification time. 108 | tags = merge( 109 | # { 110 | # "Name" = local.metadata.name 111 | # }, 112 | # local.module_tags, 113 | var.tags, 114 | ) 115 | } 116 | 117 | 118 | ################################################### 119 | # Attachment for GWLB IP Target Group 120 | ################################################### 121 | 122 | resource "aws_lb_target_group_attachment" "this" { 123 | for_each = { 124 | for target in local.targets : 125 | target.ip_address => target 126 | } 127 | 128 | target_group_arn = aws_lb_target_group.this.arn 129 | 130 | target_id = each.key 131 | port = each.value.port 132 | availability_zone = each.value.az 133 | } 134 | -------------------------------------------------------------------------------- /modules/alb/outputs.tf: -------------------------------------------------------------------------------- 1 | output "arn" { 2 | description = "The Amazon Resource Name (ARN) of the load balancer." 3 | value = aws_lb.this.arn 4 | } 5 | 6 | output "arn_suffix" { 7 | description = "The ARN suffix for use with CloudWatch Metrics." 8 | value = aws_lb.this.arn_suffix 9 | } 10 | 11 | output "id" { 12 | description = "The ID of the load balancer." 13 | value = aws_lb.this.id 14 | } 15 | 16 | output "name" { 17 | description = "The name of the load balancer." 18 | value = aws_lb.this.name 19 | } 20 | 21 | output "type" { 22 | description = "The type of the load balancer. Always return `APPLICATION`." 23 | value = local.load_balancer_type 24 | } 25 | 26 | output "zone_id" { 27 | description = "The canonical hosted zone ID of the load balancer to be used in a Route 53 Alias record." 28 | value = aws_lb.this.zone_id 29 | } 30 | 31 | output "domain" { 32 | description = "The DNS name of the load balancer." 33 | value = aws_lb.this.dns_name 34 | } 35 | 36 | output "is_public" { 37 | description = "Indicates whether the load balancer is public." 38 | value = !aws_lb.this.internal 39 | } 40 | 41 | output "ip_address_type" { 42 | description = "The type of IP addresses used by the subnets for your load balancer." 43 | value = upper(aws_lb.this.ip_address_type) 44 | } 45 | 46 | output "availability_zone_ids" { 47 | description = "A list of the Availability Zone IDs which are used by the load balancer." 48 | value = local.availability_zone_ids 49 | } 50 | 51 | output "vpc_id" { 52 | description = "The VPC ID of the load balancer." 53 | value = aws_lb.this.vpc_id 54 | } 55 | 56 | output "subnets" { 57 | description = "A list of subnet IDs attached to the load balancer." 58 | value = aws_lb.this.subnets 59 | } 60 | 61 | output "network_mapping" { 62 | description = "The configuration for the load balancer how routes traffic to targets in which subnets and IP address settings." 63 | value = local.network_mapping 64 | } 65 | 66 | output "default_security_group" { 67 | description = "The default security group ID of the load balancer." 68 | value = one(module.security_group[*].id) 69 | } 70 | 71 | output "security_groups" { 72 | description = "A set of security group IDs which is assigned to the load balancer." 73 | value = aws_lb.this.security_groups 74 | } 75 | 76 | output "access_log" { 77 | description = "The configuration for access logs of the load balancer." 78 | value = var.access_log 79 | } 80 | 81 | output "attributes" { 82 | description = "Load Balancer Attributes that applied to the application load balancer." 83 | value = { 84 | cross_zone_load_balancing_enabled = aws_lb.this.enable_cross_zone_load_balancing 85 | desync_mitigation_mode = upper(aws_lb.this.desync_mitigation_mode) 86 | deletion_protection_enabled = aws_lb.this.enable_deletion_protection 87 | http2_enabled = aws_lb.this.enable_http2 88 | waf_fail_open_enabled = aws_lb.this.enable_waf_fail_open 89 | idle_timeout = aws_lb.this.idle_timeout 90 | 91 | tls_negotiation_headers_enabled = aws_lb.this.enable_tls_version_and_cipher_suite_headers 92 | drop_invalid_header_fields = aws_lb.this.drop_invalid_header_fields 93 | preserve_host_header = aws_lb.this.preserve_host_header 94 | xff_header = { 95 | mode = upper(aws_lb.this.xff_header_processing_mode) 96 | client_port_preservation_enabled = aws_lb.this.enable_xff_client_port 97 | } 98 | } 99 | } 100 | 101 | output "listeners" { 102 | description = "The listeners of the application load balancer." 103 | value = module.listener 104 | } 105 | 106 | output "resource_group" { 107 | description = "The resource group created to manage resources in this module." 108 | value = merge( 109 | { 110 | enabled = var.resource_group.enabled && var.module_tags_enabled 111 | }, 112 | (var.resource_group.enabled && var.module_tags_enabled 113 | ? { 114 | arn = module.resource_group[0].arn 115 | name = module.resource_group[0].name 116 | } 117 | : {} 118 | ) 119 | ) 120 | } 121 | -------------------------------------------------------------------------------- /modules/alb-ip-target-group/outputs.tf: -------------------------------------------------------------------------------- 1 | output "load_balancers" { 2 | description = "The ARNs (Amazon Resource Name) of the load balancers associated with the target group." 3 | value = aws_lb_target_group.this.load_balancer_arns 4 | } 5 | 6 | output "arn" { 7 | description = "The Amazon Resource Name (ARN) of the target group." 8 | value = aws_lb_target_group.this.arn 9 | } 10 | 11 | output "arn_suffix" { 12 | description = "The ARN suffix for use with CloudWatch Metrics." 13 | value = aws_lb_target_group.this.arn_suffix 14 | } 15 | 16 | output "id" { 17 | description = "The ID of the target group." 18 | value = aws_lb_target_group.this.id 19 | } 20 | 21 | output "name" { 22 | description = "The name of the target group." 23 | value = aws_lb_target_group.this.name 24 | } 25 | 26 | output "vpc_id" { 27 | description = "The ID of the VPC which the target group belongs to." 28 | value = aws_lb_target_group.this.vpc_id 29 | } 30 | 31 | output "type" { 32 | description = "The target type of the target group." 33 | value = upper(aws_lb_target_group.this.target_type) 34 | } 35 | 36 | output "ip_address_type" { 37 | description = "The type of IP addresses used by the target group." 38 | value = upper(aws_lb_target_group.this.ip_address_type) 39 | } 40 | 41 | output "port" { 42 | description = "The port number on which the target receive trrafic." 43 | value = aws_lb_target_group.this.port 44 | } 45 | 46 | output "protocol" { 47 | description = "The protocol to use to connect with the target." 48 | value = aws_lb_target_group.this.protocol 49 | } 50 | 51 | output "protocol_version" { 52 | description = "The protocol version to use to send requests to targets." 53 | value = aws_lb_target_group.this.protocol_version 54 | } 55 | 56 | output "targets" { 57 | description = "A set of targets in the target group." 58 | value = [ 59 | for target in aws_lb_target_group_attachment.this : { 60 | ip_address = target.target_id 61 | port = target.port 62 | is_external = target.availability_zone == "all" 63 | } 64 | ] 65 | } 66 | 67 | output "attributes" { 68 | description = "Attributes of the Instance target group of network load balancer." 69 | value = { 70 | deregistration_delay = aws_lb_target_group.this.deregistration_delay 71 | load_balancing = { 72 | algorithm = upper(aws_lb_target_group.this.load_balancing_algorithm_type) 73 | anomaly_mitigation_enabled = (var.load_balancing.algorithm == "WEIGHTED_RANDOM" 74 | ? var.load_balancing.anomaly_mitigation_enabled 75 | : null 76 | ) 77 | cross_zone_strategy = var.load_balancing.cross_zone_strategy 78 | } 79 | slow_start_duration = aws_lb_target_group.this.slow_start 80 | stickiness = { 81 | enabled = aws_lb_target_group.this.stickiness[0].enabled 82 | type = upper(aws_lb_target_group.this.stickiness[0].type) 83 | duration = aws_lb_target_group.this.stickiness[0].cookie_duration 84 | cookie = var.stickiness_cookie 85 | } 86 | } 87 | } 88 | 89 | output "health_check" { 90 | description = "Health Check configuration of the target group." 91 | value = { 92 | protocol = aws_lb_target_group.this.health_check[0].protocol 93 | port = aws_lb_target_group.this.health_check[0].port 94 | path = aws_lb_target_group.this.health_check[0].path 95 | success_codes = aws_lb_target_group.this.health_check[0].matcher 96 | 97 | healthy_threshold = aws_lb_target_group.this.health_check[0].healthy_threshold 98 | unhealthy_threshold = aws_lb_target_group.this.health_check[0].unhealthy_threshold 99 | interval = aws_lb_target_group.this.health_check[0].interval 100 | timeout = aws_lb_target_group.this.health_check[0].timeout 101 | } 102 | } 103 | 104 | output "resource_group" { 105 | description = "The resource group created to manage resources in this module." 106 | value = merge( 107 | { 108 | enabled = var.resource_group.enabled && var.module_tags_enabled 109 | }, 110 | (var.resource_group.enabled && var.module_tags_enabled 111 | ? { 112 | arn = module.resource_group[0].arn 113 | name = module.resource_group[0].name 114 | } 115 | : {} 116 | ) 117 | ) 118 | } 119 | -------------------------------------------------------------------------------- /modules/nlb-ip-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | data "aws_vpc" "this" { 18 | id = var.vpc_id 19 | } 20 | 21 | locals { 22 | cross_zone_strategy = { 23 | "ENABLED" = "true" 24 | "DISABLED" = "false" 25 | "INHERIT" = "use_load_balancer_configuration" 26 | } 27 | 28 | ipv4_regex = "^(\\d+).(\\d+).(\\d+).(\\d+)$" 29 | 30 | ipv4_vpc_cidrs = data.aws_vpc.this.cidr_block_associations[*].cidr_block 31 | ipv6_vpc_cidrs = [data.aws_vpc.this.ipv6_cidr_block] 32 | 33 | targets = [ 34 | for target in var.targets : { 35 | ip_address = target.ip_address 36 | port = try(target.port, var.port) 37 | az = anytrue([ 38 | for cidr in(length(regexall(local.ipv4_regex, target.ip_address)) > 0 ? local.ipv4_vpc_cidrs : local.ipv6_vpc_cidrs) : 39 | cidr == cidrsubnet(format("%s/%s", target.ip_address, split("/", cidr)[1]), 0, 0) 40 | ]) ? null : "all" 41 | } 42 | ] 43 | } 44 | 45 | 46 | ################################################### 47 | # NLB IP Target Group 48 | ################################################### 49 | 50 | # INFO: Not supported attributes 51 | # - `lambda_multi_value_headers_enabled` 52 | # - `load_balancing_algorithm_type` 53 | # - `load_balancing_anomaly_mitigation` 54 | # - `protocol_version` 55 | # - `slow_start` 56 | resource "aws_lb_target_group" "this" { 57 | name = var.name 58 | 59 | vpc_id = var.vpc_id 60 | 61 | target_type = "ip" 62 | ip_address_type = lower(var.ip_address_type) 63 | port = var.port 64 | protocol = var.protocol 65 | 66 | ## Attributes 67 | connection_termination = var.terminate_connection_on_deregistration 68 | deregistration_delay = var.deregistration_delay 69 | load_balancing_cross_zone_enabled = local.cross_zone_strategy[var.load_balancing.cross_zone_strategy] 70 | preserve_client_ip = var.preserve_client_ip 71 | proxy_protocol_v2 = var.proxy_protocol_v2 72 | 73 | ## INFO: Not supported attributes 74 | # - `cookie_duration` 75 | # - `cookie_name` 76 | stickiness { 77 | enabled = var.stickiness_enabled 78 | type = "source_ip" 79 | } 80 | 81 | ## INFO: Not supported attributes 82 | # - `timeout` 83 | dynamic "health_check" { 84 | for_each = [merge( 85 | var.health_check, 86 | var.health_check.protocol != "TCP" 87 | ? { 88 | success_codes = "200-399" 89 | } 90 | : { 91 | success_codes = null 92 | path = null 93 | }, 94 | )] 95 | 96 | content { 97 | enabled = true 98 | 99 | protocol = health_check.value.protocol 100 | port = (health_check.value.port_override 101 | ? coalesce(health_check.value.port, var.port) 102 | : "traffic-port" 103 | ) 104 | path = health_check.value.path 105 | matcher = health_check.value.success_codes 106 | 107 | healthy_threshold = health_check.value.healthy_threshold 108 | unhealthy_threshold = health_check.value.unhealthy_threshold 109 | interval = health_check.value.interval 110 | } 111 | } 112 | 113 | tags = merge( 114 | { 115 | "Name" = local.metadata.name 116 | }, 117 | local.module_tags, 118 | var.tags, 119 | ) 120 | } 121 | 122 | 123 | ################################################### 124 | # Attachment for NLB IP Target Group 125 | ################################################### 126 | 127 | resource "aws_lb_target_group_attachment" "this" { 128 | for_each = { 129 | for target in local.targets : 130 | target.ip_address => target 131 | } 132 | 133 | target_group_arn = aws_lb_target_group.this.arn 134 | 135 | target_id = each.key 136 | port = each.value.port 137 | availability_zone = each.value.az 138 | } 139 | -------------------------------------------------------------------------------- /modules/alb-ip-target-group/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | metadata = { 3 | package = "terraform-aws-load-balancer" 4 | version = trimspace(file("${path.module}/../../VERSION")) 5 | module = basename(path.module) 6 | name = var.name 7 | } 8 | module_tags = var.module_tags_enabled ? { 9 | "module.terraform.io/package" = local.metadata.package 10 | "module.terraform.io/version" = local.metadata.version 11 | "module.terraform.io/name" = local.metadata.module 12 | "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" 13 | "module.terraform.io/instance" = local.metadata.name 14 | } : {} 15 | } 16 | 17 | data "aws_vpc" "this" { 18 | id = var.vpc_id 19 | } 20 | 21 | locals { 22 | cross_zone_strategy = { 23 | "ENABLED" = "true" 24 | "DISABLED" = "false" 25 | "INHERIT" = "use_load_balancer_configuration" 26 | } 27 | 28 | ipv4_regex = "^(\\d+).(\\d+).(\\d+).(\\d+)$" 29 | 30 | ipv4_vpc_cidrs = data.aws_vpc.this.cidr_block_associations[*].cidr_block 31 | ipv6_vpc_cidrs = [data.aws_vpc.this.ipv6_cidr_block] 32 | 33 | targets = [ 34 | for target in var.targets : { 35 | ip_address = target.ip_address 36 | port = try(target.port, var.port) 37 | az = anytrue([ 38 | for cidr in(length(regexall(local.ipv4_regex, target.ip_address)) > 0 ? local.ipv4_vpc_cidrs : local.ipv6_vpc_cidrs) : 39 | cidr == cidrsubnet(format("%s/%s", target.ip_address, split("/", cidr)[1]), 0, 0) 40 | ]) ? null : "all" 41 | } 42 | ] 43 | } 44 | 45 | 46 | ################################################### 47 | # ALB IP Target Group 48 | ################################################### 49 | 50 | # INFO: Not supported attributes 51 | # - `connection_termination` 52 | # - `lambda_multi_value_headers_enabled` 53 | # - `preserve_client_ip` 54 | # - `proxy_protocol_v2` 55 | resource "aws_lb_target_group" "this" { 56 | name = var.name 57 | 58 | vpc_id = var.vpc_id 59 | 60 | target_type = "ip" 61 | ip_address_type = lower(var.ip_address_type) 62 | port = var.port 63 | protocol = var.protocol 64 | protocol_version = var.protocol_version 65 | 66 | ## Attributes 67 | deregistration_delay = var.deregistration_delay 68 | load_balancing_algorithm_type = lower(var.load_balancing.algorithm) 69 | load_balancing_anomaly_mitigation = (var.load_balancing.algorithm == "WEIGHTED_RANDOM" 70 | ? var.load_balancing.anomaly_mitigation_enabled ? "on" : "off" 71 | : null 72 | ) 73 | load_balancing_cross_zone_enabled = local.cross_zone_strategy[var.load_balancing.cross_zone_strategy] 74 | slow_start = var.slow_start_duration 75 | 76 | stickiness { 77 | enabled = var.stickiness_enabled 78 | type = lower(var.stickiness_type) 79 | cookie_duration = var.stickiness_duration 80 | cookie_name = var.stickiness_type == "APP_COOKIE" ? var.stickiness_cookie : null 81 | } 82 | 83 | health_check { 84 | enabled = true 85 | 86 | protocol = var.health_check.protocol 87 | port = (var.health_check.port_override 88 | ? coalesce(var.health_check.port, var.port) 89 | : "traffic-port" 90 | ) 91 | path = (var.protocol_version != "GRPC" 92 | ? coalesce(var.health_check.path, "/") 93 | : coalesce(var.health_check.path, "/AWS.ALB/healthcheck") 94 | ) 95 | matcher = (var.protocol_version != "GRPC" 96 | ? coalesce(var.health_check.success_codes, "200") 97 | : coalesce(var.health_check.success_codes, "12") 98 | ) 99 | 100 | healthy_threshold = var.health_check.healthy_threshold 101 | unhealthy_threshold = var.health_check.unhealthy_threshold 102 | interval = var.health_check.interval 103 | timeout = var.health_check.timeout 104 | } 105 | 106 | tags = merge( 107 | { 108 | "Name" = local.metadata.name 109 | }, 110 | local.module_tags, 111 | var.tags, 112 | ) 113 | } 114 | 115 | 116 | ################################################### 117 | # Attachment for ALB IP Target Group 118 | ################################################### 119 | 120 | resource "aws_lb_target_group_attachment" "this" { 121 | for_each = { 122 | for target in local.targets : 123 | target.ip_address => target 124 | } 125 | 126 | target_group_arn = aws_lb_target_group.this.arn 127 | 128 | target_id = each.key 129 | port = each.value.port 130 | availability_zone = each.value.az 131 | } 132 | -------------------------------------------------------------------------------- /modules/nlb-listener/variables.tf: -------------------------------------------------------------------------------- 1 | variable "load_balancer" { 2 | description = "(Required) The ARN of the network load balancer to add the listener." 3 | type = string 4 | nullable = false 5 | } 6 | 7 | variable "port" { 8 | description = "(Required) The number of port on which the listener of load balancer is listening." 9 | type = number 10 | nullable = false 11 | } 12 | 13 | variable "protocol" { 14 | description = "(Required) The protocol for connections from clients to the load balancer. Valid values are `TCP`, `TLS`, `UDP` and `TCP_UDP`. Not valid to use `UDP` or `TCP_UDP` if dual-stack mode is enabled on the load balancer." 15 | type = string 16 | nullable = false 17 | 18 | validation { 19 | condition = contains(["TCP", "TLS", "UDP", "TCP_UDP"], var.protocol) 20 | error_message = "Valid values are `TCP`, `TLS`, `UDP` and `TCP_UDP`. Not valid to use `UDP` or `TCP_UDP` if dual-stack mode is enabled on the load balancer." 21 | } 22 | } 23 | 24 | variable "target_group" { 25 | description = "(Required) The ARN of the target group to which to route traffic." 26 | type = string 27 | nullable = false 28 | } 29 | 30 | # INFO: https://docs.aws.amazon.com/elasticloadbalancing/latest/network/create-tls-listener.html#describe-ssl-policies 31 | variable "tls" { 32 | description = < (contains(keys(var.network_mapping), zone_id) 35 | ? { 36 | subnet = data.aws_subnet.this[zone_id].id 37 | 38 | ipv4_cidr = data.aws_subnet.this[zone_id].cidr_block != "" ? data.aws_subnet.this[zone_id].cidr_block : null 39 | ipv6_cidr = data.aws_subnet.this[zone_id].ipv6_cidr_block != "" ? data.aws_subnet.this[zone_id].ipv6_cidr_block : null 40 | } 41 | : null 42 | ) 43 | } 44 | enabled_network_mapping = { 45 | for zone_id, config in local.network_mapping : 46 | zone_id => config 47 | if config != null 48 | } 49 | availability_zone_ids = keys(local.enabled_network_mapping) 50 | } 51 | 52 | 53 | ################################################### 54 | # Application Load Balancer 55 | ################################################### 56 | 57 | # INFO: Not supported attributes 58 | # - `customer_owned_ipv4_pool` 59 | # - `dns_record_client_routing_policy` 60 | # - `enforce_security_group_inbound_rules_on_private_link_traffic` 61 | # - `subnets` 62 | # TODO: `customer_owned_ipv4_pool` (ALB Only) 63 | resource "aws_lb" "this" { 64 | name = var.name 65 | 66 | load_balancer_type = lower(local.load_balancer_type) 67 | internal = !var.is_public 68 | ip_address_type = lower(var.ip_address_type) 69 | 70 | dynamic "subnet_mapping" { 71 | for_each = local.enabled_network_mapping 72 | 73 | content { 74 | subnet_id = subnet_mapping.value.subnet 75 | } 76 | } 77 | 78 | 79 | ## Access Control 80 | security_groups = local.security_groups 81 | 82 | 83 | ## Logging 84 | dynamic "access_logs" { 85 | for_each = var.access_log.enabled ? [var.access_log] : [] 86 | iterator = log 87 | 88 | content { 89 | enabled = log.value.enabled 90 | bucket = log.value.s3_bucket.name 91 | prefix = log.value.s3_bucket.key_prefix 92 | } 93 | } 94 | 95 | 96 | ## Attributes 97 | desync_mitigation_mode = lower(var.desync_mitigation_mode) 98 | enable_cross_zone_load_balancing = var.cross_zone_load_balancing_enabled 99 | enable_deletion_protection = var.deletion_protection_enabled 100 | enable_http2 = var.http2_enabled 101 | enable_waf_fail_open = var.waf_fail_open_enabled 102 | idle_timeout = var.idle_timeout 103 | 104 | # Headers 105 | drop_invalid_header_fields = var.drop_invalid_header_fields 106 | enable_tls_version_and_cipher_suite_headers = var.tls_negotiation_headers_enabled 107 | preserve_host_header = var.preserve_host_header 108 | enable_xff_client_port = var.xff_header.client_port_preservation_enabled 109 | xff_header_processing_mode = lower(var.xff_header.mode) 110 | 111 | 112 | timeouts { 113 | create = var.timeouts.create 114 | update = var.timeouts.update 115 | delete = var.timeouts.delete 116 | } 117 | 118 | tags = merge( 119 | { 120 | "Name" = local.metadata.name 121 | }, 122 | local.module_tags, 123 | var.tags, 124 | ) 125 | } 126 | 127 | 128 | ################################################### 129 | # Listeners for Application Load Balancer 130 | ################################################### 131 | 132 | module "listener" { 133 | source = "../alb-listener" 134 | 135 | for_each = { 136 | for listener in var.listeners : 137 | listener.port => listener 138 | } 139 | 140 | load_balancer = aws_lb.this.arn 141 | 142 | port = each.key 143 | protocol = each.value.protocol 144 | 145 | default_action_type = each.value.default_action_type 146 | default_action_parameters = each.value.default_action_parameters 147 | 148 | rules = try(each.value.rules, {}) 149 | 150 | ## TLS 151 | tls = { 152 | certificate = try(each.value.tls.certificate, null) 153 | additional_certificates = try(each.value.tls.additional_certificates, []) 154 | security_policy = try(each.value.tls.security_policy, "ELBSecurityPolicy-2016-08") 155 | } 156 | 157 | resource_group = { 158 | enabled = false 159 | } 160 | module_tags_enabled = false 161 | 162 | tags = merge( 163 | local.module_tags, 164 | var.tags, 165 | ) 166 | } 167 | -------------------------------------------------------------------------------- /modules/nlb-listener/README.md: -------------------------------------------------------------------------------- 1 | # nlb-listener 2 | 3 | This module creates following resources. 4 | 5 | - `aws_lb_listener` 6 | - `aws_lb_listener_certificate` (optional) 7 | 8 | 9 | ## Requirements 10 | 11 | | Name | Version | 12 | |------|---------| 13 | | [terraform](#requirement\_terraform) | >= 1.6 | 14 | | [aws](#requirement\_aws) | >= 5.30 | 15 | 16 | ## Providers 17 | 18 | | Name | Version | 19 | |------|---------| 20 | | [aws](#provider\_aws) | 5.30.0 | 21 | 22 | ## Modules 23 | 24 | | Name | Source | Version | 25 | |------|--------|---------| 26 | | [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 | 27 | 28 | ## Resources 29 | 30 | | Name | Type | 31 | |------|------| 32 | | [aws_lb_listener.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | 33 | | [aws_lb_listener_certificate.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_certificate) | resource | 34 | 35 | ## Inputs 36 | 37 | | Name | Description | Type | Default | Required | 38 | |------|-------------|------|---------|:--------:| 39 | | [load\_balancer](#input\_load\_balancer) | (Required) The ARN of the network load balancer to add the listener. | `string` | n/a | yes | 40 | | [port](#input\_port) | (Required) The number of port on which the listener of load balancer is listening. | `number` | n/a | yes | 41 | | [protocol](#input\_protocol) | (Required) The protocol for connections from clients to the load balancer. Valid values are `TCP`, `TLS`, `UDP` and `TCP_UDP`. Not valid to use `UDP` or `TCP_UDP` if dual-stack mode is enabled on the load balancer. | `string` | n/a | yes | 42 | | [target\_group](#input\_target\_group) | (Required) The ARN of the target group to which to route traffic. | `string` | n/a | yes | 43 | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | 44 | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | 45 | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | 46 | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | 47 | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | 48 | | [tls](#input\_tls) | (Optional) The configuration for TLS listener of the load balancer. Required if `protocol` is `TLS`. `tls` block as defined below.
(Optional) `certificate` - The ARN of the default SSL server certificate. For adding additional SSL certificates, see the `additional_certificates` variable.
(Optional) `additional_certificates` - A set of ARNs of the certificate to attach to the listener. This is for additional certificates and does not replace the default certificate on the listener.
(Optional) `security_policy` - The name of security policy for a Secure Socket Layer (SSL) negotiation configuration. This is used to negotiate SSL connections with clients. Required if protocol is `TLS`. Recommend using the `ELBSecurityPolicy-TLS13-1-2-2021-06` security policy. This security policy includes TLS 1.3, which is optimized for security and performance, and is backward compatible with TLS 1.2.
(Optional) `alpn_policy` - The policy of the Application-Layer Protocol Negotiation (ALPN) to select. ALPN is a TLS extension that includes the protocol negotiation within the exchange of hello messages. Can be set if `protocol` is `TLS`. Valid values are `HTTP1Only`, `HTTP2Only`, `HTTP2Optional`, `HTTP2Preferred`, and `None`. Defaults to `None`. |
object({
certificate = optional(string)
additional_certificates = optional(set(string), [])
security_policy = optional(string, "ELBSecurityPolicy-TLS13-1-2-2021-06")
alpn_policy = optional(string, "None")
})
| `{}` | no | 49 | 50 | ## Outputs 51 | 52 | | Name | Description | 53 | |------|-------------| 54 | | [arn](#output\_arn) | The Amazon Resource Name (ARN) of the listener. | 55 | | [default\_action](#output\_default\_action) | The default action for traffic on this listener. | 56 | | [id](#output\_id) | The ID of the listener. | 57 | | [name](#output\_name) | The name of the listener. | 58 | | [port](#output\_port) | The port number on which the listener of load balancer is listening. | 59 | | [protocol](#output\_protocol) | The protocol for connections of the listener. | 60 | | [tls](#output\_tls) | TLS configurations of the listener. | 61 | 62 | -------------------------------------------------------------------------------- /modules/gwlb-instance-target-group/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "(Required) Name of the target group. A maximum of 32 alphanumeric characters including hyphens are allowed, but the name must not begin or end with a hyphen." 3 | type = string 4 | nullable = false 5 | 6 | validation { 7 | condition = length(var.name) <= 32 8 | error_message = "The name can have a maximum of 32 characters, must contain only alphanumeric characters or hyphens, and must not begin or end with a hyphen." 9 | } 10 | } 11 | 12 | variable "vpc_id" { 13 | description = "(Required) The ID of the VPC which the target group belongs to." 14 | type = string 15 | } 16 | 17 | variable "targets" { 18 | description = <= 0 37 | error_message = "Valid value range is 0 - 3600." 38 | } 39 | } 40 | 41 | variable "health_check" { 42 | description = <= 1, 71 | var.health_check.port <= 65535, 72 | length(var.health_check.path) <= 1024, 73 | var.health_check.healthy_threshold <= 10, 74 | var.health_check.healthy_threshold >= 2, 75 | var.health_check.unhealthy_threshold <= 10, 76 | var.health_check.unhealthy_threshold >= 2, 77 | var.health_check.interval >= 5, 78 | var.health_check.interval <= 300, 79 | var.health_check.timeout >= 2, 80 | var.health_check.timeout <= 120, 81 | ]) 82 | error_message = "Not valid parameters for `health_check`." 83 | } 84 | } 85 | 86 | variable "tags" { 87 | description = "(Optional) A map of tags to add to all resources." 88 | type = map(string) 89 | default = {} 90 | nullable = false 91 | } 92 | 93 | variable "module_tags_enabled" { 94 | description = "(Optional) Whether to create AWS Resource Tags for the module informations." 95 | type = bool 96 | default = true 97 | nullable = false 98 | } 99 | 100 | 101 | ################################################### 102 | # Resource Group 103 | ################################################### 104 | 105 | 106 | 107 | 108 | variable "resource_group" { 109 | description = <= 2, 65 | var.health_check.unhealthy_threshold <= 10, 66 | var.health_check.unhealthy_threshold >= 2, 67 | var.health_check.interval >= 5, 68 | var.health_check.interval <= 300, 69 | var.health_check.timeout >= 2, 70 | var.health_check.timeout <= 120, 71 | ]) 72 | error_message = "Not valid parameters for `health_check`." 73 | } 74 | } 75 | 76 | variable "tags" { 77 | description = "(Optional) A map of tags to add to all resources." 78 | type = map(string) 79 | default = {} 80 | nullable = false 81 | } 82 | 83 | variable "module_tags_enabled" { 84 | description = "(Optional) Whether to create AWS Resource Tags for the module informations." 85 | type = bool 86 | default = true 87 | nullable = false 88 | } 89 | 90 | 91 | ################################################### 92 | # Resource Group 93 | ################################################### 94 | 95 | 96 | 97 | 98 | variable "resource_group" { 99 | description = < 0 30 | } 31 | 32 | locals { 33 | load_balancer_type = "NETWORK" 34 | 35 | available_availability_zone_ids = data.aws_availability_zones.available.zone_ids 36 | network_mapping = { 37 | for zone_id in local.available_availability_zone_ids : 38 | zone_id => (contains(keys(var.network_mapping), zone_id) 39 | ? { 40 | subnet = data.aws_subnet.this[zone_id].id 41 | 42 | ipv4_cidr = data.aws_subnet.this[zone_id].cidr_block != "" ? data.aws_subnet.this[zone_id].cidr_block : null 43 | ipv6_cidr = data.aws_subnet.this[zone_id].ipv6_cidr_block != "" ? data.aws_subnet.this[zone_id].ipv6_cidr_block : null 44 | private_ipv4_address = var.network_mapping[zone_id].private_ipv4_address 45 | ipv6_address = var.network_mapping[zone_id].ipv6_address 46 | elastic_ip = var.network_mapping[zone_id].elastic_ip 47 | } 48 | : null 49 | ) 50 | } 51 | enabled_network_mapping = { 52 | for zone_id, config in local.network_mapping : 53 | zone_id => config 54 | if config != null 55 | } 56 | availability_zone_ids = keys(local.enabled_network_mapping) 57 | 58 | route53_resolver_availability_zone_affinity = { 59 | "ANY" = "any_availability_zone" 60 | "PARTIAL" = "partial_availability_zone_affinity" 61 | "ALL" = "availability_zone_affinity" 62 | } 63 | } 64 | 65 | 66 | ################################################### 67 | # Network Load Balancer 68 | ################################################### 69 | 70 | # INFO: Not supported attributes 71 | # - `customer_owned_ipv4_pool` 72 | # - `desync_mitigation_mode` 73 | # - `drop_invalid_header_fields` 74 | # - `enable_http2` 75 | # - `enable_tls_version_and_cipher_suite_headers` 76 | # - `enable_waf_fail_open` 77 | # - `enable_xff_client_port` 78 | # - `idle_timeout` 79 | # - `preserve_host_header` 80 | # - `subnets` 81 | # - `xff_header_processing_mode` 82 | resource "aws_lb" "this" { 83 | name = var.name 84 | 85 | load_balancer_type = lower(local.load_balancer_type) 86 | internal = !var.is_public 87 | ip_address_type = lower(var.ip_address_type) 88 | 89 | dynamic "subnet_mapping" { 90 | for_each = local.enabled_network_mapping 91 | 92 | content { 93 | subnet_id = subnet_mapping.value.subnet 94 | 95 | private_ipv4_address = subnet_mapping.value.private_ipv4_address 96 | ipv6_address = subnet_mapping.value.ipv6_address 97 | allocation_id = subnet_mapping.value.elastic_ip 98 | } 99 | } 100 | 101 | 102 | ## Access Control 103 | enforce_security_group_inbound_rules_on_private_link_traffic = (length(local.security_groups) > 0 104 | ? (var.security_group_evaluation_on_privatelink_enabled ? "on" : "off") 105 | : null 106 | ) 107 | security_groups = local.security_groups 108 | 109 | 110 | ## Logging 111 | dynamic "access_logs" { 112 | for_each = var.access_log.enabled ? [var.access_log] : [] 113 | iterator = log 114 | 115 | content { 116 | enabled = log.value.enabled 117 | bucket = log.value.s3_bucket.name 118 | prefix = log.value.s3_bucket.key_prefix 119 | } 120 | } 121 | 122 | 123 | ## Attributes 124 | dns_record_client_routing_policy = local.route53_resolver_availability_zone_affinity[var.route53_resolver_availability_zone_affinity] 125 | enable_cross_zone_load_balancing = var.cross_zone_load_balancing_enabled 126 | enable_deletion_protection = var.deletion_protection_enabled 127 | 128 | 129 | timeouts { 130 | create = var.timeouts.create 131 | update = var.timeouts.update 132 | delete = var.timeouts.delete 133 | } 134 | 135 | tags = merge( 136 | { 137 | "Name" = local.metadata.name 138 | }, 139 | local.module_tags, 140 | var.tags, 141 | ) 142 | 143 | lifecycle { 144 | replace_triggered_by = [ 145 | terraform_data.replace_trigger, 146 | ] 147 | } 148 | } 149 | 150 | 151 | ################################################### 152 | # Listeners for Network Load Balancer 153 | ################################################### 154 | 155 | module "listener" { 156 | source = "../nlb-listener" 157 | 158 | for_each = { 159 | for listener in var.listeners : 160 | listener.port => listener 161 | } 162 | 163 | load_balancer = aws_lb.this.arn 164 | 165 | port = each.key 166 | protocol = each.value.protocol 167 | target_group = each.value.target_group 168 | 169 | ## TLS 170 | tls = { 171 | certificate = each.value.tls.certificate 172 | additional_certificates = each.value.tls.additional_certificates 173 | security_policy = each.value.tls.security_policy 174 | alpn_policy = each.value.tls.alpn_policy 175 | } 176 | 177 | resource_group = { 178 | enabled = false 179 | } 180 | module_tags_enabled = false 181 | 182 | tags = merge( 183 | local.module_tags, 184 | var.tags, 185 | ) 186 | } 187 | -------------------------------------------------------------------------------- /modules/nlb-alb-target-group/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | description = "(Required) Name of the target group. A maximum of 32 alphanumeric characters including hyphens are allowed, but the name must not begin or end with a hyphen." 3 | type = string 4 | nullable = false 5 | 6 | validation { 7 | condition = length(var.name) <= 32 8 | error_message = "The name can have a maximum of 32 characters, must contain only alphanumeric characters or hyphens, and must not begin or end with a hyphen." 9 | } 10 | } 11 | 12 | variable "vpc_id" { 13 | description = "(Required) The ID of the VPC which the target group belongs to." 14 | type = string 15 | } 16 | 17 | variable "port" { 18 | description = "(Optional) The port number on which the targets receive traffic. Valid values are either ports 1-65535." 19 | type = number 20 | nullable = false 21 | 22 | validation { 23 | condition = alltrue([ 24 | var.port >= 1, 25 | var.port <= 65535, 26 | ]) 27 | error_message = "Valid values are either ports 1-65535." 28 | } 29 | } 30 | 31 | variable "targets" { 32 | description = <= 1, 77 | coalesce(var.health_check.port, 80) <= 65535, 78 | length(var.health_check.path) <= 1024, 79 | var.health_check.healthy_threshold <= 10, 80 | var.health_check.healthy_threshold >= 2, 81 | var.health_check.unhealthy_threshold <= 10, 82 | var.health_check.unhealthy_threshold >= 2, 83 | contains([10, 30], var.health_check.interval), 84 | ]) 85 | error_message = "Not valid parameters for `health_check`." 86 | } 87 | } 88 | 89 | variable "tags" { 90 | description = "(Optional) A map of tags to add to all resources." 91 | type = map(string) 92 | default = {} 93 | nullable = false 94 | } 95 | 96 | variable "module_tags_enabled" { 97 | description = "(Optional) Whether to create AWS Resource Tags for the module informations." 98 | type = bool 99 | default = true 100 | nullable = false 101 | } 102 | 103 | 104 | ################################################### 105 | # Resource Group 106 | ################################################### 107 | 108 | 109 | 110 | 111 | variable "resource_group" { 112 | description = <= 0 37 | error_message = "Valid value range is 0 - 3600." 38 | } 39 | } 40 | 41 | variable "health_check" { 42 | description = <= 1, 71 | var.health_check.port <= 65535, 72 | length(var.health_check.path) <= 1024, 73 | var.health_check.healthy_threshold <= 10, 74 | var.health_check.healthy_threshold >= 2, 75 | var.health_check.unhealthy_threshold <= 10, 76 | var.health_check.unhealthy_threshold >= 2, 77 | var.health_check.interval >= 5, 78 | var.health_check.interval <= 300, 79 | var.health_check.timeout >= 2, 80 | var.health_check.timeout <= 120, 81 | ]) 82 | error_message = "Not valid parameters for `health_check`." 83 | } 84 | } 85 | 86 | variable "tags" { 87 | description = "(Optional) A map of tags to add to all resources." 88 | type = map(string) 89 | default = {} 90 | nullable = false 91 | } 92 | 93 | variable "module_tags_enabled" { 94 | description = "(Optional) Whether to create AWS Resource Tags for the module informations." 95 | type = bool 96 | default = true 97 | nullable = false 98 | } 99 | 100 | 101 | ################################################### 102 | # Resource Group 103 | ################################################### 104 | 105 | 106 | 107 | 108 | variable "resource_group" { 109 | description = < { 35 | subnet = subnet.id 36 | } 37 | } 38 | 39 | default_security_group = { 40 | enabled = true 41 | name = "tedilabs-alb-instance" 42 | description = "Managed by Terraform." 43 | 44 | listener_ingress_ipv4_cidrs = ["10.0.0.0/8", "172.31.0.0/16"] 45 | } 46 | security_groups = [] 47 | 48 | ## Attributes 49 | desync_mitigation_mode = "DEFENSIVE" 50 | drop_invalid_header_fields = false 51 | deletion_protection_enabled = false 52 | http2_enabled = true 53 | waf_fail_open_enabled = false 54 | idle_timeout = 60 55 | 56 | listeners = [ 57 | { 58 | port = 80 59 | protocol = "HTTP" 60 | default_action_type = "REDIRECT_301" 61 | default_action_parameters = { 62 | protocol = "HTTPS" 63 | port = 443 64 | } 65 | }, 66 | { 67 | port = 8080 68 | protocol = "HTTP" 69 | default_action_type = "FIXED_RESPONSE" 70 | default_action_parameters = { 71 | content_type = "application/json" 72 | status_code = 404 73 | data = < { 35 | subnet = subnet.id 36 | } 37 | } 38 | 39 | default_security_group = { 40 | enabled = true 41 | name = "tedilabs-alb-ip" 42 | description = "Managed by Terraform." 43 | 44 | listener_ingress_ipv4_cidrs = ["10.0.0.0/8", "172.31.0.0/16"] 45 | } 46 | security_groups = [] 47 | 48 | ## Attributes 49 | desync_mitigation_mode = "DEFENSIVE" 50 | drop_invalid_header_fields = false 51 | deletion_protection_enabled = false 52 | http2_enabled = true 53 | waf_fail_open_enabled = false 54 | idle_timeout = 60 55 | 56 | listeners = [ 57 | { 58 | port = 80 59 | protocol = "HTTP" 60 | default_action_type = "REDIRECT_301" 61 | default_action_parameters = { 62 | protocol = "HTTPS" 63 | port = 443 64 | } 65 | }, 66 | { 67 | port = 8080 68 | protocol = "HTTP" 69 | default_action_type = "FIXED_RESPONSE" 70 | default_action_parameters = { 71 | content_type = "application/json" 72 | status_code = 404 73 | data = < 9 | ## Requirements 10 | 11 | | Name | Version | 12 | |------|---------| 13 | | [terraform](#requirement\_terraform) | >= 1.6 | 14 | | [aws](#requirement\_aws) | >= 5.30 | 15 | 16 | ## Providers 17 | 18 | | Name | Version | 19 | |------|---------| 20 | | [aws](#provider\_aws) | 5.30.0 | 21 | 22 | ## Modules 23 | 24 | | Name | Source | Version | 25 | |------|--------|---------| 26 | | [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 | 27 | 28 | ## Resources 29 | 30 | | Name | Type | 31 | |------|------| 32 | | [aws_lb.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb) | resource | 33 | | [aws_lb_listener.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener) | resource | 34 | | [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | 35 | | [aws_subnet.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet) | data source | 36 | 37 | ## Inputs 38 | 39 | | Name | Description | Type | Default | Required | 40 | |------|-------------|------|---------|:--------:| 41 | | [name](#input\_name) | (Required) The name of the load balancer. This name must be unique within your AWS account, can have a maximum of 32 characters, must contain only alphanumeric characters or hyphens, and must not begin or end with a hyphen. | `string` | n/a | yes | 42 | | [cross\_zone\_load\_balancing\_enabled](#input\_cross\_zone\_load\_balancing\_enabled) | (Optional) Cross-zone load balancing distributes traffic evenly across all targets in the Availability Zones enabled for the load balancer. Indicates whether to enable cross-zone load balancing. Defaults to `false`. Regional data transfer charges may apply when cross-zone load balancing is enabled. | `bool` | `false` | no | 43 | | [deletion\_protection\_enabled](#input\_deletion\_protection\_enabled) | (Optional) Indicates whether deletion of the load balancer via the AWS API will be protected. Defaults to `false`. | `bool` | `false` | no | 44 | | [listeners](#input\_listeners) | (Optional) A list of listener configurations of the gateway load balancer. Listeners listen for connection requests using their `protocol` and `port`. Each value of `listener` block as defined below.
(Required) `port` - The number of port on which the listener of load balancer is listening. Must be `6081`.
(Required) `target_group` - The ARN of the target group to which to route traffic. |
list(object({
port = number
target_group = string
}))
| `[]` | no | 45 | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | 46 | | [network\_mapping](#input\_network\_mapping) | (Optional) The configuration for the load balancer how routes traffic to targets in which subnets, and in accordance with IP address settings. Select at least one Availability Zone and one subnet for each zone. We recommend selecting at least two Availability Zones. The load balancer will route traffic only to targets in the selected Availability Zones. Zones that are not supported by the load balancer or VPC cannot be selected. Subnets can be added, but not removed, once a load balancer is created. Each key of `network_mapping` is the availability zone id like `apne2-az1`, `use1-az1`. Each value of `network_mapping` block as defined below.
(Required) `subnet` - The id of the subnet of which to attach to the load balancer. You can specify only one subnet per Availability Zone. |
map(object({
subnet = string
}))
| `{}` | no | 47 | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | 48 | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | 49 | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | 50 | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | 51 | | [timeouts](#input\_timeouts) | (Optional) How long to wait for the load balancer to be created/updated/deleted. |
object({
create = optional(string, "10m")
update = optional(string, "10m")
delete = optional(string, "10m")
})
| `{}` | no | 52 | 53 | ## Outputs 54 | 55 | | Name | Description | 56 | |------|-------------| 57 | | [arn](#output\_arn) | The Amazon Resource Name (ARN) of the load balancer. | 58 | | [arn\_suffix](#output\_arn\_suffix) | The ARN suffix for use with CloudWatch Metrics. | 59 | | [attributes](#output\_attributes) | Load Balancer Attributes that applied to the gateway load balancer. | 60 | | [availability\_zone\_ids](#output\_availability\_zone\_ids) | A list of the Availability Zone IDs which are used by the load balancer. | 61 | | [id](#output\_id) | The ID of the load balancer. | 62 | | [listeners](#output\_listeners) | Listeners of the load balancer. | 63 | | [name](#output\_name) | The name of the load balancer. | 64 | | [network\_mapping](#output\_network\_mapping) | The configuration for the load balancer how routes traffic to targets in which subnets and IP address settings. | 65 | | [subnets](#output\_subnets) | A list of subnet IDs attached to the load balancer. | 66 | | [type](#output\_type) | The type of the load balancer. Always return `GATEWAY`. | 67 | | [vpc\_id](#output\_vpc\_id) | The VPC ID of the load balancer. | 68 | 69 | -------------------------------------------------------------------------------- /modules/gwlb-instance-target-group/README.md: -------------------------------------------------------------------------------- 1 | # gwlb-instance-target-group 2 | 3 | This module creates following resources. 4 | 5 | - `aws_lb_target_group` 6 | - `aws_lb_target_group_attachment` (optional) 7 | 8 | 9 | ## Requirements 10 | 11 | | Name | Version | 12 | |------|---------| 13 | | [terraform](#requirement\_terraform) | >= 1.6 | 14 | | [aws](#requirement\_aws) | >= 5.38 | 15 | 16 | ## Providers 17 | 18 | | Name | Version | 19 | |------|---------| 20 | | [aws](#provider\_aws) | 5.58.0 | 21 | 22 | ## Modules 23 | 24 | | Name | Source | Version | 25 | |------|--------|---------| 26 | | [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 | 27 | 28 | ## Resources 29 | 30 | | Name | Type | 31 | |------|------| 32 | | [aws_lb_target_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource | 33 | | [aws_lb_target_group_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group_attachment) | resource | 34 | 35 | ## Inputs 36 | 37 | | Name | Description | Type | Default | Required | 38 | |------|-------------|------|---------|:--------:| 39 | | [name](#input\_name) | (Required) Name of the target group. A maximum of 32 alphanumeric characters including hyphens are allowed, but the name must not begin or end with a hyphen. | `string` | n/a | yes | 40 | | [vpc\_id](#input\_vpc\_id) | (Required) The ID of the VPC which the target group belongs to. | `string` | n/a | yes | 41 | | [deregistration\_delay](#input\_deregistration\_delay) | (Optional) The time to wait for in-flight requests to complete while deregistering a target. During this time, the state of the target is draining. | `number` | `300` | no | 42 | | [health\_check](#input\_health\_check) | (Optional) Health Check configuration block. The associated load balancer periodically sends requests to the registered targets to test their status. `health_check` block as defined below.
(Optional) `protocol` - Protocol to use to connect with the target. The possible values are `TCP`, `HTTP` and `HTTPS`. Defaults to `TCP`.
(Optional) `port` - The port the load balancer uses when performing health checks on targets. The default is `80`. Valid values are either ports 1-65535.
(Optional) `port_override` - Whether to override the port on which each target receives trafficfrom the load balancer to a different port. Defaults to `true`.
(Optional) `path` - Use the default path of `/` to ping the root, or specify a custom path if preferred. Only valid if the `protocol` is `HTTP` or `HTTPS`.
(Optional) `healthy_threshold` - The number of consecutive health checks successes required before considering an unhealthy target healthy. Valid value range is 2 - 10. Defaults to `3`.
(Optional) `unhealthy_threshold` - The number of consecutive health check failures required before considering a target unhealthy. Valid value range is 2 - 10. Defaults to `3`.
(Optional) `interval` - Approximate amount of time, in seconds, between health checks of an individual target. Valid value range is 5 - 300. Defaults to `10`.
(Optional) `timeout` - The amount of time, in seconds, during which no response means a failed health check. Valid value range is 2 - 120. Defaults to `5`. |
object({
protocol = optional(string, "TCP")
port = optional(number, 80)
port_override = optional(bool, true)
path = optional(string, "/")

healthy_threshold = optional(number, 3)
unhealthy_threshold = optional(number, 3)
interval = optional(number, 10)
timeout = optional(number, 5)
})
| `{}` | no | 43 | | [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | 44 | | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | 45 | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | 46 | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | 47 | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | 48 | | [targets](#input\_targets) | (Optional) A set of targets to add to the target group. Each value of `targets` block as defined below.
(Required) `instance` - This is the Instance ID for an instance, or the container ID for an ECS container. |
set(object({
instance = string
}))
| `[]` | no | 49 | 50 | ## Outputs 51 | 52 | | Name | Description | 53 | |------|-------------| 54 | | [arn](#output\_arn) | The Amazon Resource Name (ARN) of the target group. | 55 | | [arn\_suffix](#output\_arn\_suffix) | The ARN suffix for use with CloudWatch Metrics. | 56 | | [attributes](#output\_attributes) | Attributes of the Instance target group of gateway load balancer. | 57 | | [health\_check](#output\_health\_check) | Health Check configuration of the target group. | 58 | | [id](#output\_id) | The ID of the target group. | 59 | | [load\_balancers](#output\_load\_balancers) | The ARNs (Amazon Resource Name) of the load balancers associated with the target group. | 60 | | [name](#output\_name) | The name of the target group. | 61 | | [port](#output\_port) | The port number on which the target receive trrafic. | 62 | | [protocol](#output\_protocol) | The protocol to use to connect with the target. | 63 | | [targets](#output\_targets) | A set of targets in the target group. | 64 | | [type](#output\_type) | The target type of the target group. | 65 | | [vpc\_id](#output\_vpc\_id) | The ID of the VPC which the target group belongs to. | 66 | 67 | --------------------------------------------------------------------------------