diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 75deea3..a8206b6 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
- rev: v1.77.0
+ rev: v1.77.1
hooks:
- id: terraform_fmt
- id: terraform_wrapper_module_for_each
diff --git a/README.md b/README.md
index 1e900cc..7726d4e 100644
--- a/README.md
+++ b/README.md
@@ -320,6 +320,8 @@ No modules.
| [aws_lb_listener_rule.https_listener_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule) | resource |
| [aws_lb_target_group.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group) | resource |
| [aws_lb_target_group_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_target_group_attachment) | resource |
+| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
+| [aws_security_group_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource |
## Inputs
@@ -327,6 +329,7 @@ No modules.
|------|-------------|------|---------|:--------:|
| [access\_logs](#input\_access\_logs) | Map containing access logging configuration for load balancer. | `map(string)` | `{}` | no |
| [create\_lb](#input\_create\_lb) | Controls if the Load Balancer should be created | `bool` | `true` | no |
+| [create\_security\_group](#input\_create\_security\_group) | Determines if a security group is created | `bool` | `true` | no |
| [desync\_mitigation\_mode](#input\_desync\_mitigation\_mode) | Determines how the load balancer handles requests that might pose a security risk to an application due to HTTP desync. | `string` | `"defensive"` | no |
| [drop\_invalid\_header\_fields](#input\_drop\_invalid\_header\_fields) | Indicates whether invalid header fields are dropped in application load balancers. Defaults to false. | `bool` | `false` | no |
| [enable\_cross\_zone\_load\_balancing](#input\_enable\_cross\_zone\_load\_balancing) | Indicates whether cross zone load balancing should be enabled in application load balancers. | `bool` | `false` | no |
@@ -355,6 +358,11 @@ No modules.
| [name\_prefix](#input\_name\_prefix) | The resource name prefix and Name tag of the load balancer. Cannot be longer than 6 characters | `string` | `null` | no |
| [preserve\_host\_header](#input\_preserve\_host\_header) | Indicates whether Host header should be preserve and forward to targets without any change. Defaults to false. | `bool` | `false` | no |
| [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no |
+| [security\_group\_description](#input\_security\_group\_description) | Description of the security group created | `string` | `null` | no |
+| [security\_group\_name](#input\_security\_group\_name) | Name to use on security group created | `string` | `null` | no |
+| [security\_group\_rules](#input\_security\_group\_rules) | Security group rules to add to the security group created | `any` | `{}` | no |
+| [security\_group\_tags](#input\_security\_group\_tags) | A map of additional tags to add to the security group created | `map(string)` | `{}` | no |
+| [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`security_group_name`) is used as a prefix | `bool` | `true` | no |
| [security\_groups](#input\_security\_groups) | The security groups to attach to the load balancer. e.g. ["sg-edcd9784","sg-edcd9785"] | `list(string)` | `[]` | no |
| [subnet\_mapping](#input\_subnet\_mapping) | A list of subnet mapping blocks describing subnets to attach to network load balancer | `list(map(string))` | `[]` | no |
| [subnets](#input\_subnets) | A list of subnets to associate with the load balancer. e.g. ['subnet-1a2b3c4d','subnet-1a2b3c4e','subnet-1a2b3c4f'] | `list(string)` | `null` | no |
@@ -376,6 +384,8 @@ No modules.
| [lb\_dns\_name](#output\_lb\_dns\_name) | The DNS name of the load balancer |
| [lb\_id](#output\_lb\_id) | The ID and ARN of the load balancer we created |
| [lb\_zone\_id](#output\_lb\_zone\_id) | The zone\_id of the load balancer to assist with creating DNS records |
+| [security\_group\_arn](#output\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group |
+| [security\_group\_id](#output\_security\_group\_id) | ID of the security group |
| [target\_group\_arn\_suffixes](#output\_target\_group\_arn\_suffixes) | ARN suffixes of our target groups - can be used with CloudWatch |
| [target\_group\_arns](#output\_target\_group\_arns) | ARNs of the target groups. Useful for passing to your Auto Scaling group |
| [target\_group\_attachments](#output\_target\_group\_attachments) | ARNs of the target group attachment IDs |
diff --git a/examples/complete-alb/README.md b/examples/complete-alb/README.md
index 4574e5b..5ce1cc9 100644
--- a/examples/complete-alb/README.md
+++ b/examples/complete-alb/README.md
@@ -22,7 +22,6 @@ Note that this example may create resources which cost money. Run `terraform des
| [terraform](#requirement\_terraform) | >= 1.0 |
| [aws](#requirement\_aws) | >= 4.27 |
| [null](#requirement\_null) | >= 2.0 |
-| [random](#requirement\_random) | >= 2.0 |
## Providers
@@ -30,7 +29,6 @@ Note that this example may create resources which cost money. Run `terraform des
|------|---------|
| [aws](#provider\_aws) | >= 4.27 |
| [null](#provider\_null) | >= 2.0 |
-| [random](#provider\_random) | >= 2.0 |
## Modules
@@ -41,7 +39,7 @@ Note that this example may create resources which cost money. Run `terraform des
| [lambda\_with\_allowed\_triggers](#module\_lambda\_with\_allowed\_triggers) | terraform-aws-modules/lambda/aws | ~> 3.0 |
| [lambda\_without\_allowed\_triggers](#module\_lambda\_without\_allowed\_triggers) | terraform-aws-modules/lambda/aws | ~> 3.0 |
| [lb\_disabled](#module\_lb\_disabled) | ../../ | n/a |
-| [security\_group](#module\_security\_group) | terraform-aws-modules/security-group/aws | ~> 4.0 |
+| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 |
| [wildcard\_cert](#module\_wildcard\_cert) | terraform-aws-modules/acm/aws | ~> 3.0 |
## Resources
@@ -53,11 +51,9 @@ Note that this example may create resources which cost money. Run `terraform des
| [aws_cognito_user_pool_domain.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_user_pool_domain) | resource |
| [aws_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource |
| [null_resource.download_package](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
-| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
+| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_route53_zone.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
-| [aws_subnets.all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
-| [aws_vpc.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |
## Inputs
@@ -76,6 +72,8 @@ No inputs.
| [lb\_dns\_name](#output\_lb\_dns\_name) | The DNS name of the load balancer. |
| [lb\_id](#output\_lb\_id) | The ID and ARN of the load balancer we created. |
| [lb\_zone\_id](#output\_lb\_zone\_id) | The zone\_id of the load balancer to assist with creating DNS records. |
+| [security\_group\_arn](#output\_security\_group\_arn) | Amazon Resource Name (ARN) of the security group |
+| [security\_group\_id](#output\_security\_group\_id) | ID of the security group |
| [target\_group\_arn\_suffixes](#output\_target\_group\_arn\_suffixes) | ARN suffixes of our target groups - can be used with CloudWatch. |
| [target\_group\_arns](#output\_target\_group\_arns) | ARNs of the target groups. Useful for passing to your Auto Scaling group. |
| [target\_group\_attachments](#output\_target\_group\_attachments) | ARNs of the target group attachment IDs. |
diff --git a/examples/complete-alb/main.tf b/examples/complete-alb/main.tf
index d7b2317..d363f1c 100644
--- a/examples/complete-alb/main.tf
+++ b/examples/complete-alb/main.tf
@@ -1,107 +1,66 @@
provider "aws" {
- region = "eu-west-1"
-}
-
-locals {
- domain_name = "terraform-aws-modules.modules.tf"
-}
-
-##################################################################
-# Data sources to get VPC and subnets
-##################################################################
-data "aws_vpc" "default" {
- default = true
-}
-
-data "aws_subnets" "all" {
- filter {
- name = "vpc-id"
- values = [data.aws_vpc.default.id]
- }
-}
-
-resource "random_pet" "this" {
- length = 2
-}
-
-data "aws_route53_zone" "this" {
- name = local.domain_name
+ region = local.region
}
-module "security_group" {
- source = "terraform-aws-modules/security-group/aws"
- version = "~> 4.0"
-
- name = "alb-sg-${random_pet.this.id}"
- description = "Security group for example usage with ALB"
- vpc_id = data.aws_vpc.default.id
-
- ingress_cidr_blocks = ["0.0.0.0/0"]
- ingress_rules = ["http-80-tcp", "all-icmp"]
- egress_rules = ["all-all"]
-}
+data "aws_availability_zones" "available" {}
-#module "log_bucket" {
-# source = "terraform-aws-modules/s3-bucket/aws"
-# version = "~> 3.0"
-#
-# bucket = "logs-${random_pet.this.id}"
-# acl = "log-delivery-write"
-# force_destroy = true
-# attach_elb_log_delivery_policy = true
-#}
-
-module "acm" {
- source = "terraform-aws-modules/acm/aws"
- version = "~> 3.0"
-
- domain_name = local.domain_name # trimsuffix(data.aws_route53_zone.this.name, ".")
- zone_id = data.aws_route53_zone.this.id
-}
+locals {
+ name = "ex-${basename(path.cwd)}"
+ region = "eu-west-1"
-module "wildcard_cert" {
- source = "terraform-aws-modules/acm/aws"
- version = "~> 3.0"
+ vpc_cidr = "10.0.0.0/16"
+ azs = slice(data.aws_availability_zones.available.names, 0, 3)
- domain_name = "*.${local.domain_name}" # trimsuffix(data.aws_route53_zone.this.name, ".")
- zone_id = data.aws_route53_zone.this.id
-}
-
-##################################################################
-# AWS Cognito User Pool
-##################################################################
-resource "aws_cognito_user_pool" "this" {
- name = "user-pool-${random_pet.this.id}"
-}
-
-resource "aws_cognito_user_pool_client" "this" {
- name = "user-pool-client-${random_pet.this.id}"
- user_pool_id = aws_cognito_user_pool.this.id
- generate_secret = true
- allowed_oauth_flows = ["code", "implicit"]
- callback_urls = ["https://${local.domain_name}/callback"]
- allowed_oauth_scopes = ["email", "openid"]
- allowed_oauth_flows_user_pool_client = true
-}
+ domain_name = "terraform-aws-modules.modules.tf"
-resource "aws_cognito_user_pool_domain" "this" {
- domain = random_pet.this.id
- user_pool_id = aws_cognito_user_pool.this.id
+ tags = {
+ Example = local.name
+ GithubRepo = "terraform-aws-alb"
+ GithubOrg = "terraform-aws-modules"
+ }
}
##################################################################
# Application Load Balancer
##################################################################
+
module "alb" {
source = "../../"
- name = "complete-alb-${random_pet.this.id}"
+ name = local.name
load_balancer_type = "application"
- vpc_id = data.aws_vpc.default.id
- security_groups = [module.security_group.security_group_id]
- subnets = data.aws_subnets.all.ids
+ vpc_id = module.vpc.vpc_id
+ subnets = module.vpc.public_subnets
+ # Attach security groups
+ security_groups = [module.vpc.default_security_group_id]
+ # Attach rules to the created security group
+ security_group_rules = {
+ ingress_all_http = {
+ type = "ingress"
+ from_port = 80
+ to_port = 80
+ protocol = "http"
+ description = "HTTP web traffic"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ ingress_all_icmp = {
+ type = "ingress"
+ from_port = -1
+ to_port = -1
+ protocol = "icmp"
+ description = "ICMP"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ egress_all = {
+ type = "egress"
+ from_port = 0
+ to_port = 0
+ protocol = "-1"
+ cidr_blocks = ["0.0.0.0/0"]
+ }
+ }
# # See notes in README (ref: https://github.com/terraform-providers/terraform-provider-aws/issues/7987)
# access_logs = {
@@ -158,7 +117,7 @@ module "alb" {
prompt = "login"
}
on_unauthenticated_request = "authenticate"
- session_cookie_name = "session-${random_pet.this.id}"
+ session_cookie_name = "session-${local.name}"
session_timeout = 3600
user_pool_arn = aws_cognito_user_pool.this.arn
user_pool_client_id = aws_cognito_user_pool_client.this.id
@@ -202,7 +161,7 @@ module "alb" {
type = "authenticate-cognito"
on_unauthenticated_request = "authenticate"
- session_cookie_name = "session-${random_pet.this.id}"
+ session_cookie_name = "session-${local.name}"
session_timeout = 3600
user_pool_arn = aws_cognito_user_pool.this.arn
user_pool_client_id = aws_cognito_user_pool_client.this.id
@@ -465,6 +424,7 @@ module "alb" {
#########################
# LB will not be created
#########################
+
module "lb_disabled" {
source = "../../"
@@ -474,6 +434,7 @@ module "lb_disabled" {
##################
# Extra resources
##################
+
data "aws_ami" "amazon_linux" {
most_recent = true
@@ -524,7 +485,7 @@ module "lambda_with_allowed_triggers" {
source = "terraform-aws-modules/lambda/aws"
version = "~> 3.0"
- function_name = "${random_pet.this.id}-with-allowed-triggers"
+ function_name = "${local.name}-with-allowed-triggers"
description = "My awesome lambda function (with allowed triggers)"
handler = "index.lambda_handler"
runtime = "python3.8"
@@ -548,7 +509,7 @@ module "lambda_without_allowed_triggers" {
source = "terraform-aws-modules/lambda/aws"
version = "~> 3.0"
- function_name = "${random_pet.this.id}-without-allowed-triggers"
+ function_name = "${local.name}-without-allowed-triggers"
description = "My awesome lambda function (without allowed triggers)"
handler = "index.lambda_handler"
runtime = "python3.8"
@@ -563,3 +524,68 @@ module "lambda_without_allowed_triggers" {
depends_on = [null_resource.download_package]
}
+
+##################################################################
+# Data sources to get VPC and subnets
+##################################################################
+
+module "vpc" {
+ source = "terraform-aws-modules/vpc/aws"
+ version = "~> 3.0"
+
+ name = local.name
+ cidr = local.vpc_cidr
+
+ azs = local.azs
+ private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
+ public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
+
+ enable_nat_gateway = true
+ single_nat_gateway = true
+ enable_dns_hostnames = true
+
+ tags = local.tags
+}
+
+data "aws_route53_zone" "this" {
+ name = local.domain_name
+}
+
+module "acm" {
+ source = "terraform-aws-modules/acm/aws"
+ version = "~> 3.0"
+
+ domain_name = local.domain_name # trimsuffix(data.aws_route53_zone.this.name, ".")
+ zone_id = data.aws_route53_zone.this.id
+}
+
+module "wildcard_cert" {
+ source = "terraform-aws-modules/acm/aws"
+ version = "~> 3.0"
+
+ domain_name = "*.${local.domain_name}" # trimsuffix(data.aws_route53_zone.this.name, ".")
+ zone_id = data.aws_route53_zone.this.id
+}
+
+##################################################################
+# AWS Cognito User Pool
+##################################################################
+
+resource "aws_cognito_user_pool" "this" {
+ name = "user-pool-${local.name}"
+}
+
+resource "aws_cognito_user_pool_client" "this" {
+ name = "user-pool-client-${local.name}"
+ user_pool_id = aws_cognito_user_pool.this.id
+ generate_secret = true
+ allowed_oauth_flows = ["code", "implicit"]
+ callback_urls = ["https://${local.domain_name}/callback"]
+ allowed_oauth_scopes = ["email", "openid"]
+ allowed_oauth_flows_user_pool_client = true
+}
+
+resource "aws_cognito_user_pool_domain" "this" {
+ domain = local.name
+ user_pool_id = aws_cognito_user_pool.this.id
+}
diff --git a/examples/complete-alb/outputs.tf b/examples/complete-alb/outputs.tf
index 864b493..f80e8b5 100644
--- a/examples/complete-alb/outputs.tf
+++ b/examples/complete-alb/outputs.tf
@@ -62,3 +62,17 @@ output "target_group_attachments" {
description = "ARNs of the target group attachment IDs."
value = module.alb.target_group_attachments
}
+
+################################################################################
+# Security Group
+################################################################################
+
+output "security_group_arn" {
+ description = "Amazon Resource Name (ARN) of the security group"
+ value = module.alb.security_group_arn
+}
+
+output "security_group_id" {
+ description = "ID of the security group"
+ value = module.alb.security_group_id
+}
diff --git a/examples/complete-alb/versions.tf b/examples/complete-alb/versions.tf
index e5fe0c8..81088aa 100644
--- a/examples/complete-alb/versions.tf
+++ b/examples/complete-alb/versions.tf
@@ -6,10 +6,6 @@ terraform {
source = "hashicorp/aws"
version = ">= 4.27"
}
- random = {
- source = "hashicorp/random"
- version = ">= 2.0"
- }
null = {
source = "hashicorp/null"
version = ">= 2.0"
diff --git a/main.tf b/main.tf
index 5b9ff31..deda284 100644
--- a/main.tf
+++ b/main.tf
@@ -10,7 +10,7 @@ resource "aws_lb" "this" {
load_balancer_type = var.load_balancer_type
internal = var.internal
- security_groups = var.security_groups
+ security_groups = var.create_security_group ? concat([aws_security_group.this[0].id], var.security_groups) : var.security_groups
subnets = var.subnets
idle_timeout = var.idle_timeout
@@ -24,7 +24,7 @@ resource "aws_lb" "this" {
desync_mitigation_mode = var.desync_mitigation_mode
dynamic "access_logs" {
- for_each = length(keys(var.access_logs)) == 0 ? [] : [var.access_logs]
+ for_each = length(var.access_logs) > 0 ? [var.access_logs] : []
content {
enabled = try(access_logs.value.enabled, try(access_logs.value.bucket, null) != null)
@@ -66,44 +66,44 @@ resource "aws_lb_target_group" "main" {
name_prefix = lookup(var.target_groups[count.index], "name_prefix", null)
vpc_id = var.vpc_id
- port = lookup(var.target_groups[count.index], "backend_port", null)
- protocol = lookup(var.target_groups[count.index], "backend_protocol", null) != null ? upper(lookup(var.target_groups[count.index], "backend_protocol")) : null
- protocol_version = lookup(var.target_groups[count.index], "protocol_version", null) != null ? upper(lookup(var.target_groups[count.index], "protocol_version")) : null
- target_type = lookup(var.target_groups[count.index], "target_type", null)
-
- connection_termination = lookup(var.target_groups[count.index], "connection_termination", null)
- deregistration_delay = lookup(var.target_groups[count.index], "deregistration_delay", null)
- slow_start = lookup(var.target_groups[count.index], "slow_start", null)
- proxy_protocol_v2 = lookup(var.target_groups[count.index], "proxy_protocol_v2", false)
- lambda_multi_value_headers_enabled = lookup(var.target_groups[count.index], "lambda_multi_value_headers_enabled", false)
- load_balancing_algorithm_type = lookup(var.target_groups[count.index], "load_balancing_algorithm_type", null)
- preserve_client_ip = lookup(var.target_groups[count.index], "preserve_client_ip", null)
- ip_address_type = lookup(var.target_groups[count.index], "ip_address_type", null)
+ port = try(var.target_groups[count.index].backend_port, null)
+ protocol = try(upper(var.target_groups[count.index].backend_protocol), null)
+ protocol_version = try(upper(var.target_groups[count.index].protocol_version), null)
+ target_type = try(var.target_groups[count.index].target_type, null)
+
+ connection_termination = try(var.target_groups[count.index].connection_termination, null)
+ deregistration_delay = try(var.target_groups[count.index].deregistration_delay, null)
+ slow_start = try(var.target_groups[count.index].slow_start, null)
+ proxy_protocol_v2 = try(var.target_groups[count.index].proxy_protocol_v2, false)
+ lambda_multi_value_headers_enabled = try(var.target_groups[count.index].lambda_multi_value_headers_enabled, false)
+ load_balancing_algorithm_type = try(var.target_groups[count.index].load_balancing_algorithm_type, null)
+ preserve_client_ip = try(var.target_groups[count.index].preserve_client_ip, null)
+ ip_address_type = try(var.target_groups[count.index].ip_address_type, null)
dynamic "health_check" {
- for_each = length(keys(lookup(var.target_groups[count.index], "health_check", {}))) == 0 ? [] : [lookup(var.target_groups[count.index], "health_check", {})]
+ for_each = try([var.target_groups[count.index].health_check], [])
content {
- enabled = lookup(health_check.value, "enabled", null)
- interval = lookup(health_check.value, "interval", null)
- path = lookup(health_check.value, "path", null)
- port = lookup(health_check.value, "port", null)
- healthy_threshold = lookup(health_check.value, "healthy_threshold", null)
- unhealthy_threshold = lookup(health_check.value, "unhealthy_threshold", null)
- timeout = lookup(health_check.value, "timeout", null)
- protocol = lookup(health_check.value, "protocol", null)
- matcher = lookup(health_check.value, "matcher", null)
+ enabled = try(health_check.value.enabled, null)
+ interval = try(health_check.value.interval, null)
+ path = try(health_check.value.path, null)
+ port = try(health_check.value.port, null)
+ healthy_threshold = try(health_check.value.healthy_threshold, null)
+ unhealthy_threshold = try(health_check.value.unhealthy_threshold, null)
+ timeout = try(health_check.value.timeout, null)
+ protocol = try(health_check.value.protocol, null)
+ matcher = try(health_check.value.matcher, null)
}
}
dynamic "stickiness" {
- for_each = length(keys(lookup(var.target_groups[count.index], "stickiness", {}))) == 0 ? [] : [lookup(var.target_groups[count.index], "stickiness", {})]
+ for_each = try([var.target_groups[count.index].stickiness], [])
content {
- enabled = lookup(stickiness.value, "enabled", null)
- cookie_duration = lookup(stickiness.value, "cookie_duration", null)
- type = lookup(stickiness.value, "type", null)
- cookie_name = lookup(stickiness.value, "cookie_name", null)
+ enabled = lookup(stickiness.value.enabled, null)
+ cookie_duration = lookup(stickiness.value.cookie_duration, null)
+ type = lookup(stickiness.value.type, null)
+ cookie_name = lookup(stickiness.value.cookie_name, null)
}
}
@@ -112,7 +112,7 @@ resource "aws_lb_target_group" "main" {
var.target_group_tags,
lookup(var.target_groups[count.index], "tags", {}),
{
- "Name" = lookup(var.target_groups[count.index], "name", lookup(var.target_groups[count.index], "name_prefix", ""))
+ "Name" = try(var.target_groups[count.index].name, var.target_groups[count.index].name_prefix, "")
},
)
@@ -764,3 +764,50 @@ resource "aws_lb_listener_certificate" "https_listener" {
listener_arn = aws_lb_listener.frontend_https[var.extra_ssl_certs[count.index]["https_listener_index"]].arn
certificate_arn = var.extra_ssl_certs[count.index]["certificate_arn"]
}
+
+################################################################################
+# Security Group
+################################################################################
+
+locals {
+ create_security_group = local.create_lb && var.create_security_group
+ security_group_name = try(coalesce(var.security_group_name, var.name, var.name_prefix), "")
+}
+
+resource "aws_security_group" "this" {
+ count = local.create_security_group ? 1 : 0
+
+ name = var.security_group_use_name_prefix ? null : local.security_group_name
+ name_prefix = var.security_group_use_name_prefix ? "${local.security_group_name}-" : null
+ description = var.security_group_description
+ vpc_id = var.vpc_id
+
+ tags = merge(
+ var.tags,
+ var.security_group_tags,
+ { "Name" = local.security_group_name },
+ )
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+resource "aws_security_group_rule" "this" {
+ for_each = { for k, v in var.security_group_rules : k => v if local.create_security_group }
+
+ # Required
+ security_group_id = aws_security_group.this[0].id
+ protocol = each.value.protocol
+ from_port = each.value.from_port
+ to_port = each.value.to_port
+ type = each.value.type
+
+ # Optional
+ description = lookup(each.value, "description", null)
+ cidr_blocks = lookup(each.value, "cidr_blocks", null)
+ ipv6_cidr_blocks = lookup(each.value, "ipv6_cidr_blocks", null)
+ prefix_list_ids = lookup(each.value, "prefix_list_ids", null)
+ self = lookup(each.value, "self", null)
+ source_security_group_id = lookup(each.value, "source_security_group_id", null)
+}
diff --git a/outputs.tf b/outputs.tf
index 32c9b6f..816edc6 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -62,3 +62,17 @@ output "target_group_attachments" {
description = "ARNs of the target group attachment IDs"
value = { for k, v in aws_lb_target_group_attachment.this : k => v.id }
}
+
+################################################################################
+# Security Group
+################################################################################
+
+output "security_group_arn" {
+ description = "Amazon Resource Name (ARN) of the security group"
+ value = try(aws_security_group.this[0].arn, null)
+}
+
+output "security_group_id" {
+ description = "ID of the security group"
+ value = try(aws_security_group.this[0].id, null)
+}
diff --git a/variables.tf b/variables.tf
index aa9860d..cf10f06 100644
--- a/variables.tf
+++ b/variables.tf
@@ -219,3 +219,43 @@ variable "putin_khuylo" {
type = bool
default = true
}
+
+################################################################################
+# Security Group
+################################################################################
+
+variable "create_security_group" {
+ description = "Determines if a security group is created"
+ type = bool
+ default = true
+}
+
+variable "security_group_name" {
+ description = "Name to use on security group created"
+ type = string
+ default = null
+}
+
+variable "security_group_use_name_prefix" {
+ description = "Determines whether the security group name (`security_group_name`) is used as a prefix"
+ type = bool
+ default = true
+}
+
+variable "security_group_description" {
+ description = "Description of the security group created"
+ type = string
+ default = null
+}
+
+variable "security_group_rules" {
+ description = "Security group rules to add to the security group created"
+ type = any
+ default = {}
+}
+
+variable "security_group_tags" {
+ description = "A map of additional tags to add to the security group created"
+ type = map(string)
+ default = {}
+}
diff --git a/wrappers/main.tf b/wrappers/main.tf
index 5098d5a..44f2337 100644
--- a/wrappers/main.tf
+++ b/wrappers/main.tf
@@ -40,4 +40,10 @@ module "wrapper" {
enable_waf_fail_open = try(each.value.enable_waf_fail_open, var.defaults.enable_waf_fail_open, false)
desync_mitigation_mode = try(each.value.desync_mitigation_mode, var.defaults.desync_mitigation_mode, "defensive")
putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true)
+ create_security_group = try(each.value.create_security_group, var.defaults.create_security_group, true)
+ security_group_name = try(each.value.security_group_name, var.defaults.security_group_name, null)
+ security_group_use_name_prefix = try(each.value.security_group_use_name_prefix, var.defaults.security_group_use_name_prefix, true)
+ security_group_description = try(each.value.security_group_description, var.defaults.security_group_description, null)
+ security_group_rules = try(each.value.security_group_rules, var.defaults.security_group_rules, {})
+ security_group_tags = try(each.value.security_group_tags, var.defaults.security_group_tags, {})
}