Skip to content

feat: Add ALB+S3 VPC hosting mode as alternative to CloudFront for private network deployments#245

Merged
rstrahan merged 4 commits intoaws-solutions-library-samples:developfrom
rcgeorge:feature/ALBHosting
Mar 19, 2026
Merged

feat: Add ALB+S3 VPC hosting mode as alternative to CloudFront for private network deployments#245
rstrahan merged 4 commits intoaws-solutions-library-samples:developfrom
rcgeorge:feature/ALBHosting

Conversation

@rcgeorge
Copy link
Copy Markdown
Contributor

Adds an alternative web UI hosting mode using Application Load Balancer (ALB) with S3 VPC Interface Endpoint for environments that require VPC-based hosting (private networks, regulated environments, corporate networks without internet-facing CDN access).

Changes

ALB Hosting Infrastructure (nested/alb-hosting/template.yaml)

  • New nested CloudFormation stack with ALB, S3 Interface VPC Endpoint, security groups, and target registration
  • ALB listener rules with host-header rewrite and URL rewrite transforms for serving S3 static content
  • Custom resource Lambdas for VPC CIDR lookup and VPC endpoint ENI target registration
  • TLS 1.3 enforcement, access logging, and scoped VPC endpoint policy

Main Template (template.yaml)

  • WebUIHosting parameter (CloudFront | ALB) with conditional resource creation
  • UseCloudFrontHosting / UseALBHosting conditions gating CloudFront and ALB resources
  • All S3 CORS origins, Cognito callback/logout URLs, CodeBuild env vars, and stack outputs resolve conditionally based on hosting mode
  • S3 bucket policy uses aws:sourceVpce condition for ALB mode instead of CloudFront OAI
  • Renamed nested stack logical ID to ALBHOSTINGSTACK to match existing convention (PATTERNSTACK, APPSYNCSTACK, etc.)

CLI Fix (lib/idp_cli_pkg/idp_cli/cli.py)

  • Fixed --parameters parsing to handle comma-delimited values (e.g., ALBSubnetIds=subnet-a,subnet-b) — previously the naive split(",") broke values containing commas

Helper Script (scripts/generate_self_signed_cert.sh)

  • New script to generate and import self-signed TLS certificates to ACM for demo/testing with ALB hosting

Publish Script (publish.py)

  • Added nested/alb-hosting as a build component

Documentation

  • New docs/alb-hosting.md — when/why to use ALB hosting, VPC prerequisites, deployment steps, security considerations, troubleshooting, CloudFront vs ALB comparison
  • Updated docs/architecture.md, docs/aws-services-and-roles.md, docs/configuration.md, docs/web-ui.md, docs/well-architected.md with ALB hosting references alongside existing CloudFront content
  • Updated docs/README.md with link to new doc

Testing

  • Deployed fresh stack with WebUIHosting=ALB using idp-cli deploy --from-code against customer-vpc (private subnets, self-signed cert, internal ALB scheme)
  • Stack created successfully (CREATE_COMPLETE) with ALB serving the web UI
  • Verified ALB returns 200 with full HTML content from within the VPC
  • All lint checks pass (make check-arn-partitions, make ruff-lint, make format, make validate-buildspec)
  • All CLI tests pass (108/108)

- Add WebUIHosting parameter (CloudFront/ALB) to main template
- Add ALB hosting nested stack (VPC endpoint, security groups, target registration, listener rules)
- Add ELB access log permissions to logging bucket policy
- Make CloudFront resources conditional on UseCloudFrontHosting
- Make S3 website configuration conditional (disabled for ALB mode)
- Scope VPC endpoint policy to WebUI bucket only
- Update CORS origins, Cognito callbacks, CodeBuild env vars for ALB mode
- Add self-signed cert generation script for testing
- Register alb-hosting as build component in publish.py
@rstrahan
Copy link
Copy Markdown
Contributor

My buddy, Cline, found a few small issues @rcgeorge ..

Can you address them?

Issues Found 🔍

🔴 Issue 1: ALB Security Group only allows FIRST CIDR when multiple are provided (Medium-High Severity)

SecurityGroupIngress:
  - IpProtocol: tcp
    FromPort: 443
    ToPort: 443
    CidrIp: !If
      - UseVpcCidr
      - !GetAtt VpcCidrLookup.CidrBlock
      - !Select [0, !Split [",", !Ref ALBAllowedCIDRs]]

When a user provides ALBAllowedCIDRs=10.0.0.0/8,172.16.0.0/12, only 10.0.0.0/8 is used. The second CIDR is silently ignored. This is inconsistent with the parameter description ("Comma-separated CIDR ranges") and the documentation.

Recommendation: Either:

  • Document that only a single CIDR is supported (quick fix), or
  • Use a custom resource Lambda to create multiple SG ingress rules dynamically, or
  • Change ALBAllowedCIDRs to CommaDelimitedList type and loop with AWS::EC2::SecurityGroupIngress resources

🟡 Issue 2: S3 VPC Endpoint Policy uses s3:* (Low-Medium)

Action:
  - "s3:*"
Resource:
  - !Sub "arn:${AWS::Partition}:s3:::${WebUIBucketName}"
  - !Sub "arn:${AWS::Partition}:s3:::${WebUIBucketName}/*"

While the resource is scoped to the WebUI bucket, s3:* is overly permissive for an endpoint that only needs to serve static files. Should be s3:GetObject (and perhaps s3:ListBucket for health checks).

Recommendation: Restrict to ["s3:GetObject"] on ${WebUIBucketName}/*.

🟡 Issue 3: VPC endpoint ENI targets may go stale on stack updates

The RegisterTargetsCustomResource registers VPC endpoint ENI IPs at stack creation time. If the VPC endpoint is later replaced (e.g., subnets changed), the targets won't be re-registered because the custom resource Lambda only fires on create/delete. The doc mentions this in troubleshooting, but the stack doesn't handle it.

Recommendation: Add properties to the Custom Resource to force re-registration on updates and have the Lambda handle Update events by re-registering.

@rstrahan rstrahan self-assigned this Mar 18, 2026
- Replace single-CIDR SG ingress with SGIngressManager custom resource
  Lambda that handles multiple comma-separated CIDRs with VPC CIDR fallback
- Scope VPC endpoint policy from s3:* to s3:GetObject and s3:ListBucket
- Add Update event handling to RegisterTargetsFunction Lambda with
  UpdateToken property to re-register targets when VPC endpoint changes
- Add descriptions to all security group ingress/egress rules
- Add explicit ALB-to-endpoint egress rule scoped to endpoint SG
@rstrahan rstrahan merged commit 8ff24e2 into aws-solutions-library-samples:develop Mar 19, 2026
1 check passed
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