Skip to content

certificates and dns

Aleksej Komnenovic edited this page Jun 30, 2026 · 3 revisions

Certificates and DNS

ACM certificate provisioning and Route53 DNS record management for HTTPS access.

Why HTTPS is Required for BRMS

BRMS uses browser APIs that require a secure context:

  • Web Crypto API: cryptographic operations
  • Service Workers: offline support and caching

If the browser does not reach BRMS over HTTPS, BRMS displays a blank page. The browser must get HTTPS, but that HTTPS does not have to be terminated on the ALB.

There are two deployment shapes:

  1. TLS terminated on the ALB (default). The module's variable validation requires either route53_zone_id or certificate_arn so the ALB can serve HTTPS on port 443. This is the common case.
  2. TLS terminated at an upstream edge (alb_http_only = true). Set alb_http_only = true to make the BRMS ALB serve plain HTTP on port 80 with no certificate. A trusted edge such as CloudFront then terminates HTTPS in front of it and provides the secure context the browser needs. In this mode the validation does not require a certificate or route53_zone_id, and no ACM certificate or HTTPS listener is created. This mode requires alb_internal = true (the HTTP-only ALB must be internal and sit behind the TLS-terminating edge).

HTTPS to the browser is always required, but "the ALB serves HTTPS" is only enforced when alb_http_only is left at its default of false.

Two Ways to Provide HTTPS

Option 1: Route53 Zone ID (auto-managed)

Provide route53_zone_id and the module handles everything:

  1. Creates ACM certificate for the domain
  2. Creates DNS validation records
  3. Validates the certificate
  4. Creates an A record (alias) pointing to the ALB
brms = {
  domain          = "rules.example.com"
  route53_zone_id = "Z0123456789ABCDEF"
  # certificate_arn is auto-created
}

Option 2: Existing Certificate ARN

Bring your own validated ACM certificate:

brms = {
  domain          = "rules.example.com"
  certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/abc-123"
  # No Route53 management, you handle DNS
}

Resources Created (Route53 mode)

For BRMS (when route53_zone_id is provided and alb_http_only = false)

These resources are created only when route53_zone_id is set and alb_http_only is false (the default). When alb_http_only = true, BRMS runs behind a TLS-terminating edge such as CloudFront and the module creates none of the resources below; you manage the certificate and DNS at the edge instead.

Resource Purpose
aws_acm_certificate.brms Certificate for BRMS domain
aws_route53_record.brms_validation DNS records for certificate validation
aws_acm_certificate_validation.brms Waits for certificate to be valid
aws_route53_record.brms_alias A record (alias) to BRMS ALB

Gating local: create_brms_certificate = local.create_brms && var.brms.route53_zone_id != null && !var.brms.alb_http_only (modules/ecs/certificates.tf:2).

For Agent (conditional)

Same pattern, but only created if all of these hold:

  • Agent is enabled
  • Agent has a domain configured
  • Agent has a route53_zone_id
  • Agent is not alb_http_only (when alb_http_only = true, the ALB serves HTTP behind a TLS-terminating edge such as CloudFront, so no certificate or DNS records are created even if domain and route53_zone_id are set)

Agent HTTPS is optional, HTTP-only works fine for the Agent.

ALB Listener Configuration

BRMS

BRMS always requires HTTPS at the browser (secure-context browser APIs). How TLS is served depends on alb_http_only.

Default (alb_http_only = false): ALB terminates TLS

Listener Port Action
HTTP 80 Redirect to HTTPS (301)
HTTPS 443 Forward to target group

SSL Policy: ELBSecurityPolicy-TLS13-1-2-2021-06 (negotiates TLS 1.3 and TLS 1.2; minimum TLS 1.2)

alb_http_only = true: edge (e.g. CloudFront) terminates TLS, ALB serves HTTP

Listener Port Action
HTTP 80 Forward to target group
HTTPS 443 Not created

In this mode no ACM certificate or 443 listener is created (brms_use_tls is false). It requires alb_internal = true and a trusted TLS-terminating edge in front of the ALB, which still presents HTTPS to the browser.

Agent (HTTPS optional)

Scenario Port 80 Port 443
With certificate Redirect to HTTPS Forward to target group
Without certificate Forward to target group Not created

Certificate Resolution Logic

local.brms_certificate_arn = var.brms != null ? (
  var.brms.certificate_arn != null
    ? var.brms.certificate_arn                              # 1. user-provided ARN wins
    : local.create_brms_certificate
      ? aws_acm_certificate.brms[0].arn                     # 2. else use the auto-created cert
      : null                                                # 3. else none (e.g. alb_http_only mode)
) : null

where:

local.create_brms_certificate = local.create_brms
  && var.brms.route53_zone_id != null
  && !var.brms.alb_http_only

Priority: user-provided ARN > auto-created certificate > none.

The auto-created certificate is only referenced when create_brms_certificate is true (BRMS enabled, a route53_zone_id is set, alb_http_only is false). In alb_http_only mode, or when neither a route53_zone_id nor a certificate_arn is supplied, the aws_acm_certificate.brms resource is not created (count = 0) and the resolved ARN is the user-provided value or null. The expression is wrapped in a var.brms != null guard so it short-circuits to null when BRMS is disabled.

DNS Record Details

Alias Record

resource "aws_route53_record" "brms_alias" {
  count = local.create_brms_certificate ? 1 : 0

  zone_id = var.brms.route53_zone_id
  name    = var.brms.domain
  type    = "A"

  alias {
    name                   = aws_lb.brms[0].dns_name
    zone_id                = aws_lb.brms[0].zone_id
    evaluate_target_health = true
  }
}

The record is gated on local.create_brms_certificate (create_brms && route53_zone_id != null && !alb_http_only), so it is not created when alb_http_only is set. The evaluate_target_health = true means Route53 health checks monitor the ALB.

Clone this wiki locally