Skip to content

FriendsOfTerraform/aws-eks

Repository files navigation

Elastic Kubernetes Service Module

This module will build and configure an EKS cluster with additional node pools

This repository is a READ-ONLY sub-tree split. See https://github.com/FriendsOfTerraform/modules to create issues or submit pull requests.

Table of Contents

Example Usage

Basic Usage

This example creates an EKS cluster with a one node primary node pool. The public API endpoint for the cluster is disabled by default, we will still be assigning multiple public subnets where the load balancers will be deployed, however.

module "demo_eks_cluster" {
  source = "github.com/FriendsOfTerraform/aws-eks.git?ref=v1.1.0"

  name = "demo-eks"

  vpc_config = {
    subnet_ids = [
      "subnet-029fd1fxxxxxxxx", # public-us-east-1a
      "subnet-02d1ba8xxxxxxxx", # public-us-east-1b
      "subnet-0f8c5afxxxxxxxx", # public-us-east-1c
      "subnet-0e08038xxxxxxxx", # private-us-east-1a
      "subnet-09b6fc5xxxxxxxx", # private-us-east-1b
      "subnet-0c7b976xxxxxxxx"  # private-us-east-1c
    ]
  }

  node_groups = {
    # Manages multiple node groups
    # The key of the map will be the node group's name
    linux = {
      desired_instances = 1

      # worker nodes should only be deployed in private subnets
      subnet_ids = [
        "subnet-0e08038xxxxxxxx", # private-us-east-1a
        "subnet-09b6fc5xxxxxxxx", # private-us-east-1b
        "subnet-0c7b976xxxxxxxx"  # private-us-east-1c
      ]
    }
    windows = {
      desired_instances = 1
      ami_type          = "WINDOWS_CORE_2022_x86_64"

      # worker nodes should only be deployed in private subnets
      subnet_ids = [
        "subnet-0e08038xxxxxxxx", # private-us-east-1a
        "subnet-09b6fc5xxxxxxxx", # private-us-east-1b
        "subnet-0c7b976xxxxxxxx"  # private-us-east-1c
      ]
    }
  }
}

IAM Roles For Service Accounts

This example demonstrates how to enable IAM roles for services account, which allows you to associate an IAM role to a Kubernetes service account. Please refer to this documentation to learn how to establish the association from the Kubernetes end.

module "demo_eks_irsa" {
  source = "github.com/FriendsOfTerraform/aws-eks.git?ref=v1.1.0"

  name = "demo-eks-irsa"

  vpc_config = {
    subnet_ids = [
      "subnet-029fd1fxxxxxxxx", # public-us-east-1a
      "subnet-02d1ba8xxxxxxxx", # public-us-east-1b
      "subnet-0e08038xxxxxxxx", # private-us-east-1a
      "subnet-09b6fc5xxxxxxxx", # private-us-east-1b
    ]
  }

  service_account_to_iam_role_mappings = {
    # The key of the map specifies the Kubernetes <namespace>/<service account> to create an IAM role for
    # You can specify only the namespace name in the key to allow the IAM role to be used by all service accounts in the namespace
    # The IAM role will be attached to the list of IAM policies specified

    # Associate every service account in the `default` namespace to AmazonS3FullAccess policy
    default = ["arn:aws:iam::aws:policy/AmazonS3FullAccess"]

    # Associate the `my-sa` service account in the `my-ns` namespace to two policies
    "my-ns/my-sa" = [
      "arn:aws:iam::aws:policy/AmazonS3FullAccess",
      "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
    ]
  }
}

OIDC Identity Provider

This example configures an external OIDC identity provider for authenticating to the Kubernetes API server.

module "demo_eks_oidc" {
  source = "github.com/FriendsOfTerraform/aws-eks.git?ref=v1.1.0"

  name = "demo-eks-oidc"

  vpc_config = {
    subnet_ids = [
      "subnet-029fd1fxxxxxxxx", # public-us-east-1a
      "subnet-02d1ba8xxxxxxxx", # public-us-east-1b
      "subnet-0e08038xxxxxxxx", # private-us-east-1a
      "subnet-09b6fc5xxxxxxxx", # private-us-east-1b
    ]
  }

  eks_oidc_identity_provider = {
    client_id      = "65a083ca-4398-450e-8cc2-af19cee7a423"
    groups_claim   = "gid:_groups"
    issuer_url     = "https://login.microsoftonline.com/8d6fb1c6-f181-4af2-928e-1c1bd4d56b5e/v2.0"
    name           = "azure-ad"
    username_claim = "email"
  }
}

Add-Ons

This example demonstrates how to manage multiple EKS add-ons. Some add-on requires additional permissions granted using service account to IAM role, those are automatically created and configured for add-ons from AWS.

module "demo_eks_addon" {
  source = "github.com/FriendsOfTerraform/aws-eks.git?ref=v1.1.0"

  name = "demo-eks-addon"

  vpc_config = {
    subnet_ids = [
      "subnet-029fd1fxxxxxxxx", # public-us-east-1a
      "subnet-02d1ba8xxxxxxxx", # public-us-east-1b
      "subnet-0e08038xxxxxxxx", # private-us-east-1a
      "subnet-09b6fc5xxxxxxxx", # private-us-east-1b
    ]
  }

  add_ons = {
    aws-ebs-csi-driver = { version = "v1.19.0-eksbuild.2" }
    coredns            = { version = "v1.10.1-eksbuild.1" }
    kube-proxy         = { version = "v1.27.1-eksbuild.1" }
    vpc-cni            = { version = "v1.12.6-eksbuild.2" }
  }
}

Inputs

Required

TypeNameDefault Value
string name

The name of the Kubernetes cluster. All associated resources will also have their name prefixed with this value

Since: 1.0.0

map(object(NodeGroups)) node_groups

Map of worker node groups

Examples:

Since: 1.0.0

object(VpcConfig) vpc_config

VPC configuration for the EKS cluster

Since: 1.0.0

Optional

TypeNameDefault Value
map(object(AddOns)) add_ons {}

Configures multiple EKS add-ons.

You can get a list of add-on names by running this aws cli command:

aws eks describe-addon-versions | jq -r ".addons[] | .addonName"

Examples:

Since: 1.0.0

map(string) additional_tags {}

Additional tags for the Kubernetes cluster

Since: 1.0.0

map(string) additional_tags_all {}

Additional tags for all resources deployed with this module

Since: 1.0.0

list(string) apiserver_allowed_cidrs [ "0.0.0.0/0" ]

List of CIDR blocks that can access the Amazon EKS public API server endpoint

Since: 1.0.0

bool enable_apiserver_public_endpoint false

Enables the EKS public endpoint. Cluster internal traffic will still be private

Since: 1.0.0

list(string) enable_cluster_log_types [ "api", "audit", "authenticator", "controllerManager", "scheduler" ]

List of the desired control plane logging types to enable

Links:

Since: 1.0.0

object(EnvelopeEncryption) envelope_encryption null

Configures envelope encryption for Kubernetes secrets

Since: 1.0.0

object(KubernetesNetworkingConfig) kubernetes_networking_config null

Configures various Kubernetes networking options

Since: 1.0.0

string kubernetes_version null

Desired Kubernetes master version. Defaults to latest version if null

Links:

Since: 1.0.0

object(OidcIdentityProvider) oidc_identity_provider null

Set up an EKS OIDC identity provider for authenticating to the Kubernetes API server

Examples:

Since: 1.0.0

map(list(string)) service_account_to_iam_role_mappings {}

Enables and creates the components needed for IAM roles for service accounts, then map a Kubernetes Namespace/ServiceAccount to a list of IAM policies. You can map the entire namespace to a role by omitting <service_account>.

Examples:

Since: 1.0.0

Objects

AddOns

TypeNameDefault Value
map(string) additional_tags {}

Additional tags for the add-on

Since: 1.0.0

string configuration null

Custom configuration values for add-ons with single JSON string. You can use the describe-addon-configuration call to find the correct JSON schema for each add-on. For example:

aws eks describe-addon-configuration --addon-name vpc-cni --addon-version v1.12.6-eksbuild.2

Since: 1.0.0

string iam_role_arn null

The arn of an existing IAM role to bind to the add-on's service account. The role must be assigned the IAM permissions required by the add-on. If you don't specify an existing IAM role, an IAM role will be created automatically for supported add-ons (see below), otherwise the add-on uses the permissions assigned to the node IAM role.

Supported add-ons: vpc-cni, aws-ebs-csi-driver, and adot

Since: 1.0.0

bool preserve false

Indicates if you want to preserve the created resources when deleting the EKS add-on

Since: 1.0.0

string resolve_conflicts_on_create "NONE"

How to resolve field value conflicts when migrating a self-managed add-on to an Amazon EKS add-on

Allowed Values:

  • NONE
  • OVERWRITE

Since: 1.0.0

string resolve_conflicts_on_update "NONE"

How to resolve field value conflicts for an Amazon EKS add-on if you've changed a value from the Amazon EKS default value

Allowed Values:

  • NONE
  • OVERWRITE

Since: 1.0.0

string version null

The version of the EKS add-on. Defaults to the latest version if null

You can get a list of add-on and their latest version with this command:

aws eks describe-addon-versions --kubernetes-version 1.27 | jq -r ".addons[] | .addonName, .addonVersions[0].addonVersion"

Since: 1.0.0

EnvelopeEncryption

TypeNameDefault Value
string kms_key_arn

ARN of the Key Management Service (KMS) customer master key (CMK) for encryption. The CMK must be symmetric, created in the same region as the cluster, and if the CMK was created in a different account, the user must have access to the CMK

Since: 1.0.0

KubernetesNetworkingConfig

TypeNameDefault Value
string kubernetes_service_address_range null

The CIDR block to assign Kubernetes pod and service IP addresses from. If you don't specify a block, Kubernetes assigns addresses from either the 10.100.0.0/16 or 172.20.0.0/16 CIDR blocks. The block must meet the following requirements:

  • Within one of the following private IP address blocks: "10.0.0.0/8", "172.16.0.0/12", or "192.168.0.0/16"
  • Doesn't overlap with any CIDR block assigned to the VPC that you selected for VPC
  • Between /24 and /12

Since: 1.0.0

string ip_family "ipv4"

The IP family used to assign Kubernetes pod and service addresses

Allowed Values:

  • ipv4
  • ipv6

Since: 1.0.0

NodeGroups

TypeNameDefault Value
number desired_instances

Number of desired worker nodes

Since: 1.0.0

list(string) subnet_ids

List of subnet IDs where the nodes will be deployed on. In addition, you must ensure that the subnets are tagged with the following values in order for a load balancer service to deployed successfully.

Public subnets: kubernetes.io/role/elb = 1 Private subnets: kubernetes.io/role/internal-elb = 1

Links:

Since: 1.0.0

map(string) additional_tags {}

Additional tags for the node group

Since: 1.0.0

string ami_type "AL2_x86_64"

Type of Amazon Machine Image (AMI) associated with the EKS Node Group

Allowed Values:

  • AL2_x86_64
  • AL2_x86_64_GPU
  • AL2_ARM_64
  • CUSTOM
  • BOTTLEROCKET_ARM_64
  • BOTTLEROCKET_x86_64
  • BOTTLEROCKET_ARM_64_FIPS
  • BOTTLEROCKET_x86_64_FIPS
  • BOTTLEROCKET_ARM_64_NVIDIA
  • BOTTLEROCKET_x86_64_NVIDIA
  • WINDOWS_CORE_2019_x86_64
  • WINDOWS_FULL_2019_x86_64
  • WINDOWS_CORE_2022_x86_64
  • WINDOWS_FULL_2022_x86_64
  • AL2023_x86_64_STANDARD
  • AL2023_ARM_64_STANDARD
  • AL2023_x86_64_NEURON
  • AL2023_x86_64_NVIDIA
  • AL2023_ARM_64_NVIDIA

Links:

Since: 1.0.0

string ami_release_version null

AMI version of the EKS Node Group. Defaults to latest version for Kubernetes version.

Links:

Since: 1.0.0

string capacity_type "ON_DEMAND"

Type of capacity associated with the EKS Node Group

Allowed Values:

  • ON_DEMAND
  • SPOT

Since: 1.0.0

number disk_size 20

EBS size for the worker nodes in GB

Since: 1.0.0

bool ignores_pod_disruption_budget false

Force version update if existing pods are unable to be drained due to a pod disruption budget issue

Since: 1.0.0

string instance_type "t3.medium"

EC2 instance type for the worker nodes

Since: 1.0.0

map(string) kubernetes_labels {}

Map of Kubernetes labels for the nodes

Since: 1.0.0

map(string) kubernetes_taints {}

Map of Kubernetes taints for the nodes. In the following format: {key = value:effect}.

Allowed Values:

  • NO_EXECUTE
  • NO_SCHEDULE
  • PREFER_NO_SCHEDULE

Since: 1.0.0

string kubernetes_version null

Desired Kubernetes worker version. Defaults to latest version if null

Links:

Since: 1.0.0

number max_instances null

Number of maximum worker nodes this group can scale to. Defaults to desired_instances if unspecified

Since: 1.0.0

string max_unavailable_instances_during_update "1"

Desired max number of unavailable worker nodes during node group update This can be a whole number or a percentage (e.g., "50%")

Since: 1.0.0

number min_instances null

Number of minimum worker nodes this group can scale to. Defaults to desired_instances if unspecified

Since: 1.0.0

OidcIdentityProvider

TypeNameDefault Value
string client_id

Client ID for the OIDC provider

Since: 1.0.0

string groups_claim

The JWT claim that the provider will use to return groups. This is mapped to a Kubernetes group. You can optionally prepend a prefix to this claim by separating the prefix with a _. eg gid:_groups

Since: 1.0.0

string issuer_url

Issuer URL for the OIDC identity provider. This URL should point to the level below .well-known/openid-configuration and must be publicly accessible over the internet

Since: 1.0.0

string name

A friendly name for this identity provider

Since: 1.0.0

string username_claim

The JWT claim that the provider will use as the username. This is mapped to a Kubernetes user. You can optionally prepend a prefix to this claim by separating the prefix with a _. eg uid:_email

Since: 1.0.0

VpcConfig

TypeNameDefault Value
list(string) subnet_ids

List of subnet IDs. Must be in at least two different availability zones. Amazon EKS creates cross-account elastic network interfaces in these subnets to allow communication between your worker nodes and the Kubernetes control plane.

Links:

Since: 1.0.0

list(string) security_group_ids

List of security group IDs for the cross-account elastic network interfaces that Amazon EKS creates to use to allow communication between your worker nodes and the Kubernetes control plane

Since: 1.0.0

Outputs

  • (string) cluster_arn [since v1.0.0]

    The ARN of the EKS cluster

  • (string) cluster_certificate_authority [since v1.0.0]

    The public CA certificate (based64) of the EKS cluster

  • (string) cluster_endpoint_url [since v1.0.0]

    The endpoint URL of the EKS cluster

  • (string) cluster_name [since v1.1.0]

    The name of the EKS cluster

  • (string) cluster_role_arn [since v1.1.0]

    The ARN of the cluster IAM role

  • (map(string)) node_group_arns [since v1.0.0]

    Map of ARNs of all the node groups associated to this cluster

  • (string) node_role_arn [since v1.1.0]

    The ARN of the node IAM role

  • (string) aws_cli_connect_to_cluster_command [since v1.0.0]

    The AWS cli command to connect to the EKS cluster

Known Limitations

Editing Node Group Configuration

Because the EKS node group is deployed using EC2 auto scaling group, updating node groups' configuration after creation will result in the creation of a new auto scaling group, effectively replacing the entire node group. However, node group replacement follows the Kubernetes node termination procedure, where all workloads will be automatically moved to the next healthy node group if available.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages