321 lines
8.9 KiB
Markdown
Executable File
321 lines
8.9 KiB
Markdown
Executable File
# Terraform AWS EKS Fargate Profile Module
|
|
|
|
## Overview
|
|
|
|
This Terraform module provisions an AWS EKS Fargate Profile, enabling serverless compute for Kubernetes workloads. Fargate profiles allow you to run pods without managing EC2 instances, with automatic scaling and built-in security.
|
|
|
|
## Features
|
|
|
|
- EKS Fargate Profile provisioning
|
|
- Namespace and label-based pod selection
|
|
- IAM role and policy management for Fargate pods
|
|
- Automatic pod execution without EC2 instances
|
|
- CloudPosse naming conventions
|
|
- Conditional module enablement
|
|
- Integration with existing EKS clusters
|
|
|
|
## Resources Created
|
|
|
|
### Fargate
|
|
- AWS EKS Fargate Profile
|
|
- Fargate Pod Execution IAM Role
|
|
|
|
### IAM
|
|
- IAM Role for Fargate pod execution
|
|
- IAM Policy Attachment: AmazonEKSFargatePodExecutionRolePolicy
|
|
|
|
## Usage
|
|
|
|
### Basic Example
|
|
|
|
```hcl
|
|
module "eks_fargate_profile" {
|
|
source = "git@github.com:webuildyourcloud/terraform-aws-eks_fargate_profile.git?ref=tags/0.0.2"
|
|
|
|
# Naming
|
|
namespace = "myorg"
|
|
stage = "prod"
|
|
name = "app"
|
|
|
|
# Cluster Configuration
|
|
cluster_name = "my-eks-cluster"
|
|
subnet_ids = ["subnet-12345678", "subnet-87654321"]
|
|
|
|
# Fargate Selection
|
|
kubernetes_namespace = "fargate-workloads"
|
|
|
|
kubernetes_labels = {
|
|
fargate = "true"
|
|
}
|
|
|
|
# Tags
|
|
tags = {
|
|
Environment = "production"
|
|
ManagedBy = "terraform"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Multiple Fargate Profiles
|
|
|
|
```hcl
|
|
# Fargate profile for development namespace
|
|
module "fargate_dev" {
|
|
source = "git@github.com:webuildyourcloud/terraform-aws-eks_fargate_profile.git?ref=tags/0.0.2"
|
|
|
|
namespace = "myorg"
|
|
stage = "prod"
|
|
name = "dev"
|
|
|
|
cluster_name = module.eks_cluster.cluster_id
|
|
subnet_ids = module.vpc.private_subnet_ids
|
|
kubernetes_namespace = "development"
|
|
|
|
kubernetes_labels = {}
|
|
|
|
tags = {
|
|
Environment = "development"
|
|
}
|
|
}
|
|
|
|
# Fargate profile for specific workload with labels
|
|
module "fargate_batch" {
|
|
source = "git@github.com:webuildyourcloud/terraform-aws-eks_fargate_profile.git?ref=tags/0.0.2"
|
|
|
|
namespace = "myorg"
|
|
stage = "prod"
|
|
name = "batch"
|
|
|
|
cluster_name = module.eks_cluster.cluster_id
|
|
subnet_ids = module.vpc.private_subnet_ids
|
|
kubernetes_namespace = "batch-processing"
|
|
|
|
kubernetes_labels = {
|
|
workload = "batch"
|
|
compute = "fargate"
|
|
}
|
|
|
|
tags = {
|
|
WorkloadType = "batch"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Variables
|
|
|
|
| Name | Description | Type | Default | Required |
|
|
|------|-------------|------|---------|----------|
|
|
| namespace | Namespace (e.g., 'eg' or 'cp') | `string` | `""` | no |
|
|
| stage | Stage (e.g., 'prod', 'staging', 'dev') | `string` | `""` | no |
|
|
| name | Solution name (e.g., 'app' or 'cluster') | `string` | n/a | yes |
|
|
| delimiter | Delimiter between namespace, stage, name and attributes | `string` | `"-"` | no |
|
|
| attributes | Additional attributes | `list(string)` | `[]` | no |
|
|
| tags | Additional tags | `map(string)` | `{}` | no |
|
|
| enabled | Enable/disable module resources | `bool` | `true` | no |
|
|
| cluster_name | Name of the EKS cluster | `string` | n/a | yes |
|
|
| subnet_ids | List of private subnet IDs to associate with Fargate Profile | `list(string)` | n/a | yes |
|
|
| kubernetes_namespace | Kubernetes namespace for pod selection | `string` | n/a | yes |
|
|
| kubernetes_labels | Key-value mapping of Kubernetes labels for pod selection | `map(string)` | `{}` | no |
|
|
|
|
## Outputs
|
|
|
|
| Name | Description |
|
|
|------|-------------|
|
|
| eks_fargate_profile_role_arn | ARN of the EKS Fargate Profile IAM role |
|
|
| eks_fargate_profile_role_name | Name of the EKS Fargate Profile IAM role |
|
|
| eks_fargate_profile_id | EKS Cluster name and Fargate Profile name separated by colon |
|
|
| eks_fargate_profile_arn | Amazon Resource Name (ARN) of the EKS Fargate Profile |
|
|
| eks_fargate_profile_status | Status of the EKS Fargate Profile |
|
|
|
|
## Requirements
|
|
|
|
| Name | Version |
|
|
|------|---------|
|
|
| terraform | >= 0.13 |
|
|
| aws | Latest |
|
|
|
|
## Dependencies
|
|
|
|
- [cloudposse/terraform-null-label](https://github.com/cloudposse/terraform-null-label) - Resource naming
|
|
|
|
## Pod Selection
|
|
|
|
Fargate profiles use selectors to determine which pods run on Fargate:
|
|
|
|
### Namespace-Only Selection
|
|
```hcl
|
|
kubernetes_namespace = "my-namespace"
|
|
kubernetes_labels = {}
|
|
```
|
|
All pods in `my-namespace` will run on Fargate.
|
|
|
|
### Namespace + Label Selection
|
|
```hcl
|
|
kubernetes_namespace = "my-namespace"
|
|
kubernetes_labels = {
|
|
compute = "fargate"
|
|
tier = "backend"
|
|
}
|
|
```
|
|
Only pods in `my-namespace` with matching labels will run on Fargate.
|
|
|
|
## Kubernetes Integration
|
|
|
|
### Deploy Pod to Fargate
|
|
|
|
Create a pod that matches the Fargate profile selector:
|
|
|
|
```yaml
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: my-fargate-pod
|
|
namespace: fargate-workloads
|
|
labels:
|
|
fargate: "true"
|
|
spec:
|
|
containers:
|
|
- name: nginx
|
|
image: nginx:latest
|
|
resources:
|
|
requests:
|
|
cpu: 250m
|
|
memory: 512Mi
|
|
limits:
|
|
cpu: 500m
|
|
memory: 1Gi
|
|
```
|
|
|
|
### Deploy Deployment to Fargate
|
|
|
|
```yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: fargate-app
|
|
namespace: fargate-workloads
|
|
spec:
|
|
replicas: 3
|
|
selector:
|
|
matchLabels:
|
|
app: my-app
|
|
fargate: "true"
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: my-app
|
|
fargate: "true"
|
|
spec:
|
|
containers:
|
|
- name: app
|
|
image: my-app:v1.0
|
|
resources:
|
|
requests:
|
|
cpu: 500m
|
|
memory: 1Gi
|
|
```
|
|
|
|
## Important Notes
|
|
|
|
1. **Private Subnets Only**: Fargate profiles require private subnets with NAT gateway or VPC endpoints
|
|
2. **Subnet Tagging**: Subnets must have the tag `kubernetes.io/cluster/<cluster_name> = "shared"` or `owned`
|
|
3. **Resource Limits**: Fargate requires explicit CPU and memory resource specifications
|
|
4. **Networking**: Pods get their own ENI and private IP address
|
|
5. **Profile Limits**: Each Fargate profile supports one namespace and up to 5 label selectors
|
|
6. **CoreDNS**: For CoreDNS to run on Fargate, you need a specific Fargate profile for kube-system namespace
|
|
7. **Storage**: Only supports ephemeral storage and Amazon EFS (not EBS)
|
|
8. **Creation Time**: Fargate profile creation takes 3-5 minutes
|
|
|
|
## Fargate Resource Specifications
|
|
|
|
### CPU and Memory Combinations
|
|
|
|
Fargate supports specific CPU and memory combinations:
|
|
|
|
| vCPU | Memory Options |
|
|
|------|----------------|
|
|
| 0.25 | 0.5 GB, 1 GB, 2 GB |
|
|
| 0.5 | 1 GB, 2 GB, 3 GB, 4 GB |
|
|
| 1 | 2 GB, 3 GB, 4 GB, 5 GB, 6 GB, 7 GB, 8 GB |
|
|
| 2 | Between 4 GB and 16 GB in 1 GB increments |
|
|
| 4 | Between 8 GB and 30 GB in 1 GB increments |
|
|
|
|
## Best Practices
|
|
|
|
1. **Use Private Subnets**: Always use private subnets for Fargate profiles
|
|
2. **Specify Resources**: Always define CPU and memory requests/limits for Fargate pods
|
|
3. **Multiple Profiles**: Create separate profiles for different workload types
|
|
4. **Label Strategy**: Use consistent labeling for easy workload routing
|
|
5. **Cost Optimization**: Use Fargate for variable workloads; consider EC2 for stable, predictable loads
|
|
6. **Monitoring**: Use CloudWatch Container Insights for Fargate monitoring
|
|
7. **Logging**: Configure Fargate logging to CloudWatch or Fluent Bit
|
|
8. **Security**: Leverage pod-level IAM roles via IRSA
|
|
|
|
## Cost Considerations
|
|
|
|
Fargate pricing is based on:
|
|
- vCPU resources (per hour)
|
|
- Memory resources (per GB per hour)
|
|
- Minimum charge duration: 1 minute
|
|
|
|
Cost comparison:
|
|
- **Use Fargate**: Variable workloads, batch jobs, development/testing
|
|
- **Use EC2 Node Groups**: Stable baseline workloads, cost-sensitive production workloads
|
|
|
|
## CoreDNS on Fargate
|
|
|
|
To run CoreDNS on Fargate, create a specific profile:
|
|
|
|
```hcl
|
|
module "fargate_coredns" {
|
|
source = "git@github.com:webuildyourcloud/terraform-aws-eks_fargate_profile.git"
|
|
|
|
name = "coredns"
|
|
cluster_name = module.eks_cluster.cluster_id
|
|
subnet_ids = module.vpc.private_subnet_ids
|
|
kubernetes_namespace = "kube-system"
|
|
|
|
kubernetes_labels = {
|
|
"k8s-app" = "kube-dns"
|
|
}
|
|
}
|
|
```
|
|
|
|
Then remove the `eks.amazonaws.com/compute-type : ec2` annotation from CoreDNS pods.
|
|
|
|
## Troubleshooting
|
|
|
|
### Pods stuck in Pending state
|
|
- Verify subnet IDs are correct and private
|
|
- Check subnet tags include cluster name
|
|
- Ensure NAT gateway or VPC endpoints are configured
|
|
- Verify resource requests match Fargate configurations
|
|
|
|
### Fargate profile creation fails
|
|
- Verify cluster name is correct
|
|
- Check IAM permissions for creating Fargate profiles
|
|
- Ensure subnets are in the same VPC as the cluster
|
|
|
|
### Pods not matching Fargate profile
|
|
- Verify namespace matches `kubernetes_namespace`
|
|
- Check pod labels match `kubernetes_labels`
|
|
- Ensure no conflicting node selectors or taints
|
|
|
|
## Monitoring and Logging
|
|
|
|
### Enable Container Insights
|
|
|
|
```bash
|
|
aws eks update-cluster-config \
|
|
--name my-cluster \
|
|
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
|
|
```
|
|
|
|
### Configure Fluent Bit for Fargate
|
|
|
|
Deploy AWS Fluent Bit DaemonSet for centralized logging from Fargate pods.
|
|
|
|
## License
|
|
|
|
This module is provided as-is for use within your organization.
|