diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d9d95d9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,31 @@ +--- + +### +### Travis settings +### +sudo: required +services: + - docker + + +### +### Installation +### +before_install: true +install: true + + +### +### Linting +### +before_script: + - make lint + - make gen + - git diff --quiet || { echo "Build Changes"; git diff; git status; false; } + + +### +### Testing +### +script: + - make test ARGS="-var assumer_account_role_name=test -var assumer_account_id=1234567890" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..631520d --- /dev/null +++ b/Makefile @@ -0,0 +1,204 @@ +ifneq (,) +.error This Makefile requires GNU Make. +endif + +.PHONY: help gen lint test _gen-main _gen-examples _gen-modules _lint_files _lint_fmt _pull-tf _pull-tf-docs + +CURRENT_DIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +TF_EXAMPLES = $(sort $(dir $(wildcard $(CURRENT_DIR)examples/*/))) +TF_MODULES = $(sort $(dir $(wildcard $(CURRENT_DIR)modules/*/))) + +TF_VERSION = light +TF_DOCS_VERSION = 0.6.0 + +# Adjust your delimiter here or overwrite via make arguments +DELIM_START = +DELIM_CLOSE = + +help: + @echo "gen Generate terraform-docs output and replace in all README.md's" + @echo "lint Static source code analysis" + @echo "test Integration tests" + +gen: _pull-tf-docs + @echo "################################################################################" + @echo "# Terraform-docs generate" + @echo "################################################################################" + @$(MAKE) --no-print-directory _gen-main + @$(MAKE) --no-print-directory _gen-examples + @$(MAKE) --no-print-directory _gen-modules + +lint: _pull-tf + @$(MAKE) --no-print-directory _lint_files + @$(MAKE) --no-print-directory _lint_fmt + +test: _pull-tf + @$(foreach example,\ + $(TF_EXAMPLES),\ + DOCKER_PATH="/t/examples/$(notdir $(patsubst %/,%,$(example)))"; \ + echo "################################################################################"; \ + echo "# examples/$$( basename $${DOCKER_PATH} )"; \ + echo "################################################################################"; \ + echo; \ + echo "------------------------------------------------------------"; \ + echo "# Terraform init"; \ + echo "------------------------------------------------------------"; \ + if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ + init \ + -verify-plugins=true \ + -lock=false \ + -upgrade=true \ + -reconfigure \ + -input=false \ + -get-plugins=true \ + -get=true \ + .; then \ + echo "OK"; \ + else \ + echo "Failed"; \ + docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ + exit 1; \ + fi; \ + echo; \ + echo "------------------------------------------------------------"; \ + echo "# Terraform validate"; \ + echo "------------------------------------------------------------"; \ + if docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" hashicorp/terraform:$(TF_VERSION) \ + validate \ + $(ARGS) \ + .; then \ + echo "OK"; \ + docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ + else \ + echo "Failed"; \ + docker run -it --rm -v "$(CURRENT_DIR):/t" --workdir "$${DOCKER_PATH}" --entrypoint=rm hashicorp/terraform:$(TF_VERSION) -rf .terraform/ || true; \ + exit 1; \ + fi; \ + echo; \ + ) + +_gen-main: + @echo "------------------------------------------------------------" + @echo "# Main module" + @echo "------------------------------------------------------------" + @if docker run --rm \ + -v $(CURRENT_DIR):/data \ + -e DELIM_START='$(DELIM_START)' \ + -e DELIM_CLOSE='$(DELIM_CLOSE)' \ + cytopia/terraform-docs:$(TF_DOCS_VERSION) \ + terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md README.md; then \ + echo "OK"; \ + else \ + echo "Failed"; \ + exit 1; \ + fi + +_gen-examples: + @$(foreach example,\ + $(TF_EXAMPLES),\ + DOCKER_PATH="examples/$(notdir $(patsubst %/,%,$(example)))"; \ + echo "------------------------------------------------------------"; \ + echo "# $${DOCKER_PATH}"; \ + echo "------------------------------------------------------------"; \ + if docker run --rm \ + -v $(CURRENT_DIR):/data \ + --workdir "/data/$${DOCKER_PATH}" \ + -e DELIM_START='$(DELIM_START)' \ + -e DELIM_CLOSE='$(DELIM_CLOSE)' \ + cytopia/terraform-docs:$(TF_DOCS_VERSION) \ + terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md $${DOCKER_PATH}/README.md; then \ + echo "OK"; \ + else \ + echo "Failed"; \ + exit 1; \ + fi; \ + ) + +_gen-modules: + @$(foreach module,\ + $(TF_MODULES),\ + DOCKER_PATH="modules/$(notdir $(patsubst %/,%,$(module)))"; \ + echo "------------------------------------------------------------"; \ + echo "# $${DOCKER_PATH}"; \ + echo "------------------------------------------------------------"; \ + if docker run --rm \ + -v $(CURRENT_DIR):/data \ + -e DELIM_START='$(DELIM_START)' \ + -e DELIM_CLOSE='$(DELIM_CLOSE)' \ + cytopia/terraform-docs:$(TF_DOCS_VERSION) \ + terraform-docs-replace-012 --sort-inputs-by-required --with-aggregate-type-defaults md $${DOCKER_PATH}/README.md; then \ + echo "OK"; \ + else \ + echo "Failed"; \ + exit 1; \ + fi; \ + ) + +_lint_files: + @# Lint all non-binary files for trailing spaces + @echo "################################################################################" + @echo "# Lint files" + @echo "################################################################################" + @echo + @echo "------------------------------------------------------------" + @echo "# Trailing spaces" + @echo "------------------------------------------------------------" + find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ + | xargs -0 -n1 grep -Il '' \ + | tr '\n' '\0' \ + | xargs -0 -n1 \ + sh -c 'if [ -f "$${1}" ]; then if LC_ALL=C grep --color=always -inHE "^.*[[:blank:]]+$$" "$${1}";then false; else true; fi; fi' -- + @echo + @echo "------------------------------------------------------------" + @echo "# Windows line feeds (CRLF)" + @echo "------------------------------------------------------------" + find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ + | xargs -0 -n1 grep -Il '' \ + | tr '\n' '\0' \ + | xargs -0 -n1 \ + sh -c 'if [ -f "$${1}" ]; then if file "$${1}" | grep --color=always -E "[[:space:]]CRLF[[:space:]].*line"; then false; else true; fi; fi' -- + @echo + @echo "------------------------------------------------------------" + @echo "# Single trailing newline" + @echo "------------------------------------------------------------" + find . -type f -not \( -path "*/.git/*" -o -path "*/.github/*" -o -path "*/.terraform/*" \) -print0 \ + | xargs -0 -n1 grep -Il '' \ + | tr '\n' '\0' \ + | xargs -0 -n1 \ + sh -c 'if [ -f "$${1}" ]; then if ! (tail -c 1 "$${1}" | grep -Eq "^$$" && tail -c 2 "$${1}" | grep -Eqv "^$$"); then echo "$${1}"; false; else true; fi; fi' -- + @echo + +_lint_fmt: + @# Lint all Terraform files + @echo "################################################################################" + @echo "# Terraform fmt" + @echo "################################################################################" + @echo + @echo "------------------------------------------------------------" + @echo "# *.tf files" + @echo "------------------------------------------------------------" + @if docker run --rm -v "$(CURRENT_DIR):/t:ro" --workdir "/t" hashicorp/terraform:$(TF_VERSION) \ + fmt -check=true -diff=true -write=false -list=true /t; then \ + echo "OK"; \ + else \ + echo "Failed"; \ + exit 1; \ + fi; + @echo + @echo "------------------------------------------------------------" + @echo "# *.tfvars files" + @echo "------------------------------------------------------------" + @if docker run --rm --entrypoint=/bin/sh -v "$(CURRENT_DIR)/terraform:/t:ro" hashicorp/terraform:$(TF_VERSION) \ + -c "find . -name '*.tfvars' -type f -print0 | xargs -0 -n1 terraform fmt -check=true -write=false -diff=true -list=true"; then \ + echo "OK"; \ + else \ + echo "Failed"; \ + exit 1; \ + fi; + @echo + +_pull-tf: + docker pull hashicorp/terraform:$(TF_VERSION) + +_pull-tf-docs: + docker pull cytopia/terraform-docs:$(TF_DOCS_VERSION) diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7205f4 --- /dev/null +++ b/README.md @@ -0,0 +1,177 @@ +# Terraform AWS ALB Redirect + +[![Build Status](https://travis-ci.com/Flaconi/terraform-aws-alb-redirect.svg?branch=master)](https://travis-ci.com/Flaconi/erraform-aws-alb-redirect) +[![Tag](https://img.shields.io/github/tag/Flaconi/terraform-aws-alb-redirect.svg)](https://github.com/Flaconi/terraform-aws-alb-redirect/releases) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) + +This Terraform module can create HTTP 301 and 302 redirects using the AWS Application Load Balancer + +## Usage + +### alb_redirect module + +```hcl +module "alb_redirect" { + source = "../../" + + name = "redirect-service" + + # This can be left to its default + # cidr = "172.30.0.0/16" + + # extra tags to be applied to the resources + tags = { + Terraform = "generated" + } + + # do we enable the https listener + https_enabled = true + + # certificate_arn sets the certificate arn for the https listener, not mandatory + certificate_arn = aws_acm_certificate.acme[0].arn + + # extra_ssl_certs sets the extra ssl certificate arns applied to the SSL Listener, not mandagtory + extra_ssl_certs = [aws_acm_certificate.acme[1].arn, aws_acm_certificate.acme[2].arn] + + # extra_ssl_certs_count, the count of the extra_ssl_certs + extra_ssl_certs_count = 2 + + # lb_ip_address_type sets the `ip_address_type` of the LB, either 'ipv4' or 'dualstack' in case ipv6 needs to be supported as well + # lb_ip_address_type = "ipv4" + + # response_message_body sets the default response message body in case no rules have been met" + # response_message_body = "No Match" + + # response_code sets the status code to return when no rules have been met" + # response_code = 500 + + + redirect_rules = [ + { + # Match host `somehost.tld`, match path `/wikipedia` 302 forward to https://www.wikipedia.org/ + # unless redirect_query is set to "" the query params will be kept by default + # path will be preserved + # status code will be 302 by default + host_match = "somehost.tld" + path_match = "/wikipedia" + redirect_host = "www.wikipedia.org" + redirect_protocol = "HTTPS" + redirect_path = "/" + redirect_port = "443" + # redirect_status_code = "HTTP_302" + # redirect_query = "#{query}" + }, + { + # Match host `somehost2.tld`, match all paths, permanent forward to https://example.com + # path will be preserved + # query params will be preserved + path_match = "*" + host_match = "somehost2.tld" + redirect_host = "example.com" + redirect_protocol = "HTTPS" + redirect_path = "/#{path}" + redirect_status_code = "HTTP_301" + redirect_port = "443" + redirect_query = "" + }, + { + # Match host `somehost3.tld`, match all paths, forward to http://http-redir-cannot-be-created-on-https-listener.example.com + # path will be preserved + # query params will be preserved + # this will only work on http listener as redirects from HTTPS to HTTP are not supported + path_match = "*" + host_match = "somehost3.tld" + redirect_host = "http-redir-cannot-be-created-on-https-listener.example.com" + redirect_protocol = "HTTP" + redirect_path = "/" + redirect_port = "80" + }, + { + path_match = "/danger-forward-all-uris-of-all-hosts'" + host_match = "*" + redirect_host = "to-this-subdomain-of.example.com" + redirect_protocol = "HTTPS" + redirect_path = "/" + redirect_port = "80" + } + ] +} + +locals { + ssl_domains = ["somehost.tld", "somehost2.tld", "somehost3.tld"] +} + +resource "tls_private_key" "this" { + algorithm = "RSA" +} + +resource "tls_self_signed_cert" "acme" { + count = 3 + key_algorithm = "RSA" + private_key_pem = tls_private_key.this.private_key_pem + + subject { + common_name = local.ssl_domains[count.index] + organization = "ACME Examples, Inc" + } + + validity_period_hours = 12 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] +} + +resource "aws_acm_certificate" "acme" { + count = 3 + private_key = tls_private_key.this.private_key_pem + certificate_body = tls_self_signed_cert.acme[count.index].cert_pem +} +``` + +## Resources + +The following resources _CAN_ be created: + +- 1 VPC +- 1 IGW +- 2 Subnets +- 1 Routing Table +- 1 Security Group +- 1 LB +- 2 HTTP Listeners ( HTTP / HTTPS) +- 2 HTTP Listener Rules + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|:----:|:-----:|:-----:| +| name | The name used to interpolate into the resources created | string | n/a | yes | +| certificate\_arn | The arn of the certificate | string | `""` | no | +| cidr | The cidr used for the network | string | `"172.30.0.0/16"` | no | +| extra\_ssl\_certs | The extra ssl certifice arns applied to the SSL Listener | list | `[]` | no | +| extra\_ssl\_certs\_count | The count of the extra_ssl_certs | string | `"0"` | no | +| https\_enabled | Do we enable https | string | `"false"` | no | +| lb\_ip\_address\_type | The `ip_address_type` of the LB, either 'ipv4' or 'dualstack' in case ipv6 needs to be supported as well | string | `"ipv4"` | no | +| redirect\_rules | A list with maps populated with redirect rules | list | `[]` | no | +| response\_code | The default status code to return when no rules have been met | string | `"500"` | no | +| response\_message\_body | The default response message body in case no rules have been met | string | `"No match"` | no | +| tags | Extra tags to be applied to the resources | map | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| this\_lb\_dns\_name | Application Load Balancer fqdn | + + + + +## License + +[MIT](LICENSE) + +Copyright (c) 2019 [Flaconi GmbH](https://github.com/Flaconi) diff --git a/data.tf b/data.tf new file mode 100644 index 0000000..e86957a --- /dev/null +++ b/data.tf @@ -0,0 +1,4 @@ +# ------------------------------------------------------------------------------------------------- +# Datasources +# ------------------------------------------------------------------------------------------------- +data "aws_availability_zones" "available" {} diff --git a/examples/complete/README.md b/examples/complete/README.md new file mode 100644 index 0000000..f65f762 --- /dev/null +++ b/examples/complete/README.md @@ -0,0 +1,10 @@ +# Example + + +## Outputs + +| Name | Description | +|------|-------------| +| redirect\_this\_lb\_dns\_name | Application Load Balancer fqdn | + + diff --git a/examples/complete/main.tf b/examples/complete/main.tf new file mode 100644 index 0000000..40e2394 --- /dev/null +++ b/examples/complete/main.tf @@ -0,0 +1,121 @@ +provider "aws" { + region = "us-east-1" +} + +locals { + ssl_domains = ["somehost.tld", "somehost2.tld", "somehost3.tld"] +} + +resource "tls_private_key" "this" { + algorithm = "RSA" +} + +resource "tls_self_signed_cert" "acme" { + count = 3 + key_algorithm = "RSA" + private_key_pem = tls_private_key.this.private_key_pem + + subject { + common_name = local.ssl_domains[count.index] + organization = "ACME Examples, Inc" + } + + validity_period_hours = 12 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] +} + +resource "aws_acm_certificate" "acme" { + count = 3 + private_key = tls_private_key.this.private_key_pem + certificate_body = tls_self_signed_cert.acme[count.index].cert_pem +} + +module "redirect" { + source = "../../" + + name = "redirect-service" + + # This can be left to its default + # cidr = "172.30.0.0/16" + + # extra tags to be applied to the resources + tags = { + Terraform = "generated" + } + + # do we enable the https listener + https_enabled = true + + # certificate_arn sets the certificate arn for the httpx listener + certificate_arn = aws_acm_certificate.acme[0].arn + + # extra_ssl_certs sets the extra ssl certificate arns applied to the SSL Listener + extra_ssl_certs = [aws_acm_certificate.acme[1].arn, aws_acm_certificate.acme[2].arn] + + # extra_ssl_certs_count, the count of the extra_ssl_certs + extra_ssl_certs_count = 2 + + # lb_ip_address_type sets the `ip_address_type` of the LB, either 'ipv4' or 'dualstack' in case ipv6 needs to be supported as well + # lb_ip_address_type = "ipv4" + + # response_message_body sets the default response message body in case no rules have been met" + # response_message_body = "No Match" + + # response_code sets the status code to return when no rules have been met" + # response_code = 500 + + redirect_rules = [ + { + # Match host `somehost.tld`, match path `/wikipedia` 302 forward to https://www.wikipedia.org/ + # unless redirect_query is set to "" the query params will be kept by default + # path will be preserved + # status code will be 302 by default + host_match = "somehost.tld" + path_match = "/wikipedia" + redirect_host = "www.wikipedia.org" + redirect_protocol = "HTTPS" + redirect_path = "/" + redirect_port = "443" + # redirect_status_code = "HTTP_302" + # redirect_query = "" + }, + { + # Match host `somehost2.tld`, match all paths, permanent forward to https://example.com + # path will be preserved + # query params will be preserved + path_match = "*" + host_match = "somehost2.tld" + redirect_host = "example.com" + redirect_protocol = "HTTPS" + redirect_path = "/#{path}" + redirect_status_code = "HTTP_301" + redirect_port = "443" + redirect_query = "" + }, + { + # Match host `somehost3.tld`, match all paths, forward to http://http-redir-cannot-be-created-on-https-listener.example.com + # path will be preserved + # query params will be preserved + # this will only work on http listener as redicts from HTTPS to HTTP are not supported + path_match = "*" + host_match = "somehost3.tld" + redirect_host = "http-redir-cannot-be-created-on-https-listener.example.com" + redirect_protocol = "HTTP" + redirect_path = "/" + redirect_port = "80" + }, + { + path_match = "/danger-forward-all-uris-of-all-hosts'" + host_match = "*" + redirect_host = "to-this-subdomain-of.example.com" + redirect_protocol = "HTTPS" + redirect_path = "/" + redirect_port = "80" + } + ] +} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf new file mode 100644 index 0000000..3bd1f5a --- /dev/null +++ b/examples/complete/outputs.tf @@ -0,0 +1,4 @@ +output "redirect_this_lb_dns_name" { + value = module.redirect.this_lb_dns_name + description = "Application Load Balancer fqdn" +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..9c836dd --- /dev/null +++ b/main.tf @@ -0,0 +1,216 @@ +# ------------------------------------------------------------------------------------------------- +# VPC +# ------------------------------------------------------------------------------------------------- +resource "aws_vpc" "this" { + cidr_block = var.cidr + assign_generated_ipv6_cidr_block = true + + tags = merge( + { + "Name" = var.name + }, + var.tags, + ) +} + + +resource "aws_route_table" "public" { + vpc_id = aws_vpc.this.id + + tags = merge( + { + "Name" = var.name + "Type" = "public" + }, + var.tags, + ) +} + +resource "aws_subnet" "public" { + count = 2 + + vpc_id = aws_vpc.this.id + cidr_block = cidrsubnet(var.cidr, 8, count.index) + ipv6_cidr_block = cidrsubnet(aws_vpc.this.ipv6_cidr_block, 8, count.index) + map_public_ip_on_launch = false + assign_ipv6_address_on_creation = true + + availability_zone = data.aws_availability_zones.available.names[count.index] + + # If AWS adds another availability zone, this will not have effect on the already picked subnets. + lifecycle { + ignore_changes = ["availability_zone"] + } + + tags = merge( + { + "Name" = format( + "%s-%s", + var.name, + count.index, + ) + }, + var.tags, + ) +} + +resource "aws_route_table_association" "this" { + count = 2 + subnet_id = "${aws_subnet.public[count.index].id}" + route_table_id = "${aws_route_table.public.id}" +} + +resource "aws_route" "public_internet_gateway" { + route_table_id = aws_route_table.public.id + destination_cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.this.id + + timeouts { + create = "5m" + } +} + +resource "aws_internet_gateway" "this" { + vpc_id = aws_vpc.this.id + + tags = merge( + { + "Name" = var.name + }, + var.tags, + ) +} + +resource "aws_security_group" "this" { + name = "${var.name}-albredirect" + description = "Allow inbound 80/443 traffic alb redirect" + vpc_id = "${aws_vpc.this.id}" + + ingress { + # TLS (change to whatever ports you need) + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } +} + +# ------------------------------------------------------------------------------------------------- +# LB +# ------------------------------------------------------------------------------------------------- +resource "aws_lb" "this" { + load_balancer_type = "application" + name = var.name + security_groups = [aws_security_group.this.id] + subnets = aws_subnet.public.*.id + enable_cross_zone_load_balancing = false + enable_deletion_protection = false + enable_http2 = true + ip_address_type = var.lb_ip_address_type + tags = merge( + var.tags, + { + "Name" = var.name + }, + ) +} + +resource "aws_lb_listener" "http" { + load_balancer_arn = aws_lb.this.arn + port = 80 + protocol = "HTTP" + + default_action { + type = "fixed-response" + + fixed_response { + content_type = "text/plain" + message_body = var.response_message_body + status_code = var.response_code + } + } +} + +resource "aws_lb_listener" "https" { + count = var.https_enabled ? 1 : 0 + + load_balancer_arn = aws_lb.this.arn + port = 443 + protocol = "HTTPS" + certificate_arn = var.certificate_arn + ssl_policy = "ELBSecurityPolicy-2016-08" + + default_action { + type = "fixed-response" + + fixed_response { + content_type = "text/plain" + message_body = var.response_message_body + status_code = var.response_code + } + } +} + +resource "aws_lb_listener_certificate" "https" { + listener_arn = join("", aws_lb_listener.https.*.arn) + certificate_arn = var.extra_ssl_certs[count.index] + count = var.extra_ssl_certs_count +} + +locals { + listener_types = slice(["HTTP", "HTTPS"], 0, var.https_enabled ? 2 : 1) + + rules = flatten([ + for rule in var.redirect_rules : [ + for listener_type in local.listener_types : { + listener_type = listener_type, + rule = rule, + } + ]]) +} + +resource "aws_lb_listener_rule" "this" { + # If condition makes sure we not forward from HTTPS to HTTP, as this is not allowed by the AWS ALB + for_each = { for rule in local.rules : + "${rule.listener_type}://${rule.rule.host_match}${rule.rule.path_match}" => merge( + rule.rule, + { "listener_type" = rule.listener_type } + ) if ! (rule.rule.redirect_protocol == "HTTP" && rule.listener_type == "HTTPS") } + + listener_arn = each.value.listener_type == "HTTP" ? aws_lb_listener.http.arn : join("", aws_lb_listener.https.*.arn) + + action { + type = "redirect" + + redirect { + port = lookup(each.value, "redirect_port", "#{port}") + protocol = lookup(each.value, "redirect_protocol", "#{protocol}") + host = lookup(each.value, "redirect_host", "#{host}") + query = lookup(each.value, "redirect_query", null) + path = lookup(each.value, "redirect_path", null) + status_code = lookup(each.value, "redirect_status_code", "HTTP_302") + } + } + + dynamic condition { + for_each = lookup(each.value, "path_match", "*") != "*" ? [1] : [] + content { + field = "path-pattern" + values = [lookup(each.value, "path_match", "*")] + } + } + + dynamic condition { + for_each = lookup(each.value, "host_match", "*") != "*" ? [1] : [] + content { + field = "host-header" + values = [lookup(each.value, "host_match", "*")] + } + } +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..ae3a058 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,4 @@ +output "this_lb_dns_name" { + description = "Application Load Balancer fqdn" + value = aws_lb.this.dns_name +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..9dfb4e6 --- /dev/null +++ b/variables.tf @@ -0,0 +1,52 @@ +variable "name" { + description = "The name used to interpolate into the resources created" +} +variable "cidr" { + default = "172.30.0.0/16" + description = "The cidr used for the network" +} + +variable "tags" { + default = {} + description = "Extra tags to be applied to the resources" +} + +variable "https_enabled" { + default = false + description = "Do we enable https" +} + +variable "certificate_arn" { + default = "" + description = "The arn of the certificate" +} + +variable "extra_ssl_certs" { + default = [] + description = "The extra ssl certifice arns applied to the SSL Listener" +} + +variable "extra_ssl_certs_count" { + default = 0 + description = "The count of the extra_ssl_certs" +} + +variable "redirect_rules" { + default = [] + description = "A list with maps populated with redirect rules" +} + +variable "lb_ip_address_type" { + default = "ipv4" + description = "The `ip_address_type` of the LB, either 'ipv4' or 'dualstack' in case ipv6 needs to be supported as well" +} + +variable "response_message_body" { + default = "No match" + description = "The default response message body in case no rules have been met" +} + +variable "response_code" { + default = "500" + description = "The default status code to return when no rules have been met" +}