AWS Web Stacks is a library of CloudFormation templates for hosting web applications on AWS using EKS (Elastic Kubernetes Service). The templates create a fully-managed hosting environment with an EKS cluster, worker nodes, S3 buckets for static assets, an ECR repository for Docker images, and optional RDS and ElastiCache instances. All resources are created in a self-contained VPC.
The CloudFormation templates are written in troposphere.
Available templates:
| Standard Region | AWS GovCloud | |
|---|---|---|
| Without NAT Gateway | ![]() |
![]() |
| With NAT Gateway | ![]() |
![]() |
The templates are available with and without NAT gateways. If you select the version without NAT gateways, instances in private subnets will not have internet access. This is fine if your application only needs to communicate with AWS services (which are accessed via VPC endpoints) and doesn't need to reach external APIs or package repositories.
If your application needs outbound internet access from private subnets (e.g., to pull Docker images, install OS packages, or call external APIs), use the version with NAT gateways.
Stack creation typically takes 30-35 minutes. The slowest resources are:
- CloudFront distribution (~10 min): Propagates to edge locations
- RDS instance (~10 min): Creates and initializes the database
- EKS cluster (~10 min): Provisions control plane and nodegroup
The templates automatically create an ACM certificate for your domain in us-east-1
(required for CloudFront). You'll need to approve the certificate validation via email
or DNS records, depending on your domain provider.
Note: .io domains have known issues with ACM email validation. If you use a
.io domain, you may need to create the certificate manually and pass the ARN via
the AssetsCloudFrontCertArn parameter.
The templates support three encryption modes for EBS volumes, RDS, and ElastiCache:
- AES-256 (default): AWS-managed keys, no additional cost
- Customer-managed CMK: You provide a KMS key ARN via
CustomerManagedCmkArn - No encryption: Set
UseAES256Encryptiontofalse
For EBS encryption on EKS nodes, you may also need to set up a key policy allowing the EC2 service to use the key. See the AWS EBS encryption docs for details.
Each stack creates:
- VPC: Public and private subnets across two availability zones
- EKS Cluster: Managed Kubernetes control plane
- Nodegroup: Auto-scaling group of worker nodes
- ECR Repository: Docker image registry with scan-on-push
- S3 Buckets: Public assets bucket (with optional CloudFront) and private assets bucket
- RDS Instance (optional): MySQL or PostgreSQL with optional read replica
- ElastiCache (optional): Memcached or Redis (with optional cluster mode)
- CloudFront (optional): CDN for static assets with custom domain support
To access your EKS cluster with kubectl:
aws eks update-kubeconfig --name <cluster-name> --alias <alias>
kubectl get nodes --context <alias>For Pod Identity-enabled clusters, the EBS CSI driver uses pod identity for
authentication. After enabling EksUseAccessConfig=true, you may need to
restart the EBS CSI controller:
kubectl rollout restart deployment ebs-csi-driver -n kube-systemThe v3 templates support AWS Pod Identity for fine-grained IAM permissions to pods. This requires:
EksUseAccessConfig=true: EnablesAccessConfigwithauthenticationMode: APIeks-pod-identity-agentadd-on: Installed automatically- IAM roles with pod identity trust policies: Created for EBS CSI driver
See "Upgrading from v2" below for full migration instructions.
Install dependencies (requires uv):
uv sync --locked
Build all templates:
make templates
This generates four YAML templates in the content/ directory.
Environment variables control which templates are generated:
USE_EKS=on: Build EKS templates (required)USE_GOVCLOUD=on: Build GovCloud-compatible templatesUSE_NAT_GATEWAY=on: Include NAT gateway in private subnets
Examples:
# Standard region, no NAT
USE_EKS=on python -c 'import stack' > content/eks-no-nat.yaml
# Standard region, with NAT
USE_EKS=on USE_NAT_GATEWAY=on python -c 'import stack' > content/eks-nat.yaml
# GovCloud, with NAT
USE_EKS=on USE_GOVCLOUD=on USE_NAT_GATEWAY=on python -c 'import stack' > content/gc-nat.yamlThe v3 templates are EKS-only. Several parameters from v2 have been removed and one new required parameter has been added. When updating an existing stack, you must adjust the parameters accordingly.
Parameters to remove (no longer supported):
AdministratorIPAddressBastionAMIBastionInstanceTypeBastionKeyNameBastionTypeElasticsearchInstanceTypeElasticsearchVersionElasticsearchVolumeSizeUseSFTPServer
New required parameter:
EksUseAccessConfig: Controls whether the EKS cluster uses the modernAccessConfig(authenticationMode: API) with Pod Identity support.Set to
falseinitially when migrating an existing cluster. This prevents CloudFormation from trying to replace the cluster (which fails if the cluster has a custom name).After the stack update succeeds, manually enable API authentication:
- aws eks update-cluster-config
--name <cluster-name> --access-config authenticationMode=API
Then update the stack again with
EksUseAccessConfig=trueto let CloudFormation manage the AccessConfig, Pod Identity agent, and EBS CSI driver.For new stacks, set to
truefrom the start.
Notes:
AssetsBucketAccessControlshould be set toPrivatewhen migrating existing stacks to avoid S3 ACL errors. New stacks can omit this (defaults to no ACL).After the initial update with
EksUseAccessConfig=false, enable API auth via CLI, then update again withEksUseAccessConfig=true.The EBS CSI controller may need a restart after enabling Pod Identity:
kubectl rollout restart deployment ebs-csi-driver -n kube-system
See :doc:`CONTRIBUTING` for development setup, testing, and release process.
Copyright 2017, 2018, 2026 Jean-Phillipe Serafin, Caktus Consulting Group, LLC
