Elastic Load Balancing v2
ELBv2 control plane — Application/Network/Gateway Load Balancer: load balancers, target groups + targets, listeners + rules + certificates, mTLS trust stores, attributes, capacity reservations, resource policies.
fakecloud implements ELBv2 with full control-plane coverage across all three load balancer types: Application (ALB), Network (NLB), and Gateway (GWLB). 51 operations.
Status: full API. Covers load balancer CRUD, target groups + targets + health, listeners + rules + certificates, listener/load-balancer/target-group attributes, capacity reservations, mTLS trust stores + revocations, resource policies, IP pools, IP address types, subnets, security groups, SSL policies, and tags.
Supported today (full API)
- Load balancers —
CreateLoadBalancer,DescribeLoadBalancers,DeleteLoadBalancer,SetSubnets,SetSecurityGroups,SetIpAddressType,ModifyIpPools - Load balancer attributes —
ModifyLoadBalancerAttributes,DescribeLoadBalancerAttributes - Capacity reservations —
ModifyCapacityReservation,DescribeCapacityReservation - Target groups —
CreateTargetGroup,DescribeTargetGroups,ModifyTargetGroup,DeleteTargetGroupwith cross-resource reference checks (rejects delete while a listener or rule still references the target group, includingForwardConfig.TargetGroups) - Targets —
RegisterTargets,DeregisterTargets,DescribeTargetHealth - Target group attributes —
ModifyTargetGroupAttributes,DescribeTargetGroupAttributes - Listeners —
CreateListener,DescribeListeners,ModifyListener,DeleteListener(cascades to rules),DescribeListenerAttributes,ModifyListenerAttributes - Listener certificates —
AddListenerCertificates,RemoveListenerCertificates,DescribeListenerCertificates - Listener rules —
CreateRule,DescribeRules,ModifyRule,DeleteRule,SetRulePrioritieswith positive-integer priority validation and target-group existence checks onActions - mTLS trust stores —
CreateTrustStore,DescribeTrustStores,ModifyTrustStore,DeleteTrustStore,DescribeTrustStoreAssociations,DeleteSharedTrustStoreAssociation,GetTrustStoreCaCertificatesBundle - Trust store revocations —
AddTrustStoreRevocations,RemoveTrustStoreRevocations,DescribeTrustStoreRevocations,GetTrustStoreRevocationContent - Resource policies —
GetResourcePolicy - Tags —
AddTags,RemoveTags,DescribeTagsacross load balancers, target groups, listeners, rules, and trust stores - Limits / SSL policies —
DescribeAccountLimitsreturns AWS-published default limits;DescribeSSLPoliciesreturns predefined ALB security policies with exact protocol + cipher lists
Validation matches AWS
- Load balancer name is 1-32 chars, alphanumeric or hyphens, no leading hyphen, no
internal-prefix oninternet-facingschemes — returnsValidationErrorwith the same wire shape. IpAddressTypeis restricted toipv4,dualstack,dualstack-without-public-ipv4— same enum check onCreateLoadBalancer,SetIpAddressType, andSetSubnets.- Target group name validation, target type enum (
instance,ip,lambda,alb), health check threshold ranges all match AWS. DeleteTargetGroupreturnsResourceInUsewhen any listener default action or rule action — including those wrapped inForwardConfig.TargetGroups— still references the target group.CreateRule/ModifyRulereject priority values <= 0 withValidationError, and rule actions referencing a non-existent target group returnTargetGroupNotFound.CreateListener/ModifyListenerreject Protocol/Port mismatches per LB type withValidationError. ALB (application) accepts onlyHTTP,HTTPSon ports 1-65535. NLB (network) accepts onlyTCP,UDP,TCP_UDP,TLSon ports 1-65535. GWLB (gateway) accepts onlyGENEVEand pins the port to6081.ModifyLoadBalancerAttributesvalidatesipv6.enable_prefix_for_source_natagainst the AWS-supported settrue,false,on,offand rejects anything else withValidationError. The value round-trips verbatim throughDescribeLoadBalancerAttributes.wafv2:AssociateWebACL/DisassociateWebACL/GetWebACLForResourceaccept either a load balancer ARN or a listener ARN asResourceArnfor ELBv2 targets — the listener ARN is normalized to its parent load-balancer ARN server-side so the data plane lookup matches.
Idempotent creates
CreateLoadBalancer and CreateTargetGroup are idempotent on name within a single account: a second call with the same name returns the existing resource instead of throwing, matching AWS's documented idempotency behaviour.
Smoke test
fakecloud &
# Create an ALB
LB=$(aws --endpoint-url http://localhost:4566 elbv2 create-load-balancer \
--name web-alb --type application \
--subnets subnet-aaa subnet-bbb \
--query 'LoadBalancers[0].LoadBalancerArn' --output text)
# Create a target group
TG=$(aws --endpoint-url http://localhost:4566 elbv2 create-target-group \
--name web-tg --protocol HTTP --port 80 --vpc-id vpc-12345 \
--target-type instance \
--query 'TargetGroups[0].TargetGroupArn' --output text)
# Wire the listener -> target group
aws --endpoint-url http://localhost:4566 elbv2 create-listener \
--load-balancer-arn "$LB" --protocol HTTP --port 80 \
--default-actions Type=forward,TargetGroupArn=$TG
# Register a target
aws --endpoint-url http://localhost:4566 elbv2 register-targets \
--target-group-arn "$TG" --targets Id=i-deadbeef,Port=80
# Health is `healthy` by default — fakecloud doesn't probe the target.
aws --endpoint-url http://localhost:4566 elbv2 describe-target-health \
--target-group-arn "$TG"Introspection
The /_fakecloud/elbv2/* endpoints let your tests assert directly on the persisted control-plane state without parsing XML responses:
GET /_fakecloud/elbv2/load-balancers— every ALB/NLB/GWLB across every accountGET /_fakecloud/elbv2/target-groups— every target group, including registered targets and current healthGET /_fakecloud/elbv2/listeners— every listener, with port/protocol/SSL policy/default actionGET /_fakecloud/elbv2/rules— every rule, including the default rules AWS auto-creates per listener
Wrapped by the first-party SDKs: fc.elbv2().getLoadBalancers() (TS/Java), fc.elbv2.getLoadBalancers() (Python), fc.ELBv2().GetLoadBalancers(ctx) (Go), $fc->elbv2()->getLoadBalancers() (PHP).
Health probes
A background prober walks every target group with HealthCheckEnabled=true and probes each registered target on its HealthCheckProtocol/HealthCheckPort/HealthCheckPath at the configured HealthCheckIntervalSeconds. HTTP/HTTPS probes match the configured Matcher.HttpCode (e.g. 200, 200-299, 200,301,404); TCP/TLS probes succeed on connect. After HealthyThresholdCount consecutive successes a target flips to healthy; after UnhealthyThresholdCount consecutive failures it flips to unhealthy. Newly registered targets start at initial until the first probe completes. DescribeTargetHealth returns the live state.
Set FAKECLOUD_ELBV2_DISABLE_HEALTH_PROBES=true to turn the prober off and revert to the historical default of synthetic healthy for every registered target — useful when targets are placeholder IPs that don't actually answer.
Data plane (in-process HTTP routing)
For every ALB whose state_code == "active", fakecloud binds a TCP listener on 127.0.0.1:0 (OS-allocated) and serves HTTP/1.1 requests through the listener-rule chain you configured. Connections are parsed, routed against your rules in priority order (first non-default match wins; otherwise the listener default actions), and dispatched to the action:
forward— picks a target group via the action's weighted distribution and a target within it via round-robin (skippingunhealthy/unusedtargets), then proxies the request viareqwest. The request carriesX-Forwarded-For,X-Forwarded-Proto,X-Forwarded-Port, andX-Amzn-Trace-Idheaders. The upstream's status, body, and non-hop-by-hop headers are returned to the client.fixed-response— returns the configured status code, message body, and content type immediately.redirect— emits a 301 (HTTP_301) or 302 (HTTP_302) with aLocationheader built fromprotocol/host/port/path/query, falling back to the request's own host/path when a field is omitted.authenticate-oidc/authenticate-cognito— return501 Not Implementedwith a body identifying the action; treated as next-batch work.
Sticky sessions: when ForwardConfig.Stickiness.Enabled=true, the data plane sets an AWSALB cookie on the response (with Max-Age from DurationSeconds) and pins follow-up requests carrying that cookie to the same target as long as it stays healthy. Rule conditions support host-header, path-pattern (both with */? glob wildcards; host-header is case-insensitive), http-request-method, http-header, query-string, and source-ip (IPv4 + IPv6 CIDR). Find the bound port via the boundPort field on GET /_fakecloud/elbv2/load-balancers.
Set FAKECLOUD_ELBV2_DISABLE_DATAPLANE=true to turn off the data plane (the control plane keeps working; useful when you only need to assert API calls).
Access logs and connection logs
When an ALB has access_logs.s3.enabled=true (and/or connection_logs.s3.enabled=true) plus the corresponding bucket attribute set (access_logs.s3.bucket for access logs, connection_logs.s3.bucket for connection logs), the data plane records one log line per served request and one per established connection. Lines are buffered in memory and flushed to S3 either on a 60-second timer or when the buffer hits 1000 records, whichever comes first. The body is gzip-compressed; the object key follows the AWS pattern:
<prefix>/AWSLogs/<account>/elasticloadbalancing/<region>/YYYY/MM/DD/<account>_elasticloadbalancing_<region>_<lb-id>_<timestamp>_<ip>_<random>.log.gzThe line format approximates the AWS ALB access-log spec: space-delimited fields covering timestamp, ELB name, client ip:port, target ip:port, processing times, status codes, byte counts, the quoted request line, user-agent, SSL cipher/protocol, target group ARN, trace id, host, chosen cert, matched rule priority, request creation time, actions executed, redirect URL, error reason, target port list, target status code list, classification, and classification reason.
Tests that need deterministic flush timing can POST /_fakecloud/elbv2/access-logs/flush to drain every buffered LB synchronously instead of waiting for the periodic flusher.
Next-batch work items
- HTTPS/TLS termination. Listeners with
Protocol=HTTPSare stored exactly; the in-process bind is HTTP-only for now. ACM cert lookup +rustlstermination + mTLS trust-store wiring lands in a follow-up. - Raw NLB TCP forwarding. NLB control-plane CRUD is complete; the data-plane TCP byte-copy lands with the TLS work.
authenticate-oidc/authenticate-cognitoactions. Currently respond501; bringing OIDC + Cognito flows online ships separately.
Limitations
- NLB and GWLB data planes are not implemented. Only the ALB data plane (HTTP request matching, forwarding, fixed-response, redirect, sticky sessions, access logs) is functional.
- HTTPS/TLS termination is not yet implemented. Listeners with
Protocol=HTTPSare stored but the in-process bind is HTTP-only.