Skip to content

HTTP 301 and 302 redirects made simple utilising an ALB and listener rules.

License

Notifications You must be signed in to change notification settings

Flaconi/terraform-aws-alb-redirect

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Terraform AWS ALB Redirect

lint test Tag License

This Terraform module can create HTTP 301 and 302 redirects using the AWS Application Load Balancer

Usage

alb_redirect module

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 (optional)
  certificate_arn = aws_acm_certificate.acme[0].arn

  # extra_ssl_certs sets the extra ssl certificate arns applied to the SSL Listener (optional)
  extra_ssl_certs = {
    cert1 = aws_acm_certificate.acme[1].arn
    cert2 = aws_acm_certificate.acme[2].arn
  }

  # 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, hence we disable it for HTTPS
      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"
      disabled_for      = "HTTPS"
    },
    {
      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

Providers

Name Version
aws >= 4

Requirements

Name Version
terraform >= 1.0
aws >= 4
'

Required Inputs

The following input variables are required:

Description: The name used to interpolate into the resources created

Type: string

Optional Inputs

The following input variables are optional (have default values):

Description: The cidr used for the network

Type: string

Default: "172.30.0.0/16"

Description: Extra tags to be applied to the resources

Type: map(string)

Default: {}

Description: Do we enable https

Type: bool

Default: false

Description: The arn of the certificate

Type: string

Default: ""

Description: Map of extra ssl certificates arns applied to the SSL Listener

Type: map(string)

Default: {}

Description: A list with maps populated with redirect rules

Type: list(map(string))

Default: []

Description: The ip_address_type of the LB, either 'ipv4' or 'dualstack' in case ipv6 needs to be supported as well

Type: string

Default: "ipv4"

Description: Do we configure IPv6 routing and ingress in the VPC

Type: bool

Default: false

Description: The default response message body in case no rules have been met

Type: string

Default: "No match"

Description: The default status code to return when no rules have been met

Type: string

Default: "500"

Description: Security policy used for front-end connections.

Type: string

Default: "ELBSecurityPolicy-FS-1-2-Res-2020-10"

Outputs

Name Description
dns_name Application Load Balancer fqdn
zone_id Application Load Balancer Route53 Zone ID

License

MIT

Copyright (c) 2019 Flaconi GmbH