Resource: aws_eks_cluster

Manages an EKS Cluster.

Hands-on: For an example of aws_eks_cluster in use, follow the Provision an EKS Cluster tutorial on HashiCorp Learn.

Example Usage

Basic Usage

resource "aws_eks_cluster" "example" {
  name     = "example"
  role_arn = aws_iam_role.example.arn

  vpc_config {
    subnet_ids = [aws_subnet.example1.id, aws_subnet.example2.id]
  }

  # Ensure that IAM Role permissions are created before and deleted after EKS Cluster handling.
  # Otherwise, EKS will not be able to properly delete EKS managed EC2 infrastructure such as Security Groups.
  depends_on = [
    aws_iam_role_policy_attachment.example-AmazonEKSClusterPolicy,
    aws_iam_role_policy_attachment.example-AmazonEKSVPCResourceController,
  ]
}

output "endpoint" {
  value = aws_eks_cluster.example.endpoint
}

output "kubeconfig-certificate-authority-data" {
  value = aws_eks_cluster.example.certificate_authority[0].data
}

Example IAM Role for EKS Cluster

data "aws_iam_policy_document" "assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["eks.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "example" {
  name               = "eks-cluster-example"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

resource "aws_iam_role_policy_attachment" "example-AmazonEKSClusterPolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
  role       = aws_iam_role.example.name
}

# Optionally, enable Security Groups for Pods
# Reference: https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html
resource "aws_iam_role_policy_attachment" "example-AmazonEKSVPCResourceController" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
  role       = aws_iam_role.example.name
}

Enabling Control Plane Logging

EKS Control Plane Logging can be enabled via the enabled_cluster_log_types argument. To manage the CloudWatch Log Group retention period, the aws_cloudwatch_log_group resource can be used.

variable "cluster_name" {
  default = "example"
  type    = string
}

resource "aws_eks_cluster" "example" {
  depends_on = [aws_cloudwatch_log_group.example]

  enabled_cluster_log_types = ["api", "audit"]
  name                      = var.cluster_name

  # ... other configuration ...
}

resource "aws_cloudwatch_log_group" "example" {
  # The log group name format is /aws/eks/<cluster-name>/cluster
  # Reference: https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html
  name              = "/aws/eks/${var.cluster_name}/cluster"
  retention_in_days = 7

  # ... potentially other configuration ...
}

Enabling IAM Roles for Service Accounts

Only available on Kubernetes version 1.13 and 1.14 clusters created or upgraded on or after September 3, 2019. For more information about this feature, see the EKS User Guide.

resource "aws_eks_cluster" "example" {
  # ... other configuration ...
}

data "tls_certificate" "example" {
  url = aws_eks_cluster.example.identity[0].oidc[0].issuer
}

resource "aws_iam_openid_connect_provider" "example" {
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.example.certificates[0].sha1_fingerprint]
  url             = data.tls_certificate.example.url
}

data "aws_iam_policy_document" "example_assume_role_policy" {
  statement {
    actions = ["sts:AssumeRoleWithWebIdentity"]
    effect  = "Allow"

    condition {
      test     = "StringEquals"
      variable = "${replace(aws_iam_openid_connect_provider.example.url, "https://", "")}:sub"
      values   = ["system:serviceaccount:kube-system:aws-node"]
    }

    principals {
      identifiers = [aws_iam_openid_connect_provider.example.arn]
      type        = "Federated"
    }
  }
}

resource "aws_iam_role" "example" {
  assume_role_policy = data.aws_iam_policy_document.example_assume_role_policy.json
  name               = "example"
}

EKS Cluster on AWS Outpost

Creating a local Amazon EKS cluster on an AWS Outpost

resource "aws_iam_role" "example" {
  assume_role_policy = data.aws_iam_policy_document.example_assume_role_policy.json
  name               = "example"
}

resource "aws_eks_cluster" "example" {
  name     = "example-cluster"
  role_arn = aws_iam_role.example.arn

  vpc_config {
    endpoint_private_access = true
    endpoint_public_access  = false
    # ... other configuration ...
  }

  outpost_config {
    control_plane_instance_type = "m5d.large"
    outpost_arns                = [data.aws_outposts_outpost.example.arn]
  }
}

EKS Cluster with Access Config

resource "aws_iam_role" "example" {
  assume_role_policy = data.aws_iam_policy_document.example_assume_role_policy.json
  name               = "example"
}

resource "aws_eks_cluster" "example" {
  name     = "example-cluster"
  role_arn = aws_iam_role.example.arn

  vpc_config {
    endpoint_private_access = true
    endpoint_public_access  = false
    # ... other configuration ...
  }

  access_config {
    authentication_mode                         = "CONFIG_MAP"
    bootstrap_cluster_creator_admin_permissions = true
  }
}

After adding inline IAM Policies (e.g., aws_iam_role_policy resource) or attaching IAM Policies (e.g., aws_iam_policy resource and aws_iam_role_policy_attachment resource) with the desired permissions to the IAM Role, annotate the Kubernetes service account (e.g., kubernetes_service_account resource) and recreate any pods.

Argument Reference

The following arguments are required:

The following arguments are optional:

access_config

The access_config configuration block supports the following arguments:

encryption_config

The encryption_config configuration block supports the following arguments:

provider

The provider configuration block supports the following arguments:

vpc_config Arguments

kubernetes_network_config

The kubernetes_network_config configuration block supports the following arguments:

outpost_config

The outpost_config configuration block supports the following arguments:

Attribute Reference

This resource exports the following attributes in addition to the arguments above:

certificate_authority

identity

oidc

vpc_config Attributes

Timeouts

Configuration options:

Import

In Terraform v1.5.0 and later, use an import block to import EKS Clusters using the name. For example:

import {
  to = aws_eks_cluster.my_cluster
  id = "my_cluster"
}

Using terraform import, import EKS Clusters using the name. For example:

% terraform import aws_eks_cluster.my_cluster my_cluster