Production-ready, cost-optimized Amazon EKS cluster infrastructure using Terraform. Designed to maintain monthly costs under $110 while providing essential Kubernetes functionality for the AgentGuard service.
This infrastructure provisions a minimal-cost EKS cluster with the following components:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AWS Cloud β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β VPC (10.0.0.0/16) β β
β β β β
β β ββββββββββββββββββββ ββββββββββββββββββββ β β
β β β AZ us-east-1a β β AZ us-east-1b β β β
β β β β β β β β
β β β Public Subnet β β Public Subnet β β β
β β β 10.0.1.0/28 β β 10.0.2.0/28 β β β
β β β (14 IPs) β β (14 IPs) β β β
β β β β β β β β
β β β ββββββββββββββ β β ββββββββββββββ β β β
β β β β t2.micro β β β β t2.micro β β β β
β β β β Worker β β β β Worker β β β β
β β β β Node β β β β Node β β β β
β β β ββββββββββββββ β β ββββββββββββββ β β β
β β ββββββββββββββββββββ ββββββββββββββββββββ β β
β β β β β β
β β βββββββββββββ¬ββββββββββββ β β
β β β β β
β β ββββββββββΌβββββββββ β β
β β β Internet Gateway β β β
β β βββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β EKS Control Plane (Managed by AWS) β β
β β Kubernetes 1.28 β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββ ββββββββββββββββββββββββββββββββ β
β β S3 Bucket β β DynamoDB Table β β
β β Terraform β β State Locking β β
β β State β β β β
β ββββββββββββββββ ββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- β Cost-Optimized: ~$88-110/month total infrastructure cost
- β High Availability: Multi-AZ deployment across 2 availability zones
- β Managed Control Plane: AWS-managed EKS control plane (no maintenance overhead)
- β Auto-Scaling: Configurable node group scaling (1-3 nodes)
- β Secure State Management: S3 backend with DynamoDB locking
- β Production-Ready: Encryption at rest, versioned state, IAM best practices
Public Subnet Architecture: Worker nodes are deployed in public subnets with direct internet access to eliminate NAT Gateway costs (~$32/month savings). This is suitable for development and testing environments. For production, consider private subnets with NAT Gateway or VPN access.
t2.micro Instances: Cost-optimized instance type (1 vCPU, 1GB RAM) suitable for lightweight workloads. Supports ~10-15 pods per node.
/28 Subnets: Minimal IP allocation (14 usable IPs per subnet) to reduce costs. Limits node scaling to ~6-7 nodes per subnet.
| Component | Configuration | Monthly Cost |
|---|---|---|
| EKS Control Plane | Managed by AWS | $73.00 |
| Worker Nodes | 2Γ t2.micro instances | $15.00 |
| EBS Volumes | 2Γ 20GB gp3 volumes | $3.20 |
| Load Balancer | Classic ELB + data transfer | ~$16.20 |
| Total | $88-107 |
- Scale down during off-hours: Reduce to 1 node to save $7.50/month
- Use Spot instances: Up to 90% savings for non-critical workloads
- Delete unused LoadBalancers: Save $16.20/month per LoadBalancer
- Optimize pod resources: Maximize node utilization to avoid unnecessary scaling
- NAT Gateway: +$32/month (not used in this architecture)
- Larger instances (t2.small): +$7.50/month per node
- Additional EBS storage: +$0.08/GB/month
- CloudWatch Logs: +$0.50/GB ingested
- Data transfer: +$0.09/GB egress
| Tool | Version | Purpose |
|---|---|---|
| Terraform | >= 1.5.0 | Infrastructure provisioning |
| AWS CLI | >= 2.0 | AWS authentication and resource management |
| kubectl | >= 1.28 | Kubernetes cluster interaction |
Verify installations:
terraform --version
aws --version
kubectl version --clientYour AWS credentials must have permissions for:
- Amazon EKS: Cluster and node group management
- Amazon EC2: VPC, subnet, security group, instance management
- Amazon S3: State bucket management
- Amazon DynamoDB: State lock table management
- AWS IAM: Role creation and policy attachment
- Elastic Load Balancing: LoadBalancer provisioning
Verify your account has sufficient quotas:
- EKS clusters per region: β₯ 1
- VPCs per region: β₯ 1
- EC2 instances (t2.micro): β₯ 2-3 on-demand instances
- No Elastic IPs required
Ensure you have approval for ~$100/month infrastructure costs.
aws configureEnter your AWS Access Key ID, Secret Access Key, default region, and output format.
Verify:
aws sts get-caller-identityTerraform requires an S3 bucket and DynamoDB table for state management. Choose one method:
Linux/Mac:
cd agentguard-infrastructure
chmod +x setup-backend.sh
./setup-backend.shWindows (PowerShell):
cd agentguard-infrastructure
.\setup-backend.ps1Follow the detailed instructions in MANUAL_SETUP_INSTRUCTIONS.md
What gets created:
- S3 bucket:
agentguard-terraform-state-<random-suffix>(versioning + encryption enabled) - DynamoDB table:
agentguard-terraform-state-lock(state locking)
See BACKEND_SETUP_README.md for more details.
Copy the example configuration:
cp terraform.tfvars.example terraform.tfvarsEdit terraform.tfvars with your values:
aws_region = "us-east-1"
cluster_name = "agentguard-cluster" # Must be unique in your region
cluster_version = "1.28"
vpc_cidr = "10.0.0.0/16"
availability_zones = ["us-east-1a", "us-east-1b"]
public_subnet_cidrs = ["10.0.1.0/28", "10.0.2.0/28"]
node_instance_types = ["t2.micro"]
node_desired_size = 2
node_min_size = 1
node_max_size = 3
node_disk_size = 20Edit backend.tf with your S3 bucket name and region:
terraform {
backend "s3" {
bucket = "agentguard-terraform-state-<your-suffix>"
key = "agentguard/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "agentguard-terraform-state-lock"
encrypt = true
}
}# Initialize Terraform
terraform init
# Validate configuration
terraform validate
terraform fmt -check
# Preview changes
terraform plan
# Deploy infrastructure (takes ~15-20 minutes)
terraform applyType yes when prompted to confirm.
# Get the kubeconfig command from Terraform output
terraform output kubeconfig_command
# Run the command (example):
aws eks update-kubeconfig --region us-east-1 --name agentguard-cluster
# Verify connectivity
kubectl get nodesYou should see 2 nodes in "Ready" state.
# Check cluster info
kubectl cluster-info
# View validation deployment
kubectl get deployments
kubectl get pods
# Get LoadBalancer endpoint
terraform output loadbalancer_endpoint
# Test endpoint (wait a few minutes for ELB provisioning)
curl -I http://<loadbalancer-endpoint>Expected: HTTP 200 response from nginx validation service.
agentguard-infrastructure/
βββ main.tf # Root module - integrates all components
βββ variables.tf # Input variables
βββ outputs.tf # Output values
βββ versions.tf # Provider version constraints
βββ backend.tf # S3 backend configuration
βββ terraform.tfvars.example # Example variable values
βββ setup-backend.sh # Automated backend setup (Linux/Mac)
βββ setup-backend.ps1 # Automated backend setup (Windows)
βββ README.md # This file
βββ SETUP.md # Detailed setup guide
βββ OPERATIONS.md # Operational procedures
βββ TROUBLESHOOTING.md # Common issues and solutions
βββ BACKEND_SETUP_README.md # Backend setup options
βββ MANUAL_SETUP_INSTRUCTIONS.md # Manual AWS Console setup
βββ modules/
βββ vpc/ # VPC networking module
β βββ main.tf
β βββ variables.tf
β βββ outputs.tf
β βββ README.md
βββ eks/ # EKS cluster module
β βββ main.tf
β βββ variables.tf
β βββ outputs.tf
β βββ README.md
βββ node-group/ # Managed node group module
βββ main.tf
βββ variables.tf
βββ outputs.tf
βββ README.md
- SETUP.md: Comprehensive setup guide with detailed instructions
- OPERATIONS.md: Operational procedures (kubeconfig, scaling, validation)
- TROUBLESHOOTING.md: Common issues and solutions
- BACKEND_SETUP_README.md: Backend setup options
- MANUAL_SETUP_INSTRUCTIONS.md: Manual AWS Console setup
- terraform.tfvars.example: Configuration template with cost optimization notes
- Design Document:
.kiro/specs/agentguard-infrastructure/design.md - Requirements:
.kiro/specs/agentguard-infrastructure/requirements.md
Update terraform.tfvars:
node_desired_size = 3 # Scale to 3 nodesApply changes:
terraform applyUpdate terraform.tfvars:
cluster_version = "1.29" # Upgrade to 1.29Apply changes:
terraform applyNote: Test upgrades in a non-production environment first.
# View all outputs
terraform output
# View specific output
terraform output cluster_endpoint
terraform output loadbalancer_endpointterraform destroyType yes to confirm. This will delete all resources except the S3 bucket and DynamoDB table.
See OPERATIONS.md for detailed operational procedures.
| Issue | Cause | Solution |
|---|---|---|
| "Error acquiring the state lock" | Another Terraform process holds the lock | Wait for completion or terraform force-unlock <lock-id> |
| "InsufficientFreeAddressesInSubnet" | Node scaling exceeds /28 subnet capacity | Reduce node_max_size or expand subnet CIDR |
| Nodes not joining cluster | Security group, IAM, or subnet issues | Verify security groups, IAM policies, and subnet tags |
| LoadBalancer stuck in "Pending" | Missing subnet tags or IAM permissions | Check kubernetes.io/role/elb=1 tag and IAM permissions |
See TROUBLESHOOTING.md for detailed solutions.
- β Public subnets with direct internet access (saves ~$32/month)
- β Public EKS endpoint access
- β Encryption at rest for EBS volumes
- β S3 state encryption enabled
- β IAM roles follow least privilege principle
For production deployments, consider:
- Private Subnets: Use private subnets with NAT Gateway for worker nodes
- VPN/Bastion: Implement VPN or bastion host for secure cluster access
- Network Policies: Enable Kubernetes network policies for pod-to-pod traffic control
- Audit Logging: Enable EKS audit logging to CloudWatch Logs
- Pod Security: Implement Pod Security Standards (Restricted profile)
- Secrets Management: Use AWS Secrets Manager or external secrets operator
- Private Endpoint: Enable private EKS endpoint access
# Terraform validation
terraform validate
terraform fmt -check
# Cluster connectivity
kubectl get nodes
kubectl get pods --all-namespaces
# LoadBalancer test
curl -I http://$(terraform output -raw loadbalancer_endpoint)
# Pod deployment test
kubectl run test-nginx --image=nginx --restart=Never
kubectl wait --for=condition=Ready pod/test-nginx --timeout=60s
kubectl delete pod test-nginxThe infrastructure includes Terratest-based property tests:
- Cost optimization invariant (total cost < $110)
- High availability invariant (resources in β₯ 2 AZs)
- Network connectivity invariant (nodes reach internet)
- Security group invariant (required ports open)
- State consistency invariant (no drift after apply)
See .kiro/specs/agentguard-infrastructure/design.md for testing strategy details.
- Run
terraform fmtbefore committing - Run
terraform validateto check syntax - Update documentation for any changes
- Test changes in a separate environment
Each module should include:
main.tf: Resource definitionsvariables.tf: Input variables with descriptionsoutputs.tf: Output values with descriptionsREADME.md: Module documentation
Monitor these key metrics:
- EKS Cluster: API server response time, request rate
- Worker Nodes: CPU utilization, memory utilization, disk usage
- Pods: Pod count, restart count, resource usage
# View current month costs
aws ce get-cost-and-usage \
--time-period Start=$(date +%Y-%m-01),End=$(date +%Y-%m-%d) \
--granularity MONTHLY \
--metrics BlendedCost \
--group-by Type=SERVICESet up AWS Budgets to receive alerts when costs exceed thresholds.
- Review EKS version release notes
- Test upgrade in non-production environment
- Update
cluster_versioninterraform.tfvars - Run
terraform apply - Update node group AMI if needed
- Verify workload compatibility
- Review Terraform upgrade guide
- Update
required_versioninversions.tf - Run
terraform init -upgrade - Test with
terraform plan - Apply changes
- Terraform AWS Provider: https://registry.terraform.io/providers/hashicorp/aws/latest/docs
- Amazon EKS Documentation: https://docs.aws.amazon.com/eks/
- Kubernetes Documentation: https://kubernetes.io/docs/
- AWS CLI Reference: https://docs.aws.amazon.com/cli/
- Check TROUBLESHOOTING.md for common issues
- Review Terraform plan output for error messages
- Check AWS CloudWatch Logs for cluster and node logs
- Review the design document for architecture details
This infrastructure code is provided as-is for the AgentGuard project.
After successful deployment:
- Deploy Applications: Use kubectl or Helm to deploy your applications
- Configure Monitoring: Set up CloudWatch metrics and alarms
- Implement Autoscaling: Configure HPA and Cluster Autoscaler
- Set Up CI/CD: Integrate with your CI/CD pipeline
- Review Security: Implement additional security hardening
- Cost Optimization: Monitor and optimize resource usage
Estimated Deployment Time: 15-20 minutes
Estimated Monthly Cost: $88-110
Maintenance Overhead: Low (AWS-managed control plane)