An open API service indexing awesome lists of open source software.

https://github.com/native-cube/terraform-aws-eks-auto


https://github.com/native-cube/terraform-aws-eks-auto

Last synced: 11 days ago
JSON representation

Awesome Lists containing this project

README

          

# Terraform AWS EKS Auto Mode Module

Terraform module for creating an Amazon EKS cluster with EKS Auto Mode enabled by default:

- EKS control plane IAM role with EKS Auto Mode policies.
- Optional module-created EKS Auto Mode node IAM role.
- EKS Auto Mode managed compute with configurable built-in node pools.
- EKS Auto Mode load balancing and block storage switches.
- Rendered Kubernetes manifests for custom Auto Mode NodeClasses, NodePools, StorageClasses, and LoadBalancer Services.
- Optional EKS Pod Identity associations.
- Optional EKS access entries and access policy associations.
- Optional Amazon EKS managed capabilities: Argo CD, ACK, and KRO.
- Useful connection and composition outputs.

The module expects you to provide existing subnet IDs. In most deployments these should be private subnets with outbound internet access through NAT.
The Kubernetes API endpoint is private by default; enable public endpoint access only when callers outside the VPC need it.

## Usage

```hcl
module "eks_auto" {
source = "./eks-auto"

name = "dev-auto"
subnet_ids = ["subnet-0123456789abcdef0", "subnet-0fedcba9876543210"]

tags = {
Environment = "dev"
}
}
```

Then configure `kubectl`:

```bash
aws eks update-kubeconfig --name dev-auto
```

## Examples

- `examples/minimal` - smallest practical EKS Auto Mode module call using defaults for compute, API access, logging, load balancing, and block storage.
- `examples/capabilities` - EKS Auto Mode with all supported EKS capabilities: Argo CD, ACK, and KRO.
- `examples/storage` - custom Auto Mode NodeClass, NodePool, and encrypted gp3 StorageClass manifests.
- `examples/load-balancing` - Pod Identity and an EKS Auto Mode Network Load Balancer Service manifest.

## EKS Auto Mode

By default, this module sets:

- `endpoint_private_access = true`
- `endpoint_public_access = false`
- `bootstrap_self_managed_addons = false`
- `compute_config.enabled = true`
- `compute_config.node_pools = ["general-purpose", "system"]`
- `elastic_load_balancing_enabled = true`
- `block_storage_enabled = true`
- `access_config.authentication_mode = "API"`

The module can create the Auto Mode node IAM role, or callers can pass an existing node role ARN through `compute_config.node_iam_role_arn`.

## Rendered Kubernetes Manifests

This module does not introduce a Kubernetes provider. Instead, it can render Auto Mode Kubernetes manifests as outputs:

- `auto_mode_node_classes`
- `auto_mode_node_pools`
- `auto_mode_storage_classes`
- `auto_mode_load_balancer_services`

Apply the combined YAML after the cluster is reachable:

```bash
terraform output -raw auto_mode_kubernetes_manifest_yaml | kubectl apply -f -
```

## Pod Identity

Use `pod_identity_associations` to create AWS-native EKS Pod Identity associations. The module can create one IAM role per association, attach managed policies or inline JSON, and associate it with a Kubernetes service account.

## EKS Capabilities

Enable the `capabilities` map when this module should create Amazon EKS managed capabilities. Supported types are `ARGOCD`, `ACK`, and `KRO`.

```hcl
capabilities = {
argocd = {
type = "ARGOCD"
argocd = {
idc_instance_arn = "arn:aws:sso:::instance/ssoins-7223a1b234567890"
namespace = "argocd"
}
}

ack = {
type = "ACK"
}

kro = {
type = "KRO"
}
}
```

For `ARGOCD`, configure the nested `argocd` object with IAM Identity Center settings, optional RBAC role mappings, and optional VPC endpoint IDs. Attach managed policies or an inline policy to a capability role only when that capability needs access to supporting AWS services.
Capability role presets are available through `iam_policy_presets`: `cloudcontrol_read_only`, `eks_read_only`, `resource_tagging`, and `secrets_read_only`.

## Module Documentation

## Requirements

| Name | Version |
| ---- | ------- |
| [terraform](#requirement\_terraform) | >= 1.5.0 |
| [aws](#requirement\_aws) | >= 6.0 |

## Providers

| Name | Version |
| ---- | ------- |
| [aws](#provider\_aws) | >= 6.0 |

## Resources

| Name | Type |
| ---- | ---- |
| [aws_cloudwatch_log_group.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_eks_access_entry.auto_mode_node_class](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource |
| [aws_eks_access_entry.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource |
| [aws_eks_access_policy_association.auto_mode_node_class](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_policy_association) | resource |
| [aws_eks_access_policy_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_policy_association) | resource |
| [aws_eks_capability.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_capability) | resource |
| [aws_eks_cluster.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_cluster) | resource |
| [aws_eks_pod_identity_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_pod_identity_association) | resource |
| [aws_iam_role.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.eks_capability](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.node](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.pod_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.eks_capability](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy.eks_capability_preset](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy.pod_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_role_policy_attachment.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.eks_capability](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.node](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.pod_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |

## Inputs

| Name | Description | Type | Default | Required |
| ---- | ----------- | ---- | ------- | :------: |
| [access\_config](#input\_access\_config) | Optional EKS access configuration. EKS Auto Mode uses access entries, so authentication mode defaults to API. |

object({
authentication_mode = optional(string)
bootstrap_cluster_creator_admin_permissions = optional(bool)
})
| `null` | no |
| [access\_entries](#input\_access\_entries) | Additional EKS access entries and optional access policy associations to create. |
map(object({
kubernetes_groups = optional(set(string), [])
policy_associations = optional(map(object({
access_scope = object({
namespaces = optional(set(string), [])
type = string
})
policy_arn = string
})), {})
principal_arn = string
type = optional(string, "STANDARD")
user_name = optional(string)
}))
| `{}` | no |
| [auto\_mode\_load\_balancer\_services](#input\_auto\_mode\_load\_balancer\_services) | EKS Auto Mode Network Load Balancer Service manifests to render as YAML, keyed by Kubernetes metadata.name. |
map(object({
annotations = optional(map(string), {})
external_traffic_policy = optional(string)
ip_families = optional(list(string), [])
ip_family_policy = optional(string)
labels = optional(map(string), {})
load_balancer_class = optional(string, "eks.amazonaws.com/nlb")
load_balancer_source_ranges = optional(list(string), [])
namespace = optional(string, "default")
ports = list(any)
selector = map(string)
session_affinity = optional(string)
}))
| `{}` | no |
| [auto\_mode\_node\_classes](#input\_auto\_mode\_node\_classes) | Custom EKS Auto Mode NodeClass manifests to render as YAML, keyed by Kubernetes metadata.name. The module does not apply these manifests because it intentionally avoids adding a Kubernetes provider. |
map(object({
annotations = optional(map(string), {})
create_access_entry = optional(bool, true)
labels = optional(map(string), {})
node_role_arn = optional(string)
spec = any
}))
| `{}` | no |
| [auto\_mode\_node\_pools](#input\_auto\_mode\_node\_pools) | Custom EKS Auto Mode NodePool manifests to render as YAML, keyed by Kubernetes metadata.name. The module does not apply these manifests because it intentionally avoids adding a Kubernetes provider. |
map(object({
annotations = optional(map(string), {})
labels = optional(map(string), {})
spec = any
}))
| `{}` | no |
| [auto\_mode\_storage\_classes](#input\_auto\_mode\_storage\_classes) | EKS Auto Mode EBS StorageClass manifests to render as YAML, keyed by Kubernetes metadata.name. |
map(object({
allow_volume_expansion = optional(bool, true)
allowed_topologies = optional(list(any), [])
annotations = optional(map(string), {})
labels = optional(map(string), {})
mount_options = optional(list(string), [])
parameters = optional(map(string), {})
reclaim_policy = optional(string, "Delete")
volume_binding_mode = optional(string, "WaitForFirstConsumer")
}))
| `{}` | no |
| [block\_storage\_enabled](#input\_block\_storage\_enabled) | Whether to enable EKS Auto Mode block storage support. | `bool` | `true` | no |
| [bootstrap\_self\_managed\_addons](#input\_bootstrap\_self\_managed\_addons) | Whether EKS bootstraps the default self-managed networking add-ons. Keep false for EKS Auto Mode. | `bool` | `false` | no |
| [capabilities](#input\_capabilities) | Amazon EKS managed capabilities to create, keyed by a stable local name. Supported types are ARGOCD, ACK, and KRO. The module can create a capability IAM role per entry, or use an externally managed role ARN. |
map(object({
capability_name = optional(string)
create_iam_role = optional(bool, true)
delete_propagation_policy = optional(string, "RETAIN")
iam_policy_arns = optional(set(string), [])
iam_policy_presets = optional(set(string), [])
iam_role_arn = optional(string)
iam_role_name = optional(string)
inline_policy_json = optional(string)
type = string
argocd = optional(object({
idc_instance_arn = optional(string)
idc_region = optional(string)
namespace = optional(string)
network_access_vpce_ids = optional(set(string), [])
rbac_role_mappings = optional(list(object({
role = string
identities = list(object({
id = string
type = string
}))
})), [])
}))
}))
| `{}` | no |
| [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | Optional KMS key ID or ARN for encrypting the EKS control plane CloudWatch log group. | `string` | `null` | no |
| [cloudwatch\_log\_retention\_days](#input\_cloudwatch\_log\_retention\_days) | Retention in days for the EKS control plane CloudWatch log group. | `number` | `30` | no |
| [cluster\_encryption\_config](#input\_cluster\_encryption\_config) | Optional EKS encryption configuration for Kubernetes secrets using an existing KMS key. |
object({
provider_key_arn = string
resources = optional(set(string), ["secrets"])
})
| `null` | no |
| [cluster\_name](#input\_cluster\_name) | Optional EKS cluster name. When null, name is used as the cluster name. | `string` | `null` | no |
| [cluster\_security\_group\_ids](#input\_cluster\_security\_group\_ids) | Additional security group IDs to associate with the EKS control plane. | `list(string)` | `[]` | no |
| [compute\_config](#input\_compute\_config) | EKS Auto Mode compute configuration. When enabled, the module can create the Auto Mode node IAM role and pass it to the cluster. |
object({
create_node_iam_role = optional(bool, true)
enabled = optional(bool, true)
node_iam_policy_arns = optional(set(string), [])
node_iam_role_arn = optional(string)
node_iam_role_name = optional(string)
node_pools = optional(set(string), ["general-purpose", "system"])
})
| `{}` | no |
| [control\_plane\_scaling\_tier](#input\_control\_plane\_scaling\_tier) | Optional EKS control plane scaling tier. Leave null to use the AWS/provider default. | `string` | `null` | no |
| [deletion\_protection](#input\_deletion\_protection) | Whether to enable deletion protection for the EKS cluster. Leave null to use the AWS/provider default. | `bool` | `null` | no |
| [elastic\_load\_balancing\_enabled](#input\_elastic\_load\_balancing\_enabled) | Whether to enable EKS Auto Mode load balancing support. | `bool` | `true` | no |
| [enabled\_cluster\_log\_types](#input\_enabled\_cluster\_log\_types) | EKS control plane log types to enable. | `list(string)` |
[
"api",
"audit",
"authenticator"
]
| no |
| [endpoint\_private\_access](#input\_endpoint\_private\_access) | Whether the Kubernetes API server endpoint is reachable from within the VPC. | `bool` | `true` | no |
| [endpoint\_public\_access](#input\_endpoint\_public\_access) | Whether the Kubernetes API server endpoint is reachable from the public internet. | `bool` | `false` | no |
| [force\_update\_version](#input\_force\_update\_version) | Whether to force version updates when EKS cannot drain pods. | `bool` | `null` | no |
| [ip\_family](#input\_ip\_family) | Optional Kubernetes service IP family. Valid values are ipv4 or ipv6. | `string` | `null` | no |
| [kubernetes\_version](#input\_kubernetes\_version) | Kubernetes version for the EKS cluster. Leave null to use the current AWS default. | `string` | `null` | no |
| [name](#input\_name) | Name prefix for module-created resources. Used as the EKS cluster name when cluster\_name is null. | `string` | n/a | yes |
| [pod\_identity\_associations](#input\_pod\_identity\_associations) | EKS Pod Identity associations to create for Kubernetes service accounts. The module can create the IAM role per association, or use an externally managed role ARN. |
map(object({
create_iam_role = optional(bool, true)
disable_session_tags = optional(bool)
iam_policy_arns = optional(set(string), [])
iam_role_arn = optional(string)
iam_role_name = optional(string)
inline_policy_json = optional(string)
namespace = string
service_account = string
tags = optional(map(string), {})
target_role_arn = optional(string)
}))
| `{}` | no |
| [public\_access\_cidrs](#input\_public\_access\_cidrs) | CIDR blocks that can access the public Kubernetes API endpoint when endpoint\_public\_access is true. Leave empty when the public endpoint is disabled. | `list(string)` | `[]` | no |
| [service\_ipv4\_cidr](#input\_service\_ipv4\_cidr) | Optional Kubernetes service IPv4 CIDR. Set only when you need a non-default service CIDR. | `string` | `null` | no |
| [subnet\_ids](#input\_subnet\_ids) | Subnet IDs for the EKS control plane and EKS Auto Mode managed compute. Use at least two subnets in different Availability Zones. | `list(string)` | n/a | yes |
| [tags](#input\_tags) | Tags to apply to created resources. | `map(string)` | `{}` | no |
| [upgrade\_policy\_support\_type](#input\_upgrade\_policy\_support\_type) | Optional Kubernetes version support policy. Valid values are STANDARD and EXTENDED. | `string` | `null` | no |

## Outputs

| Name | Description |
| ---- | ----------- |
| [access\_entry\_arns](#output\_access\_entry\_arns) | EKS access entry ARNs by access entry key. |
| [argocd\_idc\_managed\_application\_arns](#output\_argocd\_idc\_managed\_application\_arns) | IAM Identity Center managed application ARNs by ARGOCD capability key. |
| [argocd\_server\_urls](#output\_argocd\_server\_urls) | Managed Argo CD server URLs by ARGOCD capability key. |
| [auto\_mode\_kubernetes\_manifest\_yaml](#output\_auto\_mode\_kubernetes\_manifest\_yaml) | All rendered EKS Auto Mode Kubernetes manifests joined into a single multi-document YAML string. |
| [auto\_mode\_kubernetes\_manifests](#output\_auto\_mode\_kubernetes\_manifests) | All rendered EKS Auto Mode Kubernetes YAML manifests by kind/name. |
| [auto\_mode\_load\_balancer\_service\_manifests](#output\_auto\_mode\_load\_balancer\_service\_manifests) | Rendered EKS Auto Mode LoadBalancer Service YAML manifests by name. |
| [auto\_mode\_node\_class\_access\_entry\_arns](#output\_auto\_mode\_node\_class\_access\_entry\_arns) | EKS access entry ARNs created for custom Auto Mode NodeClass IAM roles. |
| [auto\_mode\_node\_class\_manifests](#output\_auto\_mode\_node\_class\_manifests) | Rendered EKS Auto Mode NodeClass YAML manifests by name. |
| [auto\_mode\_node\_iam\_role\_arn](#output\_auto\_mode\_node\_iam\_role\_arn) | IAM role ARN used by EKS Auto Mode managed compute when compute is enabled. |
| [auto\_mode\_node\_iam\_role\_name](#output\_auto\_mode\_node\_iam\_role\_name) | IAM role name used by EKS Auto Mode managed compute when compute is enabled. |
| [auto\_mode\_node\_pool\_manifests](#output\_auto\_mode\_node\_pool\_manifests) | Rendered EKS Auto Mode NodePool YAML manifests by name. |
| [auto\_mode\_storage\_class\_manifests](#output\_auto\_mode\_storage\_class\_manifests) | Rendered EKS Auto Mode StorageClass YAML manifests by name. |
| [capability\_arns](#output\_capability\_arns) | Amazon EKS capability ARNs by capability key. |
| [capability\_iam\_policy\_preset\_names](#output\_capability\_iam\_policy\_preset\_names) | Capability IAM policy preset names attached by capability key. |
| [capability\_iam\_role\_arns](#output\_capability\_iam\_role\_arns) | IAM role ARNs used by Amazon EKS capabilities by capability key. |
| [capability\_iam\_role\_names](#output\_capability\_iam\_role\_names) | IAM role names used by Amazon EKS capabilities by capability key. |
| [capability\_names](#output\_capability\_names) | Amazon EKS capability names by capability key. |
| [capability\_versions](#output\_capability\_versions) | Amazon EKS capability software versions by capability key. |
| [cluster\_arn](#output\_cluster\_arn) | EKS cluster ARN. |
| [cluster\_certificate\_authority\_data](#output\_cluster\_certificate\_authority\_data) | Base64-encoded cluster certificate authority data. |
| [cluster\_created\_at](#output\_cluster\_created\_at) | Timestamp when the EKS cluster was created. |
| [cluster\_endpoint](#output\_cluster\_endpoint) | Kubernetes API server endpoint. |
| [cluster\_iam\_role\_arn](#output\_cluster\_iam\_role\_arn) | IAM role ARN used by the EKS control plane. |
| [cluster\_log\_group\_name](#output\_cluster\_log\_group\_name) | CloudWatch log group for EKS control plane logs, if cluster logs are enabled. |
| [cluster\_name](#output\_cluster\_name) | EKS cluster name. |
| [cluster\_oidc\_issuer\_url](#output\_cluster\_oidc\_issuer\_url) | OIDC issuer URL for the EKS cluster. |
| [cluster\_platform\_version](#output\_cluster\_platform\_version) | EKS platform version. |
| [cluster\_security\_group\_id](#output\_cluster\_security\_group\_id) | Security group created by EKS for the cluster. |
| [cluster\_status](#output\_cluster\_status) | EKS cluster status. |
| [cluster\_tags\_all](#output\_cluster\_tags\_all) | All tags applied to the EKS cluster, including provider default tags. |
| [cluster\_version](#output\_cluster\_version) | Kubernetes version running on the EKS cluster. |
| [pod\_identity\_association\_arns](#output\_pod\_identity\_association\_arns) | EKS Pod Identity association ARNs by association key. |
| [pod\_identity\_association\_ids](#output\_pod\_identity\_association\_ids) | EKS Pod Identity association IDs by association key. |
| [pod\_identity\_external\_ids](#output\_pod\_identity\_external\_ids) | External IDs generated for EKS Pod Identity associations by association key. |
| [pod\_identity\_iam\_role\_arns](#output\_pod\_identity\_iam\_role\_arns) | IAM role ARNs used by EKS Pod Identity associations by association key. |
| [pod\_identity\_iam\_role\_names](#output\_pod\_identity\_iam\_role\_names) | IAM role names used by EKS Pod Identity associations by association key. |
| [update\_kubeconfig\_command](#output\_update\_kubeconfig\_command) | AWS CLI command to configure kubectl for this cluster. |

## Git Hooks

Enable the repository hooks after cloning or initializing Git:

```bash
git config core.hooksPath .githooks
```

The pre-commit hook checks Terraform formatting and verifies that generated Terraform docs in this README are up to date.

Regenerate the README module documentation manually with:

```bash
scripts/terraform-docs.sh
```

## Tests

Native Terraform tests live in `tests/` and use mocked AWS provider resources, so they can run without AWS credentials or creating infrastructure:

```bash
terraform test
```

Pull requests run the same tests through `.github/workflows/terraform-pr.yml`, along with formatting, generated-docs, validation, and example checks.

## Local Development

Use the Makefile for common local checks:

```bash
make fmt
make docs
make check
```

## Notes

- The module does not create VPC, subnet, route table, NAT gateway, or security baseline resources.
- The public Kubernetes API endpoint is disabled by default. If you enable it, use narrow `public_access_cidrs`.
- EKS Auto Mode manages compute from the selected built-in node pools; this module does not create managed node groups.
- Kubernetes manifests are rendered as Terraform outputs and are not applied by this module.