Conditional nested blocks in Terraform

Here’s a useful technique for using Terraform’s dynamic blocks to create conditional nested blocks.

Maintenance mode

As an example, let’s create a “maintenance mode” for a service which allows a “under maintenance” holding page to be served when a Terraform variable is set.

This is useful if you need to stop all traffic to a RDS database server so it can be upgraded.

Define a boolean maintenance_mode variable:

# variables.tf

variable "maintenance_mode" {
  type    = bool
  default = false
}

and use it to create conditional default_action blocks in an aws_lb_listener resource.

# main.tf

resource "aws_lb_listener" "this" {
  load_balancer_arn = aws_lb.this.arn
  port              = 443
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS-1-2-2017-01"

  dynamic "default_action" {
    for_each = var.maintenance_mode ? [] : [1]
    content {
      type             = "forward"
      target_group_arn = aws_lb_target_group.this.arn
    }
  }

  dynamic "default_action" {
    for_each = var.maintenance_mode ? [1] : []
    content {
      type = "fixed-response"
      fixed_response {
        content_type = "text/html"
        message_body = file("${path.module}/pages/scheduled-maintenance.html")
        status_code  = "503"
      }
    }
  }
}

If maintenance_mode is false, the load balancer will forward traffic to the target group as normal. But if true, a HTTP 503 response will be returned with a simple HTML payload.

This allows you to easily adjust a load balancer to serve a temporary holding page, which gives you time to perform whatever maintenance you need to do.

Only downside is the message_body attribute must be 1024 bytes or fewer, so you need quite a minimal “under maintenance” page.

Idea from this comment from the Terraform Github repository.

Further reading:

----

Something wrong? Suggest an improvement or add a comment (see article history)
Tagged with: terraform
Filed in: tips

Previous: Maintainable Terraform CIDR lists
Next: Setting up a 2020 MacBook Pro for Python development

Copyright © 2005-2020 David Winterbottom
Content licensed under CC BY-NC-SA 4.0.