Skip to content

Module Structure

terraform-aws-arc-eks

All Contributors

Latest Release Last Updated Terraform GitHub Actions

Quality gate

Known Vulnerabilities

Overview

SourceFuse AWS Reference Architecture (ARC) Terraform module provisions a EKS (Elastic Kubernetes Service) cluster with support for multiple operational modes and integrations:

  • EKS Cluster Creation: Automates the setup of the EKS control plane and associated IAM roles, VPC configurations, and security groups.
  • EKS Auto Mode Support: Enables simplified node management with AWS-managed node groups and automatic provisioning.
  • Karpenter Installation: Optionally installs and configures Karpenter, a flexible autoscaler that dynamically launches compute based on pod requirements.
  • Fargate Support: Allows deployment of serverless workloads on AWS Fargate by creating the required Fargate profiles and IAM roles.

This module helps streamline EKS provisioning while offering flexibility in compute optionsβ€”ideal for both production and cost-optimized environments.

For more information about this repository and its usage, please see Terraform AWS ARC EKS Module Usage Guide.

arc_eks_hla

Usage

See examples directory for usage examples, including configurations for auto-mode, fargate-profile, karpenter, and nodegroup. Below is the example for a simple EKS cluster creation.

module "eks_cluster" {
  source                    = "sourcefuse/arc-eks/aws"
  version                   = "5.0.16"
  namespace                 = var.namespace
  environment               = var.environment
  kubernetes_version        = var.kubernetes_version
  name                      = "${var.namespace}-${var.environment}-cluster"
  vpc_config                = local.vpc_config
  access_config             = local.access_config
  enable_oidc_provider      = false
  envelope_encryption       = local.envelope_encryption
  kubernetes_network_config = local.kubernetes_network_config
}

Requirements

Name Version
terraform >= 1.6.0
aws >= 5.0.0
helm 2.12.1
kubernetes = 2.24.0
null >= 2.0
tls >= 3.1.0, != 4.0.0

Providers

Name Version
aws 5.94.1
helm 2.12.1
kubernetes 2.24.0
tls 4.0.6

Modules

Name Source Version
kms sourcefuse/arc-kms/aws 1.0.9

Resources

Name Type
aws_eks_access_entry.this resource
aws_eks_access_policy_association.this resource
aws_eks_addon.this resource
aws_eks_cluster.this resource
aws_eks_fargate_profile.this resource
aws_eks_node_group.this resource
aws_iam_instance_profile.karpenter_instance_profile resource
aws_iam_openid_connect_provider.this resource
aws_iam_policy.iam resource
aws_iam_policy.kms resource
aws_iam_role.auto resource
aws_iam_role.eks_fargate_profile resource
aws_iam_role.eks_node_group resource
aws_iam_role.karpenter_controller_role resource
aws_iam_role.karpenter_node_role resource
aws_iam_role.this resource
aws_iam_role_policy.karpenter_controller resource
aws_iam_role_policy_attachment.eks_cluster_policy resource
aws_iam_role_policy_attachment.fargate resource
aws_iam_role_policy_attachment.iam resource
aws_iam_role_policy_attachment.karpenter_node_policy_attachment resource
aws_iam_role_policy_attachment.kms resource
aws_iam_role_policy_attachment.node_AmazonEC2ContainerRegistryPullOnly resource
aws_iam_role_policy_attachment.node_polcies resource
aws_iam_role_policy_attachment.this resource
aws_security_group_rule.cluster_ingress_rules resource
helm_release.karpenter resource
kubernetes_config_map.aws_auth resource
kubernetes_config_map_v1_data.aws_auth resource
aws_caller_identity.current data source
aws_iam_policy_document.iam data source
tls_certificate.this data source

Inputs

Name Description Type Default Required
access_config Access configuration for the cluster.
- authentication_mode: One of "API" or "API_AND_CONFIG_MAP"
- bootstrap_cluster_creator_admin_permissions: Grant creator admin access
- aws_auth_config_map: (optional) Config for aws-auth ConfigMap
- eks_access_entries: (optional) List of principals and their policy associations
object({
authentication_mode = optional(string, "API")
bootstrap_cluster_creator_admin_permissions = optional(bool, false)

aws_auth_config_map = optional(object({
create = optional(bool, false)
manage = optional(bool, false)
roles = optional(list(any), [])
users = optional(list(any), [])
accounts = optional(list(string), [])
}), {})

eks_access_entries = optional(list(object({
principal_arn = optional(string)
policy_arns = optional(list(string))
access_scope = optional(object({
type = string
namespaces = optional(list(string))
}))
})), [])
})
{
"authentication_mode": "API",
"bootstrap_cluster_creator_admin_permissions": false
}
no
additional_cluster_security_group_rules List of ingress security group rules to apply to the EKS cluster security group
list(object({
from_port = number
to_port = number
protocol = string
cidr_blocks = optional(list(string), [])
ipv6_cidr_blocks = optional(list(string), [])
description = optional(string)
}))
[] no
additional_node_group_policy_arns Optional additional policies to attach to node group role list(string) [] no
auto_mode_config (optional) EKS automates routine cluster tasks for compute, storage, and networking.
When a new pod can't fit onto existing nodes, EKS creates a new node.
EKS combines cluster infrastructure managed by AWS with integrated Kubernetes capabilities to meet application compute needs.
object({
enable = optional(bool, false)
node_pools = optional(list(string), ["general-purpose", "system"])
node_role_arn = optional(string, null)
})
{
"enable": false
}
no
bootstrap_self_managed_addons_enabled (optional) Install default unmanaged add-ons, such as aws-cni, kube-proxy, and CoreDNS during cluster creation. If false, you must manually install desired add-ons. Changing this value will force a new cluster to be created. bool true no
eks_additional_policy_arns Optional additional policy ARNs that user wants to attach list(string) [] no
eks_addons Map of EKS Add-ons to create
map(object({
addon_version = optional(string)
service_account_role_arn = optional(string)
resolve_conflicts_on_update = optional(string)
resolve_conflicts_on_create = optional(string)
}))
{} no
eks_policy_arns List of IAM policy ARNs to attach to the EKS role list(string)
[
"arn:aws:iam::aws:policy/AmazonEKSClusterPolicy",
"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
"arn:aws:iam::aws:policy/AmazonEKSNetworkingPolicy",
"arn:aws:iam::aws:policy/AmazonEKSComputePolicy"
]
no
enable_arc_zonal_shift (optional) Whether to enable ARC Zonal shift , it shift application traffic away from an impaired Availability Zone (AZ) in your EKS cluster. bool false no
enable_oidc_provider Whether to enable OIDC provider bool true no
enabled_cluster_log_types A list of the desired control plane logging to enable. Valid values [api, audit, authenticator, controllerManager, scheduler] list(string) [] no
envelope_encryption Whether to enable Envelope encryption
object({
enable = optional(bool, true)
kms_deletion_window_in_days = optional(number, 10)
resources = optional(list(string), ["secrets"])
key_arn = optional(string, null) // if null it created new KMS key
})
{
"enable": true,
"resources": [
"secrets"
]
}
no
environment ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' string n/a yes
fargate_profile_config Combined configuration for the EKS Fargate profile, including IAM policies.
object({
enable = bool
fargate_profile_name = optional(string)
pod_execution_role_arn = optional(string)
subnet_ids = optional(list(string))
selectors = optional(list(object({
namespace = string
labels = optional(map(string))
})))
tags = optional(map(string), {})
policy_arns = optional(list(string), ["arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy"])
additional_policy_arns = optional(list(string), [])
})
{
"enable": false
}
no
karpenter_config Configuration for Karpenter
object({
enable = bool
name = optional(string)
namespace = optional(string, "karpenter")
create_namespace = optional(bool)
version = optional(string, "0.36.0")
helm_repository = optional(string, "oci://public.ecr.aws/karpenter")
chart = optional(string)
additional_karpenter_node_role_policies = optional(list(string), [])
helm_release_values = optional(any)
helm_release_set_values = optional(list(object({
name = string
value = string
})), [])
})
{
"enable": false
}
no
kubernetes_network_config Configuration block for Kubernetes network.

- service_ipv4_cidr: Optional custom CIDR block for Kubernetes service IPs. Must be within 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16 and have a netmask between /12 and /24.
- ip_family: The IP family to assign (ipv4 or ipv6). Default is ipv4.
object({
ipv4_cidr = optional(string, null)
ip_family = optional(string, "ipv4")
})
{
"ip_family": "ipv4"
}
no
kubernetes_version Desired Kubernetes master version string n/a yes
name EKS Cluster name string n/a yes
namespace Namespace your resource belongs to.
Usually an abbreviation of your organization name, e.g. 'example' or 'arc', to help ensure generated IDs are globally unique"
string n/a yes
node_group_config Configuration for EKS managed node groups.

- enable: Controls whether EKS node groups should be created.
- config: A map of node group configurations, where each key is an identifier for a node group.
Each node group object may include:

- node_group_name: (Optional) Custom name for the node group. If not specified, a default will be used.
- node_role_arn: (Optional) ARN of the IAM role for the node group.
- release_version: (Optional) AMI version for the node group.
- scaling_config: Required settings for desired, minimum, and maximum node counts.
- taints: (Optional) List of taints applied to nodes, each with a key, value (optional), and effect.
- update_config: (Optional) Configuration for rolling updates, such as max unavailable nodes.
- remote_access: (Optional) SSH access configuration, including key name and allowed source security group IDs.
- launch_template: (Optional) Launch template settings, including ID, name, and version.
- node_repair_config: (Optional) Node auto-repair configuration (e.g., self-healing).
- instance_types: (Optional) List of EC2 instance types to use (default is ["t3.medium"]).
- ami_type: (Optional) AMI type (e.g., "AL2_x86_64", "BOTTLEROCKET_x86_64").
- disk_size: (Optional) Size in GiB of the root EBS volume.
- capacity_type: (Optional) Capacity type ("ON_DEMAND" or "SPOT"), defaults to "ON_DEMAND".
- labels: (Optional) Key-value map of Kubernetes labels to apply to the nodes.
- ignore_desired_size: (Optional) If true, the desired size will be ignored during updates (default: false).
- subnet_ids: Required list of subnet IDs where the node group will be deployed.
- kubernetes_version: (Optional) Kubernetes version to use for the node group.
object({
enable = bool
config = map(object({
node_group_name = optional(string)
node_role_arn = optional(string)
release_version = optional(string)
scaling_config = object({
desired_size = number
max_size = number
min_size = number
})
taints = optional(list(object({
key = string
value = optional(string)
effect = string
})), [])
update_config = optional(object({
max_unavailable = optional(number)
max_unavailable_percentage = optional(number)
}))
remote_access = optional(object({
ec2_ssh_key = string
source_security_group_ids = list(string)
}))
launch_template = optional(object({
id = optional(string)
name = optional(string)
version = string
}))
node_repair_config = optional(object({
enabled = bool
}))
instance_types = optional(list(string), ["t3.medium"])
ami_type = optional(string)
disk_size = optional(number)
capacity_type = optional(string, "ON_DEMAND")
labels = optional(map(string), {})
ignore_desired_size = optional(bool, false)
subnet_ids = list(string)
kubernetes_version = optional(string)
}))
})
{
"config": {},
"enable": false
}
no
node_group_policy_arns Default policies for EKS node group list(string)
[
"arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
"arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
]
no
tags Tags for EKS resources map(string) {} no
upgrade_policy (optional) Support type to use for the cluster. If the cluster is set to EXTENDED, it will enter extended support at the end of standard support.
If the cluster is set to STANDARD, it will be automatically upgraded at the end of standard support.
Valid values are EXTENDED, STANDARD"

STANDARD - This option supports the Kubernetes version for 14 months after the release date. There is no additional cost. When standard support ends, your cluster will be auto upgraded to the next version.
EXTENDED - This option supports the Kubernetes version for 26 months after the release date. The extended support period has an additional hourly cost that begins after the standard support period ends. When extended support ends, your cluster will be auto upgraded to the next version.
string "STANDARD" no
vpc_config Configuration block for VPC settings:
- security_group_ids: List of security group IDs associated with the VPC.
- subnet_ids: List of subnet IDs where resources will be deployed.
- endpoint_private_access: Enable or disable private access to the cluster endpoint.
- endpoint_public_access: Enable or disable public access to the cluster endpoint.
- public_access_cidrs: CIDR blocks that can access the public endpoint (if enabled).
object({
security_group_ids = optional(list(string), [])
subnet_ids = list(string)
endpoint_private_access = optional(bool, false)
endpoint_public_access = optional(bool, true)
public_access_cidrs = optional(list(string), ["0.0.0.0/0"])
})
n/a yes

Outputs

Name Description
arn The Amazon Resource Name (ARN) of the EKS cluster
certificate_authority_data The base64-encoded certificate data required to communicate with the EKS cluster
eks_cluster_id The unique identifier of the EKS cluster
eks_cluster_security_group_id The ID of the security group associated with the EKS cluster's control plane
endpoint The endpoint for the EKS cluster API server
name The name of the EKS cluster
oidc_provider_url The OIDC identity provider URL for the EKS cluster (without the https:// prefix)

Kubernetes dashboard

To view the dashboard, run the following commands:

1
2
3
aws eks update-kubeconfig --name refarch-dev-primary-k8s-cluster --region us-east-1
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep eks-dashboard-viewer | awk '{print $1}') #Copy the token from the output
kubectl proxy

Then navigate to:

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login

and use the copied token to login

Development

Prerequisites

Configurations

  • Configure pre-commit hooks
    pre-commit install
    
  • Configure golang deps for tests
    > go get github.com/gruntwork-io/terratest/modules/terraform
    > go get github.com/stretchr/testify/assert
    

Git commits

while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch

For Example

git commit -m "your commit message #major"
By specifying this , it will bump the version and if you dont specify this in your commit message then by default it will consider patch and will bump that accordingly

Tests

  • Tests are available in test directory
  • In the test directory, run the below command
    go test
    

Authors

This project is authored by below people

  • SourceFuse ARC Team

Contributors ✨

Thanks goes to these wonderful people (emoji key):

vijay-stephen
vijay-stephen

πŸ’» πŸš‡ πŸ“– 🚧 πŸ§‘β€πŸ«
Shubham Sinha
Shubham Sinha

πŸ’» πŸš‡ πŸ“– 🚧 πŸ§‘β€πŸ«
Travis Saucier
Travis Saucier

πŸ’» πŸš‡ πŸ“– 🚧 πŸ§‘β€πŸ«
Mayank Sharma
Mayank Sharma

πŸ’» πŸš‡ πŸ“– 🚧 πŸ§‘β€πŸ«

This project follows the all-contributors specification. Contributions of any kind welcome!