8.9 KiB
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

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

# 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

Pod Selection

Fargate profiles use selectors to determine which pods run on Fargate:

Namespace-Only Selection

kubernetes_namespace = "my-namespace"
kubernetes_labels    = {}

All pods in my-namespace will run on Fargate.

Namespace + Label Selection

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:

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

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:

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

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.