Terraform script to Launch EKS cluster using eksctl

Harshit Sinha
3 min readMar 11, 2021

This heading might be confusing to some but this article will do as it says.

Why is there a need to for an EKS cluster with eksctl?

In my use case my service needed access to some AW services, which can only be granted via AWS IAM, for that we need to setup identity federation by first creating an OIDC connector between EKS and IAM then using eksctl commands create a Kubernetes service account which federated to use an AWS IAM policy this explained in more detail in my upcoming EFK in AWS story, but in short if you want to run eksctl commands you need have a CloudFormation created by “eksctl create cluster” command for your EKS cluster. So if you are managing your cluster with terraform there is now a way to achieve this so follow along this walkthrough

Pr-requisites

  1. Terraform version 0.13 or above
  2. eksctl cli installed with bin file/exe for window
  3. aws cli installed and configured

Terraform template for reusing VPC and subnet and launching EKS cluster

terraform {required_providers {eksctl = {source = "mumoshu/eksctl"version = ">= 0.3.14"}}}provider "eksctl" {}locals {iams = [{iamarn   = "arn:aws:iam::$accountid:role/$rolename" #add any roles you want to RBACusername = "$anyname"groups = ["system:masters"]},{iamarn   = "arn:aws:iam::$accountid:user/$iam" #add any user arn if you wantusername = "$anyname"groups = ["system:masters"]},]}resource "eksctl_cluster" "main" {eksctl_bin = "eksctl.exe" #iam using windows and stored my executable in the terraform directory name = var.eks_cluster_nameregion = "$region"version = "1.18"spec = <<-EOSvpc:#    cidr: var.vpc_cidr       # {optional, must match CIDR used by the given VPC}subnets:# must provide 'private' and/or 'public' subnets by availability zone as shownprivate:var.aznameofsubnet1:id: ${var.private_subnet1}#cidr: var.private_subnet1_cidr # {optional, must match CIDR used by the given subnet}var.aznameofsubnet2:id: ${var.private_subnet2}#cidr: var.private_subnet2_cidr # {optional, must match CIDR used by the given subnet}var.aznameofsubnet3:id: ${var.private_subnet3}#cidr: var.private_subnet3_cidr # {optional, must match CIDR used by the given subnet}public:var.aznameofsubnet1:id: ${var.public_subnet1}#cidr: var.public_subnet1_cidr # {optional, must match CIDR used by the given subnet}var.aznameofsubnet2:id: ${var.public_subnet2}#cidr: var.public_subnet2_cidr # {optional, must match CIDR used by the given subnet}var.aznameofsubnet3:id: ${var.public_subnet3}#cidr: var.public_subnet3_cidr # {optional, must match CIDR used by the given subnet}iam:withOIDC: trueserviceAccounts: []EOSdynamic "iam_identity_mapping" {for_each = local.iamscontent {iamarn   = iam_identity_mapping.value["iamarn"]username = iam_identity_mapping.value["username"]groups   = iam_identity_mapping.value["groups"]}}}

This will create the cluster but It won’t create the node groups they can be added separately I haven’t added those here as my CloudFormation would fail and rollback waiting for the signal of ec2 instance.

This will solve the problem to run eksctl command in a terraform managed eksctl cluster more info can be found the GitHub repository here.

--

--

Harshit Sinha

Forever learner of Kuberentes, devops and everything cloud