diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f23873 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +#terraform.tfstate +#*.tfstate.backup +#*.backup +*.lock.info +**/*.tfplan +**/.terraform/ + +# Crash log files +crash.log + +# Ignore any .tfvars files that are generated automatically for each Terraform run. Most +# .tfvars files are managed as part of configuration and so should be included in +# version control. +# +# example.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json +*.tf.xxx + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* +*tfplan* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0989391..6dc423a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,23 @@ -## Release Version: 0.0.2 +## 1.0.0 + +BACKWARDS INCOMPATIBILITIES / NOTES: + +* Terraform version 0.12.x +* List variables "http_target_group_names", "http_target_group_ports" and "http_host_headers" replaced with list of objects variable "http_target_group_parameters" ([#11](https://github.com/zoitech/terraform-aws-saml/issues/11)) +* List variables "https_target_group_names", "https_target_group_ports" and "https_host_headers" replaced with list of objects variable "https_target_group_parameters" ([#11](httpss://github.com/zoitech/terraform-aws-saml/issues/11)) +* Changed variable name of "lb_http_listener" to "create_lb_http_listener" ([#12](https://github.com/zoitech/terraform-aws-saml/issues/12)) +Changed variable name of "lb_https_listener" to "create_lb_https_listener" ([#12](httpss://github.com/zoitech/terraform-aws-saml/issues/12)) +* Changed variable name of "lb_internal" to "create_internal_lb" ([#12](httpss://github.com/zoitech/terraform-aws-saml/issues/12)) +* Changed variabble name of "lb_https_offloading" to "enable_lb_https_offloading" ([#12](httpss://github.com/zoitech/terraform-aws-saml/issues/12)) +* Variables "lb_private_subnet_ids" and "lb_public_subnet_ids" replaced with "lb_subnet_ids" + +ENHANCEMENTS: + +* Upgraded module to terraform 0.12.x ([#10](https://github.com/zoitech/terraform-aws-saml/issues/10)) +* Reduced security group complexity ([#13](https://github.com/zoitech/terraform-aws-saml/issues/13)) +* Enabled access logs ([#7](https://github.com/zoitech/terraform-aws-saml/issues/7)) + +## 0.0.2 BACKWARDS INCOMPATIBILITIES / NOTES: diff --git a/LICENSE b/LICENSE index ea48c49..e5d88c9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License (MIT) -Copyright (c) 2018 Zoi TechCon GmbH +Copyright (c) 2019 Zoi TechCon GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index f2384c1..104529a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # AWS Application Load Balancer Module -Terraform module which sets up an application load balancer with either a HTTP listener, a HTTPS listener or both, and one or more target groups as required. -The idea behind this module is to support webservers hosting multiple sites for example a windows server running IIS. +Terraform module which sets up an application load balancer with either a HTTP listener, a HTTPS listener or both, and one or more target groups as needed. Terraform version required is 0.12.x . The following resources are created: * Application load balancer (internal or external) @@ -13,26 +12,59 @@ lb = load balancer sg = security group tg = target group - ## Usage -### Specify this Module as Source + ```hcl module "alb" { - source = "git::https://github.com/zoitech/terraform-aws-alb.git" - - # Or to specifiy a particular module version: - source = "git::https://github.com/zoitech/terraform-aws-alb.git?ref=v0.0.1" -``` -### Target Group Arguments -The position of the values in each list corresponds to the value in the same position of the other list. E.g. a https request to "serv9.mysite.com" will be sent to the target group with name "Serv9-int-ssl" on port "10503". + source = "git::https://github.com/zoitech/terraform-aws-alb.git" + aws_region = "eu-central-1" + vpc_id = "vpc-1234567b" + prefix = "p-dept.123-" + suffix = "-abc" + lb_name = "my-load-balancer" + create_internal_lb = true + lb_security_group_ids = ["sg-1524364d", "172625db"] + lb_subnet_ids = ["subnet-fd42536a", "subnet-98781bac"] + create_lb_http_listener = true + lb_http_listener_port = 80 + http_target_group_parameters = [ + { + target_group = "application-1-http" + host_headers = ["application-1.com"] + port = 80 + }, + { + target_group = "application-2-http" + host_headers = ["application-2.com"] + port = 10002 + }, + ] + + create_lb_https_listener = true + lb_https_listener_port = 443 + https_target_group_parameters = [ + { + target_group = "application-1-https" + host_headers = ["application-1.com"] + port = 443 + }, + { + target_group = "application-2-https" + host_headers = ["application-2.com"] + port = 10002 + }, + ] + enable_lb_https_offloading = false + certificate_arn = "arn:aws:acm:eu-central-1:xxxxxxxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +``` + +### Health Checks + +Health checks for all target groups can be set. + +HTTP: -Each of the three HTTP lists must contain an equal number of values, as is the case for when using HTTPS. ```hcl -# HTTP required arguments (if "lb_http_listener = true" ): - -http_target_group_names = ["Serv1-int", "Serv2-int", "Serv3-int"] -http_target_group_ports = ["10500", "10501", "80"] -http_host_headers = ["serv1.mysite.com", "serv2.mysite.com", "serv3.mysite.com"] http_health_check_interval = 15 #default = 30 http_health_check_path = "/status/load-balancer" #default = "/" http_health_check_port = 1500 #default = "traffic-port" @@ -40,18 +72,10 @@ http_health_check_timeout = 10 #default = 5 http_health_check_healthy_threshold = 2 #default = 3 http_health_check_unhealthy_threshold = 2 #default = 3 http_health_check_matcher = "200-299" #default = 200 (Success codes) +``` -# HTTP optional arguments (if "lb_http_listener = true" ): - -http_target_group_deregistration_delay = 30 #default = 300 (seconds) -http_target_group_stickiness_enabled = true #default set to false -http_target_group_stickiness_cookie_duration = 8640 #default 8640 seconds (1 day) - -# HTTPS required arguments (if "lb_https_listener = true" ): - -https_target_group_names = ["Serv1-int-ssl", "Serv2-int-ssl", "Serv9-int-ssl"] -https_target_group_ports = ["443", "8080", "10503"] -https_host_headers = ["serv1.mysite.com", "serv2.mysite.com", "serv9.mysite.com"] +HTTPS: +```hcl https_health_check_interval = 15 #default = 30 https_health_check_path = "/status/load-balancer" #default = "/" https_health_check_port = 1500 #default = "traffic-port" @@ -59,188 +83,74 @@ https_health_check_timeout = 10 #default = 5 https_health_check_healthy_threshold = 2 #default = 3 https_health_check_unhealthy_threshold = 2 #default = 3 https_health_check_matcher = "200-299" #default = 200 (Success codes) - - -# HTTPS optional arguments (if "lb_https_listener = true" ): - -https_target_group_deregistration_delay = 30 #default = 300 (seconds) -https_target_group_stickiness_enabled = true #default set to false -https_target_group_stickiness_cookie_duration = 8640 #default 8640 seconds (1 day) -``` - -### VPC ID and Target Instance -Are valid for both target groups and need only be set once. Multiple targets should be specified in a comma separated string without spaces. A maximum of 8 targets are currently supported in this module: -```hcl -vpc_id = "vpc-a01234bc" -target_id = "i-00123456789123aaa,i-00123456789123bbb,i-00123456789123ccc" ``` +### Target Instance -### Load Balancer Required Arguments -#### Internal or External -To configure the load balancer for internal or external (public) use: - -```hcl - lb_internal = false #default = true -``` -#### Load Balancer Listener Protocols -The following determines what kind of listener(s) will be applied to the load balancer: -* HTTP -* HTTPS -* or both - -```hcl - lb_http_listener = true #default = true - *lb_https_listener = true #default = false -``` -#### * HTTPS Offloading -To enable offloading from HTTPS to HTTP set the following parameter "lb_https_offloading" to "true": - +Are valid for both target groups and need only be set once. Multiple targets should be specified in a comma separated string without spaces. A maximum of 8 targets are currently supported in this module: ```hcl - lb_https_listener = true #default = false - lb_https_offloading = true #default = false +target_id = "i-00123456789123aaa,i-00123456789123bbb,i-00123456789123ccc" ``` -The following parameters need to be set: -* http_target_group_names -* http_target_group_ports -* https_host_headers - -The following parameters need **not** be set as the HTTP counterparts are used instead: -* https_target_group_names -* https_target_group_ports - +#### HTTPS Offloading +If HTTPS offloading is enabled ("enable_lb_https_offloading = true") the variable "https_target_group_parameters" is not required, as the "http_target_group_parameters" variable will be used. -#### Load Balancer Listener Ports -HTTP/HTTPS listener port of the load balancer depending on what kind of listener(s) are selected: -```hcl - lb_http_listener_port = 8080 #default = 80 - lb_https_listener_port = 443 #default = 443 -``` +### HTTP optional arguments (if "create_lb_http_listener = true" ) -#### SSL Certificate -If a HTTPS listener is being used, set the SSL certificate: ```hcl - certificate_arn = "arn:aws:acm:eu-central-1:xxxxxxxxxxxx:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +http_target_group_deregistration_delay = 30 #default = 300 (seconds) +http_target_group_stickiness_enabled = true #default set to false +http_target_group_stickiness_cookie_duration = 8640 #default 8640 seconds (1 day) ``` -#### Load Balancer Name +### HTTPS optional arguments (if "create_lb_https_listener = true" ) -Set the load balancer name: ```hcl - lb_name = "Internal Services" +https_target_group_deregistration_delay = 30 #default = 300 (seconds) +https_target_group_stickiness_enabled = true #default set to false +https_target_group_stickiness_cookie_duration = 8640 #default 8640 seconds (1 day) ``` - -#### Subnets - -Specifying the subnets for the load balancer: - -```hcl - # If the load balancer is internal, configure lb_private_subnet_ids: - - lb_private_subnet_ids = ["subnet-12345678", "subnet-abc87654"] - - # If the load balancer is external, configure lb_public_subnet_ids: - - lb_public_subnet_ids = ["subnet-98765432", "subnet-98765cba"] -``` #### Security Groups -Four security groups are created by default. - -An empty security group is created and attached to the load balancer, which can be used later as the security group source in other security groups to allow traffic into the instance: -* "Group-ALB-${var.lb_name}" +The following security groups are created (depending on whether a HTTP listener, HTTPS listener or both are in use). -The following security group permits all traffic outbound from the load balancer by default: - -* "Rule-all-out-all" - -A HTTP listener traffic in security group is created to allow HTTP traffic in only from specific sources. The name of the security group is configured as follows: - -* "Rule-allow-${var.lb_source_traffic_name}-in-HTTP" - -The variable "lb_source_traffic_name" should be set to a location or department where the source traffic is coming from: - -```hcl - lb_source_traffic_name = "Human-Resources" -``` - -Alternatively the variable "var.lb_sg_http_name" can be set to fully customize the name of the security group. If this variable is set, "var.lb_source_traffic_name" is no longer required: - -```hcl - lb_sg_http_name = "My-http-security-group-name" -``` -The same applies for the HTTPS security group name: +An empty security group is created and attached to the load balancer, which can be used later as the security group source in other security groups to allow traffic into the instance: -```hcl - lb_sg_https_name = "My-https-security-group-name" -``` +* Group-ALB-${var.lb_name} -By default **all IP addresses are permitted** for both the HTTP and HTTPS security group. To specify specific IP ranges (or CIDR blocks) set the following variables: +The HTTP and HTTPs security groups uses the previously mentioned security group as the source, and is attached to the target instances to allow traffic in: -```hcl - rule_allow_lb_http_listener_traffic_in_cidr_blocks = ["172.16.0.0/16", "192.168.0.0/24"] - rule_allow_lb_https_listener_traffic_in_cidr_blocks = ["172.16.0.0/16", "192.168.0.0/24"] -``` +* group_loadbalancer_in_http +* group_loadbalancer_in_https ### Load Balancer Optional Arguments -#### Adding Already Existing Security Groups - -Additional security groups can be added to the load balancer: -```hcl - lb_security_group_ids = ["sg-12345678", "sg-abc87654"] -``` Idle timeout (default = 60) for the load balancer, defining if http2 is enabled (default = true) and enabling deletion protection (default = false) can also be set as follows: + ```hcl lb_idle_timeout = 60 lb_enable_http2 = true lb_enable_deletion_protection = false - -``` -##### Prefixes and Suffixes (not Latin words ;-)) -Can be set when there is a standard naming convention in use. They are applied to the name of the load balancer and target group resources (default = null/empty) -```hcl - prefix = "P-" - suffix = "-HR" ``` + #### Outputs -The following outputs are possible: +The following outputs are available: + * lb_name (The name of the LB) * lb_arn (The ARN of the load balancer) * lb_arn_suffix (The ARN suffix for use with CloudWatch Metrics) * lb_dns_name (The DNS name of the load balancer) * lb_zone_id (The canonical hosted zone ID of the load balancer (to be used in a Route 53 Alias record)) -Example usage: +## Referencing a Tagged Version + ```hcl -#The name of the LB -output "lb_name" { - value = "${module.alb.lb_name}" -} -#The ARN of the load balancer -output "lb_arn" { - value = "${module.alb.lb_arn}" -} -#The ARN suffix for use with CloudWatch Metrics -output "lb_arn_suffix" { - value = "${module.alb.lb_arn_suffix}" -} -#The DNS name of the load balancer -output "lb_dns_name" { - value = "${module.alb.lb_dns_name}" -} -#The canonical hosted zone ID of the load balancer (to be used in a Route 53 Alias record) -output "lb_zone_id" { - value = "${module.alb.lb_zone_id}" -} +module "alb" { + source = "git::https://github.com/zoitech/terraform-aws-alb.git?ref=v1.0.0" ``` - - - ## Authors Module managed by [Zoi](https://github.com/zoitech). diff --git a/alb.tf b/alb.tf index 09b72f4..1e23488 100644 --- a/alb.tf +++ b/alb.tf @@ -1,13 +1,22 @@ resource "aws_lb" "application_loadbalancer" { ### Required Arguments ### name = "${var.prefix}${var.lb_name}${var.suffix}" - internal = "${var.lb_internal}" + internal = var.create_internal_lb load_balancer_type = "application" - security_groups = ["${local.lb_security_groups}"] - subnets = ["${local.lb_subnet_ids}"] + security_groups = local.lb_security_groups + subnets = var.lb_subnet_ids + + access_logs { + enabled = var.lb_logs_bucket_enabled + bucket = var.lb_logs_bucket_name + prefix = var.lb_logs_bucket_prefix + } ### Optional Arguments ### - idle_timeout = "${var.lb_idle_timeout}" - enable_http2 = "${var.lb_enable_http2}" - enable_deletion_protection = "${var.lb_enable_deletion_protection}" + idle_timeout = var.lb_idle_timeout + enable_http2 = var.lb_enable_http2 + enable_deletion_protection = var.lb_enable_deletion_protection + + tags = var.lb_tags } + diff --git a/alb_http_listeners.tf b/alb_http_listeners.tf index bb6be0f..a4a54fe 100644 --- a/alb_http_listeners.tf +++ b/alb_http_listeners.tf @@ -1,29 +1,33 @@ # Create http listener for the loadbalancer if "var.lb_http_listener == true" resource "aws_lb_listener" "application_loadbalancer_listener_http" { - count = "${var.lb_http_listener}" - load_balancer_arn = "${aws_lb.application_loadbalancer.arn}" - port = "${var.lb_http_listener_port}" + count = local.create_lb_http_listener + load_balancer_arn = aws_lb.application_loadbalancer.arn + port = var.lb_http_listener_port protocol = "HTTP" default_action { - target_group_arn = "${aws_lb_target_group.tg_http.0.arn}" + target_group_arn = aws_lb_target_group.tg_http[0].arn type = "forward" } } # Create http listener rules resource "aws_lb_listener_rule" "http_host_based_routing" { - count = "${var.lb_http_listener ? "${length(var.http_host_headers) == "${length(var.http_target_group_names)}" ? "${length(var.http_host_headers)}" : 0}" :0}" - - listener_arn = "${aws_lb_listener.application_loadbalancer_listener_http.arn}" + count = local.create_lb_http_listener_rules + listener_arn = aws_lb_listener.application_loadbalancer_listener_http[0].arn action { type = "forward" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) } condition { field = "host-header" - values = ["${element(var.http_host_headers, count.index)}"] + values = lookup(element(var.http_target_group_parameters, count.index), "host_headers") + } + + lifecycle { + create_before_destroy = true } } + diff --git a/alb_https_listeners.tf b/alb_https_listeners.tf index 644c549..4f59441 100644 --- a/alb_https_listeners.tf +++ b/alb_https_listeners.tf @@ -1,63 +1,30 @@ -# Create https listener for the loadbalancer if "var.lb_https_listener == true" and "var.lb_https_offloading == false" +# Create https listener for the loadbalancer if "var.create_lb_https_listener == true" and "var.enable_lb_https_offloading == false" resource "aws_lb_listener" "application_loadbalancer_listener_https" { - count = "${var.lb_https_listener ? "${!var.lb_https_offloading ? 1 :0 }" :0 }" - load_balancer_arn = "${aws_lb.application_loadbalancer.arn}" - port = "${var.lb_https_listener_port}" + count = local.create_lb_https_listener + load_balancer_arn = aws_lb.application_loadbalancer.arn + port = var.lb_https_listener_port protocol = "HTTPS" default_action { - target_group_arn = "${aws_lb_target_group.tg_https.0.arn}" + target_group_arn = (var.enable_lb_https_offloading == true ? aws_lb_target_group.tg_http[0].arn : aws_lb_target_group.tg_https[0].arn) type = "forward" } - certificate_arn = "${var.certificate_arn}" + certificate_arn = var.certificate_arn } # Create https listener rules resource "aws_lb_listener_rule" "https_host_based_routing" { - count = "${var.lb_https_listener ? "${!var.lb_https_offloading ? "${length(var.https_host_headers) == "${length(var.http_target_group_names)}" ? "${length(var.https_host_headers)}" : 0}" :0}" :0}" - - listener_arn = "${aws_lb_listener.application_loadbalancer_listener_https.arn}" - - action { - type = "forward" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - } - - condition { - field = "host-header" - values = ["${element(var.https_host_headers, count.index)}"] - } -} - -# Create https listener (with offloading) for the loadbalancer if "var.lb_https_listener == true" and "var.lb_https_offloading == true" -resource "aws_lb_listener" "application_loadbalancer_listener_https_with_offloading" { - count = "${var.lb_https_listener ? "${var.lb_https_offloading ? 1 :0 }" :0 }" - load_balancer_arn = "${aws_lb.application_loadbalancer.arn}" - port = "${var.lb_https_listener_port}" - protocol = "HTTPS" - - default_action { - target_group_arn = "${aws_lb_target_group.tg_http.0.arn}" - type = "forward" - } - - certificate_arn = "${var.certificate_arn}" -} - -# Create https (offloading) listener rules -resource "aws_lb_listener_rule" "https_host_based_routing_offloading" { - count = "${var.lb_https_listener ? "${var.lb_https_offloading ? "${length(var.https_host_headers) == "${length(var.http_target_group_names)}" ? "${length(var.https_host_headers)}" : 0}" :0}" :0}" - - listener_arn = "${aws_lb_listener.application_loadbalancer_listener_https_with_offloading.arn}" + count = local.create_lb_https_listener_rules + listener_arn = aws_lb_listener.application_loadbalancer_listener_https[0].arn action { type = "forward" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" + target_group_arn = (var.enable_lb_https_offloading == true ? element(aws_lb_target_group.tg_http.*.arn, count.index) : element(aws_lb_target_group.tg_https.*.arn, count.index)) } condition { field = "host-header" - values = ["${element(var.https_host_headers, count.index)}"] + values = (var.enable_lb_https_offloading == true ? lookup(element(var.http_target_group_parameters, count.index), "host_headers") : lookup(element(var.https_target_group_parameters, count.index), "host_headers")) } } diff --git a/data.tf b/data.tf new file mode 100644 index 0000000..341e919 --- /dev/null +++ b/data.tf @@ -0,0 +1,7 @@ +data "aws_caller_identity" "current" { +} + +data "aws_instance" "target_group_instances" { + count = length(split(",", var.target_ids)) + instance_id = element(split(",", var.target_ids), count.index) +} diff --git a/http_target_groups.tf b/http_target_groups.tf index f22ea68..328c7fa 100644 --- a/http_target_groups.tf +++ b/http_target_groups.tf @@ -1,88 +1,93 @@ #### Create http target group(s) #### resource "aws_lb_target_group" "tg_http" { - # Check the number of http target group names matches the number of http target group ports. - # If check is ok creates the number of http target group resources based on the number of http target group names - count = "${var.lb_http_listener ? "${length(var.http_target_group_names) == "${length(var.http_target_group_ports)}" ? "${length(var.http_target_group_names)}" : 0}" :0}" + count = local.create_tg_http ### Required Arguments ### - name = "${var.prefix}${element(var.http_target_group_names, count.index)}${var.suffix}" # default prefix/suffix = "". Default target group name = ["http-target-group"] N.B. 32 Character limit with prefix/suffix - port = "${element(var.http_target_group_ports, count.index)}" # default = [80] + name = "${var.prefix}${lookup(element(var.http_target_group_parameters, count.index), "target_group")}" + port = lookup(element(var.http_target_group_parameters, count.index), "port") protocol = "HTTP" - vpc_id = "${var.vpc_id}" + vpc_id = var.vpc_id health_check { - interval = "${var.http_health_check_interval}" #default = 30 - path = "${var.http_health_check_path}" #default = "/" - port = "${var.http_health_check_port}" #default = "traffic-port" + interval = var.http_health_check_interval #default = 30 + path = var.http_health_check_path #default = "/" + port = var.http_health_check_port #default = "traffic-port" protocol = "HTTP" - timeout = "${var.http_health_check_timeout}" #default = 5 - healthy_threshold = "${var.http_health_check_healthy_threshold}" #default = 3 - unhealthy_threshold = "${var.http_health_check_unhealthy_threshold}" #default = 3 - matcher = "${var.http_health_check_matcher}" #default = 200 + timeout = var.http_health_check_timeout #default = 5 + healthy_threshold = var.http_health_check_healthy_threshold #default = 3 + unhealthy_threshold = var.http_health_check_unhealthy_threshold #default = 3 + matcher = var.http_health_check_matcher #default = 200 } target_type = "instance" ### Optional Arguments ### - deregistration_delay = "${var.http_target_group_deregistration_delay}" # default = 300. + deregistration_delay = var.http_target_group_deregistration_delay # default = 300. stickiness { - enabled = "${var.http_target_group_stickiness_enabled}" # default set to false - type = "lb_cookie" # default = lb_cookie. Only possible value for applicatoin load balancer - cookie_duration = "${var.http_target_group_stickiness_cookie_duration}" # default 8640 seconds (1 day). + enabled = var.http_target_group_stickiness_enabled # default set to false + type = "lb_cookie" # default = lb_cookie. Only possible value for applicatoin load balancer + cookie_duration = var.http_target_group_stickiness_cookie_duration # default 8640 seconds (1 day). } - - #tags = https://github.com/hashicorp/terraform/issues/15226 + tags = var.tg_tags } # Attach up to 8 targets to http target group(s) # aws_alb_target_group_attachment errors out when multiple instance id's used # Workaround until https://github.com/terraform-providers/terraform-provider-aws/issues/647 is solved resource "aws_lb_target_group_attachment" "attach_http_tg_target1" { - count = "${local.http_target_id_1}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 0)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_1 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 0) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_http_tg_target2" { - count = "${local.http_target_id_2}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 1)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_2 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 1) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_http_tg_target3" { - count = "${local.http_target_id_3}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 2)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_3 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 2) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_http_tg_target4" { - count = "${local.http_target_id_4}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 3)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_4 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 3) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_http_tg_target5" { - count = "${local.http_target_id_5}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 4)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_5 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 4) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_http_tg_target6" { - count = "${local.http_target_id_6}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 5)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_6 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 5) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_http_tg_target7" { - count = "${local.http_target_id_7}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 6)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_7 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 6) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_http_tg_target8" { - count = "${local.http_target_id_8}" - target_group_arn = "${element(aws_lb_target_group.tg_http.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 7)}" - port = "${element(var.http_target_group_ports, count.index)}" + count = local.http_target_id_8 + target_group_arn = element(aws_lb_target_group.tg_http.*.arn, count.index) + target_id = element(split(",", var.target_ids), 7) + port = lookup(element(var.http_target_group_parameters, count.index), "port") } + diff --git a/https_target_groups.tf b/https_target_groups.tf index b506358..9329eed 100644 --- a/https_target_groups.tf +++ b/https_target_groups.tf @@ -1,86 +1,93 @@ #### Create https target group(s) #### resource "aws_lb_target_group" "tg_https" { - # Check the number of https target group names matches the number of https target group ports. - # If check is ok creates the number of https target group resources based on the number of https target group names - count = "${var.lb_https_listener ? "${!var.lb_https_offloading ? "${length(var.https_target_group_names) == "${length(var.https_target_group_ports)}" ? "${length(var.https_target_group_names)}" : 0}" :0}" :0}" + count = local.create_tg_https ### Required Arguments ### - name = "${var.prefix}${element(var.https_target_group_names, count.index)}${var.suffix}" # default prefix/suffix = "". Default target group name = ["https-target-group"] N.B. 32 Character limit with prefix/suffix - port = "${element(var.https_target_group_ports, count.index)}" # default = [443] + name = "${var.prefix}${lookup(element(var.https_target_group_parameters, count.index), "target_group")}" + port = lookup(element(var.https_target_group_parameters, count.index), "port") protocol = "HTTPS" - vpc_id = "${var.vpc_id}" + vpc_id = var.vpc_id health_check { - interval = "${var.https_health_check_interval}" #default = 30 - path = "${var.https_health_check_path}" #default = "/" - port = "${var.https_health_check_port}" #default = "traffic-port" + interval = var.https_health_check_interval #default = 30 + path = var.https_health_check_path #default = "/" + port = lookup(element(var.https_target_group_parameters, count.index), "port") #default = "traffic-port" protocol = "HTTPS" - timeout = "${var.https_health_check_timeout}" #default = 5 - healthy_threshold = "${var.https_health_check_healthy_threshold}" #default = 3 - unhealthy_threshold = "${var.https_health_check_unhealthy_threshold}" #default = 3 - matcher = "${var.https_health_check_matcher}" #default = 200 + timeout = var.https_health_check_timeout #default = 5 + healthy_threshold = var.https_health_check_healthy_threshold #default = 3 + unhealthy_threshold = var.https_health_check_unhealthy_threshold #default = 3 + matcher = var.https_health_check_matcher #default = 200 } target_type = "instance" ### Optional Arguments ### - deregistration_delay = "${var.https_target_group_deregistration_delay}" # default = 300. + deregistration_delay = var.https_target_group_deregistration_delay # default = 300. stickiness { - enabled = "${var.https_target_group_stickiness_enabled}" # default set to false - type = "lb_cookie" # default = lb_cookie. Only possible value for applicatoin load balancer - cookie_duration = "${var.https_target_group_stickiness_cookie_duration}" # default 8640 seconds (1 day). + enabled = var.https_target_group_stickiness_enabled # default set to false + type = "lb_cookie" # default = lb_cookie. Only possible value for applicatoin load balancer + cookie_duration = var.https_target_group_stickiness_cookie_duration # default 8640 seconds (1 day). } + tags = var.tg_tags } # Attach up to 8 targets to https target group(s) # aws_alb_target_group_attachment errors out when multiple instance id's used # Workaround until https://github.com/terraform-providers/terraform-provider-aws/issues/647 is solved resource "aws_lb_target_group_attachment" "attach_https_tg_target1" { - count = "${local.https_target_id_1}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 0)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_1 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 0) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_https_tg_target2" { - count = "${local.https_target_id_2}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 1)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_2 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 1) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_https_tg_target3" { - count = "${local.https_target_id_3}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 2)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_3 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 2) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_https_tg_target4" { - count = "${local.https_target_id_4}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 3)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_4 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 3) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_https_tg_target5" { - count = "${local.https_target_id_5}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 4)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_5 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 4) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_https_tg_target6" { - count = "${local.https_target_id_6}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 5)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_6 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 5) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_https_tg_target7" { - count = "${local.https_target_id_7}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 6)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_7 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 6) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + resource "aws_lb_target_group_attachment" "attach_https_tg_target8" { - count = "${local.https_target_id_8}" - target_group_arn = "${element(aws_lb_target_group.tg_https.*.arn, count.index)}" - target_id = "${element(split(",", var.target_ids), 7)}" - port = "${element(var.https_target_group_ports, count.index)}" + count = local.https_target_id_8 + target_group_arn = element(aws_lb_target_group.tg_https.*.arn, count.index) + target_id = element(split(",", var.target_ids), 7) + port = lookup(element(var.https_target_group_parameters, count.index), "port") } + diff --git a/locals.tf b/locals.tf index 372028e..424e992 100644 --- a/locals.tf +++ b/locals.tf @@ -1,35 +1,48 @@ locals { - # Security groups - lb_security_groups_for_http = ["${aws_security_group.lb_group.id}", "${aws_security_group.rule_all_out.id}", "${aws_security_group.lb_http_listener_traffic_in.id}", "${var.lb_security_group_ids}"] - lb_security_groups_for_https = ["${aws_security_group.lb_group.id}", "${aws_security_group.rule_all_out.id}", "${aws_security_group.lb_https_listener_traffic_in.id}", "${var.lb_security_group_ids}"] - lb_security_groups_for_http_https = ["${aws_security_group.lb_group.id}", "${aws_security_group.rule_all_out.id}", "${aws_security_group.lb_http_listener_traffic_in.id}", "${aws_security_group.lb_https_listener_traffic_in.id}", "${var.lb_security_group_ids}"] - lb_security_groups = ["${split(",", var.lb_http_listener ? var.lb_https_listener ? join(",", local.lb_security_groups_for_http_https) : join(",", local.lb_security_groups_for_http) : join(",", local.lb_security_groups_for_https))}"] + # load balancer + ## Security groups + create_sg_http_in = (var.create_lb_http_listener == true ? 1 : 0) + create_sg_https_in = (var.create_lb_https_listener == true ? 1 : 0) + create_sg_http_attach = (var.create_lb_http_listener == true ? length(split(",", var.target_ids)) : 0) + create_sg_https_attach = (var.create_lb_https_listener == true ? length(split(",", var.target_ids)) : 0) + lb_security_groups = concat([aws_security_group.lb_group.id], var.lb_security_group_ids) + + # load balancer listeners + ## alb_http_listeners.tf + create_lb_http_listener = (var.create_lb_http_listener == true ? 1 : 0) + create_lb_http_listener_rules = (var.create_lb_http_listener == true && var.http_target_group_parameters != null ? length(var.http_target_group_parameters) : 0) + ## alb_https_listeners.tf + create_lb_https_listener = (var.create_lb_https_listener == true ? 1 : 0) + create_lb_https_listener_rules = (var.create_lb_https_listener == true ? (var.enable_lb_https_offloading == true && var.http_target_group_parameters != null ? length(var.http_target_group_parameters) : (var.enable_lb_https_offloading == false && var.https_target_group_parameters != null ? length(var.https_target_group_parameters) : 0)) : 0) + + # target groups + ## http target group + create_tg_http = (var.create_lb_http_listener == true && var.http_target_group_parameters != null ? length(var.http_target_group_parameters) : 0) + ## https target groups + create_tg_https = (var.create_lb_https_listener == true && var.enable_lb_https_offloading == false && var.https_target_group_parameters != null ? length(var.https_target_group_parameters) : 0) - # Subnet IDs - lb_private_subnet_ids = ["${var.lb_private_subnet_ids}"] - lb_public_subnet_ids = ["${var.lb_public_subnet_ids}"] - lb_subnet_ids = ["${split(",", var.lb_internal ? join(",", local.lb_private_subnet_ids) : join(",", local.lb_public_subnet_ids))}"] # HTTP target group attachment - http_tg_attachment_conditionals = "${var.lb_http_listener ? "${length(var.http_target_group_names) == "${length(var.http_target_group_ports)}" ? "${length(var.http_target_group_names)}" : 0}" :0}" - http_target_id_1 = "${length(split(",", var.target_ids)) >= 1 ? "${local.http_tg_attachment_conditionals}" :0}" - http_target_id_2 = "${length(split(",", var.target_ids)) >= 2 ? "${local.http_tg_attachment_conditionals}" :0}" - http_target_id_3 = "${length(split(",", var.target_ids)) >= 3 ? "${local.http_tg_attachment_conditionals}" :0}" - http_target_id_4 = "${length(split(",", var.target_ids)) >= 4 ? "${local.http_tg_attachment_conditionals}" :0}" - http_target_id_5 = "${length(split(",", var.target_ids)) >= 5 ? "${local.http_tg_attachment_conditionals}" :0}" - http_target_id_6 = "${length(split(",", var.target_ids)) >= 6 ? "${local.http_tg_attachment_conditionals}" :0}" - http_target_id_7 = "${length(split(",", var.target_ids)) >= 7 ? "${local.http_tg_attachment_conditionals}" :0}" - http_target_id_8 = "${length(split(",", var.target_ids)) >= 8 ? "${local.http_tg_attachment_conditionals}" :0}" + http_tg_attachment_conditionals = var.create_lb_http_listener == true ? length(var.http_target_group_parameters) : 0 + http_target_id_1 = length(split(",", var.target_ids)) >= 1 ? local.http_tg_attachment_conditionals : 0 + http_target_id_2 = length(split(",", var.target_ids)) >= 2 ? local.http_tg_attachment_conditionals : 0 + http_target_id_3 = length(split(",", var.target_ids)) >= 3 ? local.http_tg_attachment_conditionals : 0 + http_target_id_4 = length(split(",", var.target_ids)) >= 4 ? local.http_tg_attachment_conditionals : 0 + http_target_id_5 = length(split(",", var.target_ids)) >= 5 ? local.http_tg_attachment_conditionals : 0 + http_target_id_6 = length(split(",", var.target_ids)) >= 6 ? local.http_tg_attachment_conditionals : 0 + http_target_id_7 = length(split(",", var.target_ids)) >= 7 ? local.http_tg_attachment_conditionals : 0 + http_target_id_8 = length(split(",", var.target_ids)) >= 8 ? local.http_tg_attachment_conditionals : 0 # HTTPS target group attachment - https_tg_attachment_conditionals = "${var.lb_https_listener ? "${!var.lb_https_offloading ? "${length(var.https_target_group_names) == "${length(var.https_target_group_ports)}" ? "${length(var.https_target_group_names)}" : 0}" :0}" :0}" + https_tg_attachment_conditionals = var.create_lb_https_listener == true ? var.enable_lb_https_offloading == false ? length(var.https_target_group_parameters) : 0 : 0 - https_target_id_1 = "${length(split(",", var.target_ids)) >= 1 ? "${local.https_tg_attachment_conditionals}" :0}" - https_target_id_2 = "${length(split(",", var.target_ids)) >= 2 ? "${local.https_tg_attachment_conditionals}" :0}" - https_target_id_3 = "${length(split(",", var.target_ids)) >= 3 ? "${local.https_tg_attachment_conditionals}" :0}" - https_target_id_4 = "${length(split(",", var.target_ids)) >= 4 ? "${local.https_tg_attachment_conditionals}" :0}" - https_target_id_5 = "${length(split(",", var.target_ids)) >= 5 ? "${local.https_tg_attachment_conditionals}" :0}" - https_target_id_6 = "${length(split(",", var.target_ids)) >= 6 ? "${local.https_tg_attachment_conditionals}" :0}" - https_target_id_7 = "${length(split(",", var.target_ids)) >= 7 ? "${local.https_tg_attachment_conditionals}" :0}" - https_target_id_8 = "${length(split(",", var.target_ids)) >= 8 ? "${local.https_tg_attachment_conditionals}" :0}" + https_target_id_1 = length(split(",", var.target_ids)) >= 1 ? local.https_tg_attachment_conditionals : 0 + https_target_id_2 = length(split(",", var.target_ids)) >= 2 ? local.https_tg_attachment_conditionals : 0 + https_target_id_3 = length(split(",", var.target_ids)) >= 3 ? local.https_tg_attachment_conditionals : 0 + https_target_id_4 = length(split(",", var.target_ids)) >= 4 ? local.https_tg_attachment_conditionals : 0 + https_target_id_5 = length(split(",", var.target_ids)) >= 5 ? local.https_tg_attachment_conditionals : 0 + https_target_id_6 = length(split(",", var.target_ids)) >= 6 ? local.https_tg_attachment_conditionals : 0 + https_target_id_7 = length(split(",", var.target_ids)) >= 7 ? local.https_tg_attachment_conditionals : 0 + https_target_id_8 = length(split(",", var.target_ids)) >= 8 ? local.https_tg_attachment_conditionals : 0 } + diff --git a/outputs.tf b/outputs.tf index f31073b..3358a44 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,20 +1,25 @@ #The name of the LB output "lb_name" { - value = "${aws_lb.application_loadbalancer.name}" + value = aws_lb.application_loadbalancer.name } + #The ARN of the load balancer output "lb_arn" { - value = "${aws_lb.application_loadbalancer.arn}" + value = aws_lb.application_loadbalancer.arn } + #The DNS name of the load balancer output "lb_dns_name" { - value = "${aws_lb.application_loadbalancer.dns_name}" + value = aws_lb.application_loadbalancer.dns_name } + #The ARN suffix for use with CloudWatch Metrics output "lb_arn_suffix" { - value = "${aws_lb.application_loadbalancer.arn_suffix}" + value = aws_lb.application_loadbalancer.arn_suffix } + #The canonical hosted zone ID of the load balancer (to be used in a Route 53 Alias record) output "lb_zone_id" { - value = "${aws_lb.application_loadbalancer.zone_id}" + value = aws_lb.application_loadbalancer.zone_id } + diff --git a/security_groups.tf b/security_groups.tf index 62cca85..99521cf 100644 --- a/security_groups.tf +++ b/security_groups.tf @@ -1,57 +1,59 @@ -# Security group "group" for loadbalancer with no rules. To be used in other security group rules to specify the loadblaancer as the source. +# Security group "group" for loadbalancer with no rules. +#To be used in other security group rules to specify the loadblaancer as the source. resource "aws_security_group" "lb_group" { name = "Group-ALB-${var.lb_name}" description = "Attach security group with loadbalancer name to loadbalancer with no rules" - vpc_id = "${var.vpc_id}" + vpc_id = var.vpc_id } -# Security group which allows all outbound traffic -resource "aws_security_group" "rule_all_out" { - name = "Rule-all-out-all" - description = "Allow all outgoing traffic" - vpc_id = "${var.vpc_id}" +#http +resource "aws_security_group" "group_loadbalancer_in_http" { + count = local.create_sg_http_in + name = "tf-rule-alb-${var.prefix}${var.lb_name}-in-${lookup(element(var.http_target_group_parameters, 0), "port")}-${lookup(element(var.http_target_group_parameters, length(var.http_target_group_parameters)), "port")}" + description = "Allow the load balancer in on ports ${lookup(element(var.http_target_group_parameters, 0), "port")}-${lookup(element(var.http_target_group_parameters, length(var.http_target_group_parameters)), "port")}" + vpc_id = var.vpc_id } -resource "aws_security_group_rule" "rule_all_out" { - type = "egress" - from_port = 0 - to_port = 0 - protocol = -1 - cidr_blocks = ["0.0.0.0/0"] +resource "aws_security_group_rule" "rule_loadbalancer_in_http" { + count = local.create_sg_http_in + description = "Allow the load balancer in on ports ${lookup(element(var.http_target_group_parameters, 0), "port")}-${length(var.http_target_group_parameters)}" + type = "ingress" + from_port = lookup(element(var.http_target_group_parameters, 0), "port") + to_port = lookup(element(var.http_target_group_parameters, length(var.http_target_group_parameters)), "port") + protocol = "tcp" + source_security_group_id = aws_security_group.lb_group.id - security_group_id = "${aws_security_group.rule_all_out.id}" + security_group_id = aws_security_group.group_loadbalancer_in_http[0].id } -# Security group to allow traffic in on the http listener port -resource "aws_security_group" "lb_http_listener_traffic_in" { - name = "${var.lb_sg_http_name != "" ? "${var.lb_sg_http_name}" : "Rule-allow-${var.lb_source_traffic_name}-in-HTTP"}" - description = "Allow traffic in from ${var.lb_source_traffic_name} on HTTP" - vpc_id = "${var.vpc_id}" +resource "aws_network_interface_sg_attachment" "sg_http_attachment" { + count = local.create_sg_http_attach + security_group_id = aws_security_group.group_loadbalancer_in_http[0].id + network_interface_id = data.aws_instance.target_group_instances[count.index].network_interface_id } -resource "aws_security_group_rule" "rule_allow_lb_http_listener_traffic_in" { - type = "ingress" - from_port = "${var.lb_http_listener_port}" - to_port = "${var.lb_http_listener_port}" - protocol = "tcp" - cidr_blocks = ["${var.rule_allow_lb_http_listener_traffic_in_cidr_blocks}"] - - security_group_id = "${aws_security_group.lb_http_listener_traffic_in.id}" +# https +resource "aws_security_group" "group_loadbalancer_in_https" { + count = local.create_sg_https_in + name = "tf-rule-alb-${var.prefix}${var.lb_name}-in-${lookup(element(var.https_target_group_parameters, 0), "port")}-${lookup(element(var.https_target_group_parameters, length(var.https_target_group_parameters)), "port")}" + description = "Allow the load balancer in on ports ${lookup(element(var.https_target_group_parameters, 0), "port")}-${lookup(element(var.https_target_group_parameters, length(var.https_target_group_parameters)), "port")}" + vpc_id = var.vpc_id } -# Security group to allow traffic in on the https listener port -resource "aws_security_group" "lb_https_listener_traffic_in" { - name = "${var.lb_sg_https_name != "" ? "${var.lb_sg_https_name}" : "Rule-allow-${var.lb_source_traffic_name}-in-HTTPS"}" - description = "Allow traffic in from ${var.lb_source_traffic_name} on HTTPS" - vpc_id = "${var.vpc_id}" -} +resource "aws_security_group_rule" "rule_loadbalancer_in_https" { + count = local.create_sg_https_in + description = "Allow the load balancer in on ports ${lookup(element(var.https_target_group_parameters, 0), "port")}-${length(var.https_target_group_parameters)}" + type = "ingress" + from_port = lookup(element(var.https_target_group_parameters, 0), "port") + to_port = lookup(element(var.https_target_group_parameters, length(var.https_target_group_parameters)), "port") + protocol = "tcp" + source_security_group_id = aws_security_group.lb_group.id -resource "aws_security_group_rule" "rule_allow_lb_https_listener_traffic_in" { - type = "ingress" - from_port = "${var.lb_https_listener_port}" - to_port = "${var.lb_https_listener_port}" - protocol = "tcp" - cidr_blocks = ["${var.rule_allow_lb_https_listener_traffic_in_cidr_blocks}"] + security_group_id = aws_security_group.group_loadbalancer_in_https[0].id +} - security_group_id = "${aws_security_group.lb_https_listener_traffic_in.id}" +resource "aws_network_interface_sg_attachment" "sg_https_attachment" { + count = local.create_sg_https_attach + security_group_id = aws_security_group.group_loadbalancer_in_https[0].id + network_interface_id = data.aws_instance.target_group_instances[count.index].network_interface_id } diff --git a/variables_general.tf b/variables_general.tf index 98ac931..f234af1 100644 --- a/variables_general.tf +++ b/variables_general.tf @@ -1,10 +1,3 @@ -data "aws_caller_identity" "current" {} - -# Account -provider "aws" { - region = "${var.aws_region}" -} - # Region variable "aws_region" { description = "The AWS region to run in." @@ -14,6 +7,7 @@ variable "aws_region" { # VPC ID variable "vpc_id" { description = "The VPC ID in which the resources should be created." + default = "" } # Prefix @@ -27,3 +21,4 @@ variable "suffix" { description = "A suffix which is added to each resource name." default = "" } + diff --git a/variables_http_target_group.tf b/variables_http_target_group.tf index 9241891..d9689dd 100644 --- a/variables_http_target_group.tf +++ b/variables_http_target_group.tf @@ -1,29 +1,31 @@ ### HTTP target group variables ### -# HTTP target group names -variable "http_target_group_names" { - type = "list" - description = "Name(s) of the http target group(s)" - default = ["http-target-group"] #N.B. Target Group name acceptable characters: letters, digits or the dash -} - -# HTTP target group ports -variable "http_target_group_ports" { - type = "list" - description = "Port(s) of the http target group(s)" - default = [80] +variable "http_target_group_parameters" { + #https://github.com/terraform-providers/terraform-provider-aws/pull/8268 + type = list(object({ + target_group = string + host_headers = list(string) + port = number + })) + default = [ + { + target_group = "default-http" + host_headers = ["default.com"] + port = 80 + } + ] } # HTTP target group degregistration delay variable "http_target_group_deregistration_delay" { description = "Deregistration delay for the http target group(s)" - default = 300 #Possible values in seconds: 0-3600 + default = 300 #Possible values in seconds: 0-3600 } ##HTTP target group health checks # HTTP target group health check intveral variable "http_health_check_interval" { description = "Set HTTP health check interval" - default = 30 #min=5 max=300 + default = 30 #min=5 max=300 } # HTTP target group health check path @@ -47,7 +49,7 @@ variable "http_health_check_protocol" { # HTTP target group health check timeout variable "http_health_check_timeout" { description = "Set HTTP health check timeout" - default = 5 #min=2 max=60 + default = 5 #min=2 max=60 } # HTTP target group health check healthy threshold @@ -65,7 +67,7 @@ variable "http_health_check_unhealthy_threshold" { # HTTP target group health check matcher variable "http_health_check_matcher" { description = "Set HTTP health check matcher" - default = 200 #Matcher aka success code. Range-example: 200-299 + default = 200 #Matcher aka success code. Range-example: 200-299 } ## HTTP target group sticky cookie settings @@ -78,5 +80,6 @@ variable "http_target_group_stickiness_enabled" { # HTTP cookie duration for stickiness if enabled variable "http_target_group_stickiness_cookie_duration" { description = "Cookie Duration for stickiness of the http target group(s)" - default = 8640 #Possible values 1-604800 (604800 = 1 day). + default = 8640 #Possible values 1-604800 (604800 = 1 day). } + diff --git a/variables_https_target_group.tf b/variables_https_target_group.tf index 5aebb29..b12f473 100644 --- a/variables_https_target_group.tf +++ b/variables_https_target_group.tf @@ -1,29 +1,31 @@ ### HTTPS target group variables ### -# HTTPS target group names -variable "https_target_group_names" { - type = "list" - description = "Name(s) of the https target group(s)" - default = ["https-target-group"] #N.B. Target Group name acceptable characters: letters, digits or the dash -} - -# HTTPS target group ports -variable "https_target_group_ports" { - type = "list" - description = "Port(s) of the https target group(s)" - default = [443] +variable "https_target_group_parameters" { + #https://github.com/terraform-providers/terraform-provider-aws/pull/8268 + type = list(object({ + target_group = string + host_headers = list(string) + port = number + })) + default = [ + { + target_group = "default-https" + host_headers = ["default.com"] + port = 443 + } + ] } # HTTPS target group degregistration delay variable "https_target_group_deregistration_delay" { description = "Deregistration delay for the https target group(s)" - default = 300 #Possible values in seconds: 0-3600 + default = 300 #Possible values in seconds: 0-3600 } ##HTTPS target group health checks # HTTPS target group health check intveral variable "https_health_check_interval" { description = "Set HTTPS health check interval" - default = 30 #min=5 max=300 + default = 30 #min=5 max=300 } # HTTPS target group health check path @@ -47,7 +49,7 @@ variable "https_health_check_protocol" { # HTTPS target group health check timeout variable "https_health_check_timeout" { description = "Set HTTPS health check timeout" - default = 5 #min=2 max=60 + default = 5 #min=2 max=60 } # HTTPS target group health check healthy threshold @@ -65,7 +67,7 @@ variable "https_health_check_unhealthy_threshold" { # HTTPS target group health check matcher variable "https_health_check_matcher" { description = "Set HTTPS health check matcher" - default = 200 #Matcher aka success code. Range-example: 200-299 + default = 200 #Matcher aka success code. Range-example: 200-299 } ## HTTPS target group sticky cookie settings @@ -78,5 +80,6 @@ variable "https_target_group_stickiness_enabled" { # HTTPS cookie duration for stickiness if enabled variable "https_target_group_stickiness_cookie_duration" { description = "Cookie Duration for stickiness of the https target group(s)" - default = 8640 #Possible values 1-604800 (604800 = 1 day). + default = 8640 #Possible values 1-604800 (604800 = 1 day). } + diff --git a/variables_listeners.tf b/variables_listeners.tf new file mode 100644 index 0000000..d171325 --- /dev/null +++ b/variables_listeners.tf @@ -0,0 +1,36 @@ +# Load balancer listener variables +## Load balancer HTTP listener needed? +variable "create_lb_http_listener" { + description = "If true add a HTTP listener" + default = false +} + +## Load balancer HTTPS listener needed? +variable "create_lb_https_listener" { + description = "If true add a HTTPS listener" + default = false +} + +## Load balancer HTTPS offloading? +variable "enable_lb_https_offloading" { + description = "If true offload to HTTP" + default = true +} + +## Load balancer HTTP listener port +variable "lb_http_listener_port" { + description = "HTTP listener port of the loadbalancer" + default = 80 +} + +## Loadbalancer HTTPS listener port +variable "lb_https_listener_port" { + description = "HTTPS listener port of the loadbalancer" + default = 443 +} + +## Certificate ARN for the HTTPS listener +variable "certificate_arn" { + description = "Certificate ARN for the HTTPS listener" + default = null +} diff --git a/variables_load_balancer.tf b/variables_load_balancer.tf index 6c8885c..9850cf2 100644 --- a/variables_load_balancer.tf +++ b/variables_load_balancer.tf @@ -1,6 +1,6 @@ ## Load balancer variables # Load balancer internal or external -variable "lb_internal" { +variable "create_internal_lb" { description = "Define if the loadbalancer should be internal or not" default = true } @@ -11,60 +11,20 @@ variable "lb_name" { default = "loadbalancer" } -# Load balancer public subnet groups -variable "lb_public_subnet_ids" { - type = "list" - description = "The Public Subnet ID(s) which should be attached to the loadbalancer" - default = [] -} - -# Load balancer private subnet groups -variable "lb_private_subnet_ids" { - type = "list" - description = "The Private Subnet ID(s) which should be attached to the loadbalancer" +# Load balancer subnet groups +variable "lb_subnet_ids" { + type = list(string) + description = "The subnet ID(s) which should be attached to the loadbalancer" default = [] } ## Load balancer security groups -# Load balancer additional security groups variable "lb_security_group_ids" { - type = "list" + type = list(string) description = "Additional Security Group ID(s) which should be attached to the loadbalancer" default = [] } -# Loadbalancer source traffic name (for security group allowing listener traffic in) -variable "lb_source_traffic_name" { - description = "Name of source traffic for the loadbalancer within the HTTP and HTTPS security group. E.g. Rule-allow-${var.lb_source_traffic_name}-in-HTTP" - default = "" -} - -# Loadbalancer HTTP security group name -variable "lb_sg_http_name" { - description = "Name of the HTTP security group" - default = "" -} - -# Loadbalancer HTTPS security group name -variable "lb_sg_https_name" { - description = "Name of the HTTP security group" - default = "" -} - -# CIDR blocks specifying IP(s) allowed in on the http listener port for the loadbalancer -variable "rule_allow_lb_http_listener_traffic_in_cidr_blocks" { - type = "list" - description = "CIDR blocks loadbalancer http listener source traffic" - default = ["0.0.0.0/0"] -} - -# CIDR blocks specifying IP(s) allowed in on the https listener port for the loadbalancer -variable "rule_allow_lb_https_listener_traffic_in_cidr_blocks" { - type = "list" - description = "CIDR blocks loadbalancer https listener source traffic" - default = ["0.0.0.0/0"] -} - # Load balancer idle timeout variable "lb_idle_timeout" { description = "Idle timeout for the loadbalancer." @@ -77,59 +37,31 @@ variable "lb_enable_http2" { default = true } -# Load balancer deletion protection -variable "lb_enable_deletion_protection" { - description = "Enable deletion protection" - default = false -} - -## Load balancer listener variables -# Load balancer HTTP listener needed? -variable "lb_http_listener" { - description = "If true add a HTTP listener" +# Load balancer logs bucket +variable "lb_logs_bucket_enabled" { + description = "Boolean to enable / disable access_logs" default = true } -# Load balancer HTTPS listener needed? -variable "lb_https_listener" { - description = "If true add a HTTPS listener" - default = false -} - -# Load balancer HTTPS offloading? -variable "lb_https_offloading" { - description = "If true offload to HTTP" - default = false -} - -# Load balancer HTTP listener port -variable "lb_http_listener_port" { - description = "HTTP listener port of the loadbalancer" - default = 80 -} - -# Loadbalancer HTTPS listener port -variable "lb_https_listener_port" { - description = "HTTPS listener port of the loadbalancer" - default = 443 +variable "lb_logs_bucket_name" { + description = "The S3 bucket name to store the logs in" + default = "" } -# HTTP host headers for load balancer listener rules -variable "http_host_headers" { - type = "list" - description = "Http ost headers for load balancer listener rules" - default = [] +variable "lb_logs_bucket_prefix" { + description = "The S3 bucket prefix. Logs are stored in the root if not configured" + default = "" } -# HTTPS host headers for load balancer listener rules -variable "https_host_headers" { - type = "list" - description = "Https ost headers for load balancer listener rules" - default = [] +# Load balancer deletion protection +variable "lb_enable_deletion_protection" { + description = "Enable deletion protection" + default = false } -# Certificate ARN for the HTTPS listener -variable "certificate_arn" { - description = "Certificate ARN for the HTTPS listener" - default = "" +# Tags +variable "lb_tags" { + description = "Tags for the load balancer" + type = map(string) + default = {} } diff --git a/variables_shared_target_group.tf b/variables_shared_target_group.tf index 981e2ff..ec109bd 100644 --- a/variables_shared_target_group.tf +++ b/variables_shared_target_group.tf @@ -3,3 +3,9 @@ variable "target_ids" { description = "Instance IDs for the target group(s)" default = "" } + +variable "tg_tags" { + description = "Tags for target groups" + type = map(string) + default = {} +} diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..ac97c6a --- /dev/null +++ b/versions.tf @@ -0,0 +1,4 @@ + +terraform { + required_version = ">= 0.12" +}