Terraform script to Launch EKS cluster using eksctl
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
- Terraform version 0.13 or above
- eksctl cli installed with bin file/exe for window
- 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.