Skip to content

Create a load balancer with SSL offload

A standard HTTPS listener on a Breqwatr Cloud load balancer is TLS passthrough — encrypted bytes are forwarded to the backend, which has to terminate TLS itself. SSL offload moves TLS termination to the load balancer instead: the LB holds the certificate, decrypts the traffic, and forwards plain HTTP to the backends.

This is set up via the OpenStack CLI. The Portal does not surface a TLS-termination option on its listener form today — the HTTPS protocol there is passthrough only.

Prerequisites

  • An application credential for the project that owns the load balancer.
  • The OpenStack CLI installed, pointed at a clouds.yaml for the project.
  • Backend instances reachable on HTTP (the listener will decrypt TLS and forward plain HTTP).
  • A TLS certificate + private key for the hostname clients will use. For testing you can self-sign.
  • Barbican (the OpenStack secret store) enabled in your Breqwatr Cloud deployment. Octavia reads the certificate from Barbican by reference at TLS-termination time. If openstack secret list returns an Unauthorized or not found error, contact support to confirm Barbican is available before going further.

Steps

1. Prepare the certificate and key

For a real deployment, use your own. For testing:

mkdir cert && cd cert
openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes \
  -out certificate.crt -keyout private.key

Bundle them into a PKCS12 archive — Barbican stores the cert and key together as a single secret:

openssl pkcs12 -export -in certificate.crt -inkey private.key -out cert.p12

(Set or skip an export password as your tooling requires.)

2. Store the certificate in Barbican

openstack --os-cloud breqwatr secret store \
  --name tls-prod-2026-04-19 \
  -t 'application/octet-stream' \
  -e base64 \
  --payload="$(base64 < cert.p12)"

The command returns a Secret href. Capture the secret ID for the next steps:

secret_id=$(openstack --os-cloud breqwatr secret list \
  -f value -c "Secret href" --name tls-prod-2026-04-19 \
  | sed 's|.*/||')

Grant the Octavia service user read access on the secret so it can fetch the cert at TLS-termination time:

octavia_user_id=$(openstack --os-cloud breqwatr user show octavia -c id -f value)
openstack --os-cloud breqwatr acl user add -u $octavia_user_id $secret_id

3. Create the load balancer

openstack --os-cloud breqwatr loadbalancer create \
  --name web-tls \
  --vip-subnet-id <subnet-name-or-id>

Wait for openstack loadbalancer list to show ACTIVE provisioning status before moving on.

4. Create the TERMINATED_HTTPS listener

openstack --os-cloud breqwatr loadbalancer listener create \
  --name web-tls-listener \
  --protocol-port 443 \
  --protocol TERMINATED_HTTPS \
  --default-tls-container=$secret_id \
  web-tls

TERMINATED_HTTPS is the protocol that decrypts at the LB. --default-tls-container points at the Barbican secret containing the PKCS12.

5. Create the backend pool

The pool uses HTTP (not HTTPS) because TLS terminates at the LB and the backends only see plain HTTP:

openstack --os-cloud breqwatr loadbalancer pool create \
  --name web-tls-pool \
  --lb-algorithm ROUND_ROBIN \
  --listener web-tls-listener \
  --protocol HTTP

6. Add backend members

openstack --os-cloud breqwatr loadbalancer member create \
  --subnet-id <subnet-id> \
  --address 10.0.1.21 \
  --protocol-port 80 \
  web-tls-pool

openstack --os-cloud breqwatr loadbalancer member create \
  --subnet-id <subnet-id> \
  --address 10.0.1.22 \
  --protocol-port 80 \
  web-tls-pool

Verification

List members and confirm they reach ACTIVE:

openstack --os-cloud breqwatr loadbalancer member list web-tls-pool

Curl the VIP over HTTPS:

curl -k https://<vip-address>

(Use -k for the self-signed certificate; drop it for a real cert.)

Hitting the VIP repeatedly should round-robin across the backend members — backend access logs are the easiest way to see the distribution.

Rotate the certificate

When you replace the cert (renewal, new hostname, key compromise):

  1. Store the new PKCS12 as a new Barbican secret (don't overwrite the old one).
  2. Update the listener to point at the new secret:

    openstack --os-cloud breqwatr loadbalancer listener set \
      --default-tls-container=$new_secret_id web-tls-listener
    
  3. Once the rotation is confirmed working, delete the old secret:

    openstack --os-cloud breqwatr secret delete $old_secret_id
    

Next steps

  • Create a load balancer — the Portal-driven flow for HTTP, HTTPS-passthrough, TCP, UDP, and SCTP listeners.
  • Floating IPs — associate one to the LB's VIP if clients need to reach it from outside the cloud.
  • Use the OpenStack CLIclouds.yaml setup and authentication recap.