Skip to content

Add private internal ALB example with end-to-end TLS - #17

Open
FloMicSch wants to merge 1 commit into
stackitcloud:mainfrom
FloMicSch:feature/alb-private-internal-endpoint
Open

Add private internal ALB example with end-to-end TLS#17
FloMicSch wants to merge 1 commit into
stackitcloud:mainfrom
FloMicSch:feature/alb-private-internal-endpoint

Conversation

@FloMicSch

Copy link
Copy Markdown

Description

Adds examples/alb-private-internal-endpoint: an internal-only Application Load Balancer. The load balancer has no public address (options.private_network_only = true) and lives in a listener network; the backends run in a separate target network that is reached through the project router. The exported target_security_group is assigned to the backend interfaces by the configuration (disable_target_security_group_assignment = true). TLS is terminated at the load balancer with a certificate from a private CA and re-established towards the backends, verified against the same CA (tls_config with custom_ca and skip_certificate_validation = false). A second target pool whose backends present a self-signed certificate shows that the validation is enforced. A jump host in the listener network is the only resource with a public address; it exists to run the checks without a VPN.

The existing ALB examples publish services on the internet; this example covers the private side:

  • options.private_network_only with private_address as the only entry point, and the production access paths (VPN gateway, hub-and-spoke routing) the README points to
  • disable_target_security_group_assignment with the exported target_security_group and load_balancer_security_group
  • TLS bridging with custom_ca; the HTTP health check runs over the pool's tls_config and rejects the untrusted certificate (503 no healthy upstream)
  • Private CA, listener and backend certificates issued by the tls provider at apply time; the listener certificate is uploaded as stackit_alb_certificate
  • The backend application lives in files/server.py and is injected into cloud-init via templatefile

Tested

Deployed end to end in a sandbox project (eu01, provider 0.113.0); the README's Testing section lists the commands and the observed results:

  • externalAddress is null and privateAddress set at STATUS_READY; TLS 1.3 from the jump host with Verify return code: 0 against the private CA, 404 for unknown hosts, no listener on port 80
  • Every response reports TLS 1.2 between load balancer and backend and the SHA-256 fingerprint of the certificate Terraform issued for that backend
  • The pool with the untrusted certificate never becomes healthy (503), the pool with the CA-issued certificate passes the identical check
  • The backend interfaces carry the example's group and the exported target_security_group only; the load balancer added nothing to them
  • terraform fmt, terraform validate, pre-commit hooks (prettier, black, gitleaks, addlicense, README tags, file naming) pass; AGENTS.md regenerated

Notes

  • A second networks entry with ROLE_LISTENERS and ROLE_TARGETS is accepted by the API and reaches STATUS_READY, but the listener never answers on the private address (provider 0.113.0, September 2026); the API reference states that only ROLE_LISTENERS_AND_TARGETS is supported at this time. The example declares the listener network only and documents the finding.
  • private_network_only, disable_target_security_group_assignment, networks and external_address cannot be changed after creation; the README describes how to detach the target security group from the backend interfaces before replacing the load balancer.
  • stackit beta alb plans lists only p10 in eu01 at the time of writing; the plan is a variable with that default.
  • In a project that belongs to a STACKIT Network Area, both network CIDRs have to lie inside the ranges of the area; the README says so.

Checklist

  • The CI pipeline passed successfully.

An Application Load Balancer without a public address: private listener
in one network, backends in another, the exported target security group
assigned to the backend interfaces by the configuration, and TLS
bridging with a private CA created at apply time, so that the hop from
the load balancer to the backends is encrypted and verified as well. A
second target pool with an untrusted certificate shows that the
validation is enforced, and a jump host in the listener network runs the
checks. The listener/target network roles of the API were tried and did
not work; the README records the finding and the single-network layout
used instead.
@h3adex

h3adex commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants