EKS Fargate Terraform Provisioning With Fargate Profiles And Addon Management

Terraform driven provisioning of Amazon EKS with AWS Fargate as the compute layer removes the operational burden of managing EC2 worker nodes while preserving declarative infrastructure as code control. The reference material describes a reproducible workflow for creating an EKS cluster with Fargate profiles, installing essential addons, exposing a microservice via an AWS Load Balancer, and organizing state and configuration for multi environment use. The pattern is presented as a production starting point that delivers complete EKS infrastructure in 10 to 15 minutes, a working nginx application with load balancer, comprehensive RBAC ready for team use, and multi environment support for dev, staging and prod.

The approach centers on the terraform-aws-modules/eks/aws module. The module creates Amazon EKS Kubernetes resources and supports Fargate profile configuration, user data, network connectivity, and upgrade guides. The documentation notes a caution for EKS Auto Mode API behavior. Due to the current EKS Auto Mode API, to disable EKS Auto Mode you will have to explicitly set computeconfig = { enabled = false }. If you try to disable by simply removing computeconfig block, this will fail to disable EKS Auto Mode.

The material also emphasizes that Terraform ensures reproducible infrastructure. Always monitor costs and permissions when using serverless EKS. The prediction is that as serverless Kubernetes adoption grows, expect tighter integration between Fargate, EKS, and DevOps tools like Terraform and GitHub Actions. The report is attributed to Darryl Ruggles – Hackers Feeds, Extra Hub Undercode MoN, Basic Verification Pass.

Terraform Prerequisites And Provider Configuration

The workflow begins with environment readiness. The prerequisites are AWS CLI configured, Terraform installed, kubectl installed.

Impact layer for the user is that without AWS CLI configured, Terraform cannot authenticate to AWS and the eks module cannot create resources. Without Terraform installed, the declarative manifests cannot be processed. Without kubectl installed, the cluster cannot be accessed after creation for node verification and microservice deployment.

Contextual layer connects prerequisites to later steps. The AWS CLI configuration is later used implicitly for authentication when running aws eks --region us-west-2 update-kubeconfig --name fargate-cluster. kubectl get nodes is executed after kubeconfig update to confirm the control plane is reachable.

Provider definition is shown in two variants. The first variant uses a simple region declaration.

provider "aws" { region = "us-west-2" }

A second variant from the file structure example defines AWS provider along with AWS CLI credentials as variable that you can read from variables defined in variables.tf file.

terraform { required_version = "=1.0.2" required_providers { aws = { source = "hashicorp/aws" version = "3.49.0" } } }

Provider definition

provider "aws" { access_key = var.access_key secret_key = var.secret_key region = var.region token = var.session_token }

The presence of required_version = "=1.0.2" and provider version "3.49.0" locks the execution environment. Impact is that reproducible runs are guaranteed across team members. Changing versions without testing can break module compatibility.

Core Module Declaration And Fargate Profile Definition

The main.tf file contains the module block.

module "eks" { source = "terraform-aws-modules/eks/aws" cluster_name = "fargate-cluster" cluster_version = "1.27" subnets = ["subnet-123456", "subnet-789012"] vpc_id = "vpc-123456" fargate_profiles = { default = { name = "fp-default" selectors = [ { namespace = "default" } ] } } }

The module source is terraform-aws-modules/eks/aws. clustername is fargate-cluster. clusterversion is 1.27. subnets are subnet-123456 and subnet-789012. vpcid is vpc-123456. fargateprofiles default contains name fp-default and a selector for namespace default.

The impact of specifying subnets and vpc_id is that Fargate pods are scheduled only in the subnets belonging to the specified VPC. The selector restricts pod placement to the default namespace. This means any pod created in default namespace without additional constraints will be scheduled onto Fargate.

Contextual connection: The fargateprofiles block is later expanded to include coredns-fargate-profile with name coredns, selectors for namespace kube-system with labels k8s-app = kube-dns and namespace default, and subnets from module.vpc.outputs.privatesubnets. The expansion shows how system critical pods can be pinned to Fargate with label selectors.

A table summarizes the core parameters.

| Parameter | Value | Purpose |
| clustername | fargate-cluster | Identifier for the EKS control plane |
| cluster
version | 1.27 | Kubernetes version pinned for the control plane |
| vpcid | vpc-123456 | VPC containing the worker subnets |
| subnets | subnet-123456, subnet-789012 | Subnets for Fargate pod ENI placement |
| fargate
profiles.default.name | fp-default | Fargate profile name |
| fargate_profiles.default.selectors.namespace | default | Namespace selector for Fargate placement |

Addon Installation And VPC CNI Requirement

Kubernetes Networking requires ensuring VPC CNI addon is installed.

resource "aws_eks_addon" "example" { cluster_name = module.eks.cluster_id addon_name = "vpc-cni" }

The addonname is vpc-cni. The clustername references module.eks.cluster_id.

The material also shows CoreDNS plugin configuration.

resource "aws_eks_addon" "coredns" { addon_name = "coredns" addon_version = "v1.8.4-eksbuild.1" cluster_name = "eks-serve" resolve_conflicts = "OVERWRITE" depends_on = [module.eks-cluster] }

Impact layer: VPC CNI provides networking for pods in the VPC. Without it, pods cannot obtain ENI and IP addresses. CoreDNS provides cluster DNS. Version pinning to v1.8.4-eksbuild.1 ensures compatibility with clusterversion 1.27. resolveconflicts = "OVERWRITE" forces updates when conflicts arise.

Contextual layer: Addon installation occurs after the cluster exists. dependson = [module.eks-cluster] enforces ordering. The module.eks.clusterid output is used to reference the created cluster.

Cluster Deployment Workflow And Kubectl Configuration

Deploy the Cluster commands are:

terraform init terraform plan terraform apply -auto-approve

Configure kubectl commands are:

aws eks --region us-west-2 update-kubeconfig --name fargate-cluster kubectl get nodes

Impact: terraform init downloads providers and modules. terraform plan previews changes. terraform apply -auto-approve applies without interactive confirmation. The update-kubeconfig command writes kubeconfig credentials for the current AWS profile. kubectl get nodes confirms the control plane is reachable and shows Fargate managed nodes.

Contextual layer: The workflow is sequential deployment. Infrastructure first, then applications automatically. Terraform workspaces isolate state for different environments.

Microservice Exposure Pattern With Load Balancer

Expose a Microservice steps are:

kubectl create deployment nginx --image=nginx kubectl expose deployment nginx --port=80 --type=LoadBalancer

Verify the Service command is:

kubectl get svc

Expected Output contains NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx.

Impact: Creating deployment nginx with image nginx instantiates a pod in the default namespace. Because fargate_profiles.default selects namespace default, the pod runs on Fargate. Exposing as LoadBalancer creates an AWS Load Balancer Service type, which provisions an ELB with external IP.

Contextual connection: Fargate pricing is pay-per-pod, no idle EC2 instances. Resource limits prevent resource waste in containers. Health checks with application-aware load balancer probes are ready. Auto scaling with Horizontal Pod Autoscaler is ready.

Pricing Model And Resource Consumption Awareness

You Should Know items include:

  • AWS Fargate Pricing: Pay only for vCPU and memory used.
  • Terraform Best Practices: Use remote state (S3 backend).
  • Kubernetes Networking: Ensure VPC CNI addon is installed.
  • Security: Apply IAM roles for least privilege access.

The Fargate pricing model means costs scale with actual pod resource requests. The impact is cost predictability versus EC2 overprovisioning. The user must monitor costs and permissions when using serverless EKS.

The material also notes Fargate pricing: Pay-per-pod, no idle EC2 instances. Resource limits: Prevent resource waste in containers. Multi-AZ deployment: High availability by default.

Contextual layer ties pricing to the earlier decision to use Fargate profiles for default and kube-system namespaces. No node provisioning means no idle capacity charges.

State Management And Remote Backend Configuration

Terraform Best Practices include use remote state (S3 backend).

The terraform.tf file example shows:

terraform { backend "s3" { bucket = "swiftalk-iac" dynamodb_table = "swiftalk-iac-locks" key = "vpc/terraform.tfstate" region = "us-east-1" encrypt = true } }

Impact: Remote state prevents local state file conflicts. S3 provides durable storage. DynamoDB table swiftalk-iac-locks provides state locking to prevent concurrent applies. encrypt = true protects state at rest. key = "vpc/terraform.tfstate" organizes state per component.

Contextual layer: The same backend pattern supports Terraform workspace isolation for dev, staging, prod. Separate tfvars files for environment-specific configurations.

Multi-Environment Workspace Isolation And Configuration Separation

The reference describes:

  • Terraform workspaces: Isolate state for different environments
  • Separate tfvars files: Environment-specific configurations
  • Sequential deployment: Infrastructure first, then applications automatically
    Each environment uses:
  • Separate tfvars files (dev/, staging/, prod/)
  • Different cluster names and configurations
  • Isolated AWS resources and namespaces
  • Terraform workspace isolation
  • Automatic creation: IAM Groups are created for each cluster
  • User management: Add IAM users to groups for appropriate access
  • Role assumption: Users assume roles based on group membership
  • MFA support: Optional MFA requirements for role assumption
  • Fargate pricing: Pay-per-pod, no idle EC2 instances
  • Resource limits: Prevent resource waste in containers
  • Multi-AZ deployment: High availability by default
  • Health checks: Application-aware load balancer probes
  • Auto scaling: Horizontal Pod Autoscaler ready
  • Monitoring: CloudWatch integration ready for extension
  • Modular design: Add applications via additional Helm charts
  • RBAC foundation: Easy to add users to IAM Groups

Impact: Separation of tfvars prevents configuration drift. Workspace isolation ensures dev changes do not affect prod state. IAM Groups automation provides RBAC foundation.

Contextual connection: The file structure example lists cluster main.tf, outputs.tf, providers.tf, terraform.tf, terraform.tfvars, variables.tf. This structure supports modular design and environment-specific variables.

File Structure And Provider Credentials Handling

The file structure looks like:

cluster ├── main.tf ├── outputs.tf ├── providers.tf ├── terraform.tf ├── terraform.tfvars ├── variables.tf

The providers.tf file defined AWS provider along with AWS CLI credentials as variable that you can read from variables defined in variables.tf file.

Impact: Clear separation of concerns. main.tf contains module and resource declarations. outputs.tf exposes cluster_endpoint. providers.tf manages credentials. terraform.tf manages backend. variables.tf defines input variables.

Contextual layer: The providers.tf uses var.accesskey, var.secretkey, var.region, var.session_token. This allows credential injection without hardcoding secrets. The variables.tf file supplies these values.

Fargate Profile Selector Logic For CoreDNS And System Namespaces

The profile configuration example shows:

fargate_profiles = { coredns-fargate-profile = { name = "coredns" selectors = [ { namespace = "kube-system" labels = { k8s-app = "kube-dns" } }, { namespace = "default" } ] subnets = flatten([module.vpc.outputs.private_subnets]) } }

We're essentially saying, select the pods with label k8s-app to run in the kube-system namespace.

Impact: Label selector restricts Fargate placement to CoreDNS pods only, not all kube-system pods. Using flatten([module.vpc.outputs.private_subnets]) ensures pods run in private subnets.

Contextual connection: This complements the default fargate profile that selects namespace default. The combination provides system DNS on Fargate and application workloads on Fargate.

Operational Best Practices And Security Considerations

Security: Apply IAM roles for least privilege access.

The material notes User management: Add IAM users to groups for appropriate access. Role assumption: Users assume roles based on group membership. MFA support: Optional MFA requirements for role assumption.

Impact: Least privilege IAM roles reduce blast radius. Role assumption with MFA adds defense in depth.

Contextual layer: Terraform ensures reproducible infrastructure. Monitoring costs and permissions when using serverless EKS is essential. The prediction of tighter integration between Fargate, EKS, and DevOps tools like Terraform and GitHub Actions suggests future CI/CD pipelines will automate profile updates and addon versions.

Expected Outputs And Verification Steps

Output block:

output "cluster_endpoint" { value = module.eks.cluster_endpoint }

The cluster endpoint output allows downstream modules or scripts to reference the API server address.

Verification steps from the guide:

  • Run terraform init to get an EKS Fargate Cluster up and running in minutes!
  • Run terraform plan
  • Run terraform apply -auto-approve
  • Configure kubectl
  • Deploy sample app
  • Verify service

Expected output for kubectl get svc shows NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx.

Impact: Verification confirms load balancer provisioning and pod scheduling on Fargate. The external IP indicates the AWS Load Balancer is attached.

Contextual layer: The complete solution gives complete EKS infrastructure in 10-15 minutes, working nginx application with load balancer, comprehensive RBAC ready for team, multi-environment support.

Conclusion

The reference material presents a coherent pattern for provisioning EKS Fargate with Terraform. The core module declaration with clustername fargate-cluster, clusterversion 1.27, vpcid vpc-123456, subnets subnet-123456 and subnet-789012, and fargateprofiles default with name fp-default selecting namespace default establishes the baseline. Addon installation for vpc-cni and coredns with version v1.8.4-eksbuild.1 ensures networking and DNS functionality. Deployment workflow with terraform init, terraform plan, terraform apply -auto-approve followed by aws eks update-kubeconfig and kubectl get nodes validates the control plane. Microservice exposure with kubectl create deployment nginx --image=nginx and kubectl expose deployment nginx --port=80 --type=LoadBalancer demonstrates Fargate pod placement and load balancer integration.

Remote state with S3 backend bucket swiftalk-iac, dynamodb_table swiftalk-iac-locks, key vpc/terraform.tfstate, region us-east-1, encrypt true provides durable and locked state. File structure with main.tf, outputs.tf, providers.tf, terraform.tf, terraform.tfvars, variables.tf supports maintainability. Multi-environment support via Terraform workspaces, separate tfvars files for dev, staging, prod, isolated AWS resources and namespaces, automatic IAM Groups creation, user management with role assumption and optional MFA, and modular design for Helm charts provides production readiness.

The pattern aligns with Terraform best practices for remote state, least privilege IAM roles, VPC CNI addon installation, and pay-per-pod Fargate pricing with no idle EC2 instances. The prediction of tighter integration between Fargate, EKS, and DevOps tools like Terraform and GitHub Actions indicates continued evolution of serverless Kubernetes automation. The solution remains a perfect starting point for next production workloads.

Sources

  1. undercodetesting.com
  2. github.com/terraform-aws-modules/terraform-aws-eks
  3. github.com/cloudposse/terraform-aws-eks-fargate-profile
  4. dev.to/rmendoza
  5. dev.to/anadimisra

Related Posts