# Trace of `terraform/loadbalancing.tf` — 1 blocks

> PROPOSAL — generated by StackToIT Assess. Architect review required before any decision.

Run `f6267c3f-2848-4aa5-89df-5fee8b15b3b9` · source digest `sha256:812c5ae3f6cc8530163abbf5b6fbe305ed3b363c4886ec6b87623db857ea0c70`

The draft keeps a one-paragraph comment above each block: where it comes from, why its values are what they are, what is not carried and which decision is open. Each section of this file is the whole comment the generators wrote for one block, unabridged and in the order they wrote it: the rule and the knowledge-base stamp, the references with their digests, the evidence of each chosen value, the reason of each attribute that is not written and the caveats of the checks. The `# trace:` line above a block names its section by the anchor, which is the trace id.

<a id="TR-c243e261bc0d"></a>

## Trace TR-c243e261bc0d — stackit_application_load_balancer.retail_app_ecs_alb_this

| | |
|---|---|
| Block | `stackit_application_load_balancer.retail_app_ecs_alb_this` in `terraform/loadbalancing.tf` |
| Source units | `module.retail_app_ecs.module.alb.aws_lb.this` |
| Comment | 20 lines as the generators wrote it, 18 lines kept above the block in the .tf (the last is the `# trace:` line) |

### Where each setting comes from

| Setting of the block | Origin in the source |
|---|---|
| `listeners[listener-1].http.hosts[*].rules[*].target_pool (default route)` | from module.retail_app_ecs.module.alb.aws_lb_listener.frontend_http_tcp.default_action |
| `listeners[listener-1].port` | from module.retail_app_ecs.module.alb.aws_lb_listener.frontend_http_tcp.port |
| `listeners[listener-1].protocol` | from module.retail_app_ecs.module.alb.aws_lb_listener.frontend_http_tcp.protocol |
| `name` | from module.retail_app_ecs.module.alb.aws_lb.this.name |
| `networks[0].network_id` | SOURCE_UNPROVEN: the load balancer spans several subnets of the source, or a repeated one, and the network the draft places it in is a variable or a choice of the placement, not a setting of the source |
| `options.ephemeral_address` | from module.retail_app_ecs.module.alb.aws_lb.this.internal |
| `plan_id` | SOURCE_UNPROVEN: a STACKIT Application Load Balancer plan has no setting in the source: it is chosen from the catalogue of the target |
| `target_pools[retail-app-ecs-alb-main].active_health_check.healthy_threshold` | from module.retail_app_ecs.module.alb.aws_lb_target_group.main.health_check.healthy_threshold |
| `target_pools[retail-app-ecs-alb-main].active_health_check.http_health_checks.ok_status` | SOURCE_UNPROVEN: the source matcher is absent or is no list of HTTP status codes: a variable |
| `target_pools[retail-app-ecs-alb-main].active_health_check.http_health_checks.path` | from module.retail_app_ecs.module.alb.aws_lb_target_group.main.health_check.path |
| `target_pools[retail-app-ecs-alb-main].active_health_check.interval` | from module.retail_app_ecs.module.alb.aws_lb_target_group.main.health_check.interval |
| `target_pools[retail-app-ecs-alb-main].active_health_check.interval_jitter` | SOURCE_UNPROVEN: the source load balancer has no such setting: a variable without a default |
| `target_pools[retail-app-ecs-alb-main].active_health_check.timeout` | from module.retail_app_ecs.module.alb.aws_lb_target_group.main.health_check.timeout |
| `target_pools[retail-app-ecs-alb-main].active_health_check.unhealthy_threshold` | from module.retail_app_ecs.module.alb.aws_lb_target_group.main.health_check.unhealthy_threshold |
| `target_pools[retail-app-ecs-alb-main].target_port` | SOURCE_UNPROVEN: the node port 30000 of the NodePort Service ui-nodeport the draft writes for the workload of module.retail_app_ecs.module.ui_service.aws_ecs_service.this (the source forwarded to container port 8080): the exposure path is a decision (aws.ingress.exposure-path) |
| `target_pools[retail-app-ecs-alb-main].targets` | SOURCE_UNPROVEN: the targets are the nodes of the SKE cluster that runs the workload ui of module.retail_app_ecs.module.ui_service.aws_ecs_service.this, reached on the node port 30000 of the NodePort Service ui-nodeport; STACKIT exports no node address to Terraform: the target IPs are a variable |

A setting in the state SOURCE_UNPROVEN is that setting's own: the draft writes it, and says here that the source does not prove where it comes from. It holds nothing else of the migration back.

## Comment

````text
from module.retail_app_ecs.module.alb.aws_lb.this (.terraform/modules/retail_app_ecs.alb/main.tf:5) — RECONFIGURE / MEDIUM
rule aws.lb/alb · KB 0.384.0 · target maturity GA · lifecycle active · mapping maturity beta · evidence internal · review required
Internet-facing: an ephemeral public address is requested; use external_address with a stackit_public_ip for a fixed one.
TODO: the source load balancer names every instance of the repeated subnet module.vpc.module.vpc.aws_subnet.public, each a network of its own on STACKIT; the draft places the load balancer in one network (its layout choice; other layouts are a redesign): which instance is the placement is a decision; network_id is selected by the required variable var.retail_app_ecs_alb_this_network_id_target — set it to the index of the instance that is the network of the load balancer's listeners and targets.
TODO: EXPOSURE PATH: pool retail-app-ecs-alb-main forwards to the ECS service module.retail_app_ecs.module.ui_service.aws_ecs_service.this, drafted as the workload ui on SKE (kubernetes/ui/manifests.yaml): the pool reaches it through the NodePort Service ui-nodeport of the manifest (node port 30000 → container port 8080, the port the target group module.retail_app_ecs.module.alb.aws_lb_target_group.main forwarded to), so its target_port is 30000 and its targets are the private IPs of the nodes of the cluster (var.retail_app_ecs_alb_this_target_ips: STACKIT exports no node address to Terraform, and the IPs change as the node pool scales and is updated). The health check of the pool reaches the pods through the same node port. Which exposure path the workload takes is the open decision DEC-GEN-CONVERT-INGRESS-EXPOSURE-PATH (alias `convert:module.retail_app_ecs.module.alb.aws_lb.this:target_pools:INGRESS_EXPOSURE_PATH`) (aws.ingress.exposure-path): nodeport-alb-target-pool (this draft), ingress-controller-behind-alb or stackit-alb-ingress-controller.
NOT CARRIED (module.retail_app_ecs.module.alb.aws_lb_target_group.main): deregistration_delay = 30 — a STACKIT target pool has name, target_port, targets, active_health_check and tls_config only (pinned provider): no connection draining delay, slow start or load-balancing algorithm — not generated; check that the targets tolerate the STACKIT behaviour.
WebSocket: an AWS Application Load Balancer proxies WebSocket upgrades (ws, wss) on every listener and rule without a setting; a STACKIT Application Load Balancer enables them per rule (rules[].web_socket, pinned provider; docs.stackit.cloud, Application Load Balancer, create: "Enable only if your app needs WebSocket") and the draft leaves it off, because the source does not say which targets serve WebSocket — set web_socket = true on the rules whose targets do.
CLIENT ACCESS: public on source, public on target — the rules of module.retail_app_ecs.module.alb.aws_security_group.this, module.retail_app_ecs.module.alb_sg.aws_security_group.this_name_prefix admit every IPv4 address on the listener port(s) 80, and the load balancer drafted here is public and admits every client: no options.access_control.allowed_source_ranges (pinned provider schema, resource stackit_application_load_balancer: "Application Load Balancer is accessible only from an IP address in this range.", one set for the whole load balancer) is written, it would restrict nothing.
CLIENT ACCESS (assumed): the network ACLs of the subnets of module.retail_app_ecs.module.alb.aws_lb.this is not managed by this source and is taken as unrestricted — not verified; the client access stated for stackit_application_load_balancer.retail_app_ecs_alb_this is an assumption about it and not a proof.
NOT CARRIED (module.retail_app_ecs.module.alb.aws_lb.this): security_groups — a STACKIT Application Load Balancer is in no security group, so the attachment of module.retail_app_ecs.module.alb.aws_security_group.this, module.retail_app_ecs.module.alb_sg.aws_security_group.this_name_prefix is not carried (STACKIT assigns its own target security group (loadbalancer/<name>/backend, which admits the load balancer on the pool ports) to the pool servers unless disable_target_security_group_assignment is set); the client restriction of the group rules is public on source, public on target: no access control is written — the load balancer limits clients by options.access_control.allowed_source_ranges (pinned provider schema, resource stackit_application_load_balancer: "Application Load Balancer is accessible only from an IP address in this range.", one set for the whole load balancer) only.
WARNING source-provider-unpinned: No lock file entry pins aws (>= 3.0, >= 3.29, >= 4.18, >= 4.30, >= 4.59, >= 5.64, >= 5.79, ~> 5.0): the version the plan would use is not proven (stated once for the whole estate)
LEDGER network exposure: internet-facing → public address (ASSUMPTION: the unmanaged default network ACL of the subnets of module.retail_app_ecs.module.alb.aws_lb.this is taken as unrestricted, not verified) (SECURITY_OBSERVATION Plaintext public listener of module.retail_app_ecs.module.alb.aws_lb.this, port 80) — REVIEW
NOT CARRIED (module.retail_app_ecs.module.alb.aws_lb.this): enable_http2 = true, desync_mitigation_mode = defensive, xff_header_processing_mode = append, enable_xff_client_port = true — no attribute for it on the STACKIT load balancers (pinned provider).
NOT CARRIED (module.retail_app_ecs.module.alb.aws_lb.this): idle_timeout = 60 — the STACKIT Application Load Balancer has no idle timeout; Network Load Balancer listeners take tcp.idle_timeout — not generated (pinned provider).
SECURITY_OBSERVATION Plaintext public listener of module.retail_app_ecs.module.alb.aws_lb.this, port 80 (non-blocking): The source load balancer module.retail_app_ecs.module.alb.aws_lb.this is internet-facing and every listener it states is HTTP (port 80 forwards to its targets, no listener is HTTPS or TLS): clients reach the application without transport encryption. Source: .terraform/modules/retail_app_ecs.alb/main.tf:5. In the draft (PRESERVED): the drafted listener of stackit_application_load_balancer.retail_app_ecs_alb_this is plain HTTP on port 80, as the source states it; the public address is kept and no HTTPS listener or certificate is added. Hardening, if wanted (a note, not a change; owner Security Architect): serve the application over HTTPS (an HTTPS listener with a certificate, certificate_config in the pinned provider schema) and redirect or close port 80.
TODO: module.retail_app_ecs.module.alb.aws_lb.this: which instance of stackit_network.vpc_vpc_public the networks of this block means is not visible in the source (it is repeated); set var.retail_app_ecs_alb_this_network_id_target to its index — no instance is assumed (open decision DEC-GEN-CONVERT-AMBIGUOUS-INSTANCE-SELECTION (alias `convert:module.retail_app_ecs.module.alb.aws_lb.this:network_id:AMBIGUOUS_INSTANCE_SELECTION`)).
````
