AWS CloudFormation describes BookNest's AWS 24 side as CloudFormation 24 templates: a VPC with subnets and security groups, an S3 24 bucket for the front end, a DynamoDB 24 table and a Lambda 24 API, deployed to LocalStack 4.13.1 63,725 (LocalStack and cfn-lint). It does not provision EKS 24 , and the reason is worth seeing. eksctl 24 , which looks like a Kubernetes 5,150 tool, is a CloudFormation client: every cluster is a stack named eksctl-<cluster>-cluster (the VPC, subnets, NAT gateway, IAM service role, security groups and the AWS::EKS::Cluster itself) plus one eksctl-<cluster>-nodegroup-<name> stack per node group. eksctl utils describe-stacks --cluster booknest lists them, and delete cluster deletes them.

CloudFormation also has native AWS::EKS::* resource types, so a cluster can live in your own template beside the rest of AWS CloudFormation. This one takes its subnets as a parameter; to build on AWS CloudFormation's VPC stack, replace it with Fn::ImportValue of that stack's subnet exports (Fn::ImportValue):
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
SubnetIds: {Type: "List<AWS::EC2::Subnet::Id>"}
ClusterRoleArn: {Type: String}
NodeRoleArn: {Type: String}
Resources:
Cluster:
Type: AWS::EKS::Cluster
Properties:
Name: booknest
Version: "1.36"
RoleArn: !Ref ClusterRoleArn
ResourcesVpcConfig: {SubnetIds: !Ref SubnetIds}
SpotNodes:
Type: AWS::EKS::Nodegroup
Properties:
ClusterName: !Ref Cluster
NodeRole: !Ref NodeRoleArn
Subnets: !Ref SubnetIds
CapacityType: SPOT
InstanceTypes: [t3.medium, t3a.medium]
ScalingConfig: {MinSize: 1, DesiredSize: 2, MaxSize: 4}Run AWS CloudFormation's checks against it, on a LocalStack 4.13.1 container of this chapter's own (port 32566), then ask eksctl to plan a cluster there:
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_DEFAULT_REGION=us-east-1
export AWS_ENDPOINT_URL=http://127.0.0.1:32566
cfn-lint eks-cluster.yaml && echo "cfn-lint: no findings"
sed 's/SPOT$/SPOTS/' eks-cluster.yaml > typo.yaml && cfn-lint typo.yaml
aws cloudformation create-stack --stack-name booknest-eks --template-body file://eks-cluster.yaml \
--parameters ParameterKey=SubnetIds,ParameterValue=subnet-1a \
ParameterKey=ClusterRoleArn,ParameterValue=arn:aws:iam::000000000000:role/eks \
ParameterKey=NodeRoleArn,ParameterValue=arn:aws:iam::000000000000:role/node >/dev/null
aws cloudformation wait stack-create-complete --stack-name booknest-eks
aws cloudformation describe-stack-events --stack-name booknest-eks --output text \
--query 'StackEvents[?ResourceStatusReason].[LogicalResourceId,ResourceStatusReason]' |
tr '\t' ' '
eksctl create cluster --name booknest --zones us-east-1a,us-east-1b --dry-run 2>&1 |
grep -o 'StatusCode: 501\|the eks service is not included[^,]*'cfn-lint: no findings E3030 'SPOTS' is not one of ['CAPACITY_BLOCK', 'ON_DEMAND', 'OnDemand', 'SPOT'] typo.yaml:20:7 SpotNodes Resource type AWS::EKS::Nodegroup is not supported but was deployed as a fallback Cluster Resource type AWS::EKS::Cluster is not supported but was deployed as a fallback StatusCode: 501 the eks service is not included within your LocalStack license
cfn-lint 1.57.0 2,641 knows the EKS schema and catches the typo. LocalStack's answer is the lesson: the stack reached CREATE_COMPLETE, but EKS is not in the Community image, so both resources are empty fallbacks, and eksctl, asking the EKS API directly, gets a plain refusal. A green stack on an emulator proves that a template parses, not that the service exists: check EKS templates with cfn-lint and cfn-guard 1,388 (Linting and Testing), then in a sandbox account.