feat: Add support for EKS Auto Mode and EKS Hybrid nodes (#3225)

* feat: Add support for EKS hybrid nodes

* feat: Add support for EKS Auto Mode

* chore: Update test directory names

* chore: Clean up examples and tests

* fix: Clean up and last minute changes for GA

* chore: Formatting

* chore: Bump min required version for new features

* fix: Corrects from test/validation on existing clusters

* feat: Add policy for custom tags on EKS Auto Mode, validate examples

* chore: Expand on `CAM` acronym

* chore: Update README to match examples
This commit is contained in:
Bryant Biggs
2024-12-04 09:24:21 -06:00
committed by GitHub
parent 6866b40bec
commit 3b974d33ad
62 changed files with 3896 additions and 441 deletions

View File

@@ -64,13 +64,13 @@ module "eks_managed_node_group" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.75 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.79 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.75 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.79 |
## Modules

View File

@@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.75"
version = ">= 5.79"
}
}
}

View File

@@ -29,13 +29,13 @@ module "fargate_profile" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.75 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.79 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.75 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.79 |
## Modules

View File

@@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.75"
version = ">= 5.79"
}
}
}

View File

@@ -0,0 +1,159 @@
# EKS Hybrid Node Role Module
Terraform module which creates IAM role and policy resources for Amazon EKS Hybrid Node(s).
## Usage
EKS Hybrid nodes use the AWS IAM Authenticator and temporary IAM credentials provisioned by AWS SSM or AWS IAM Roles Anywhere to authenticate with the EKS cluster. This module supports both SSM and IAM Roles Anywhere based IAM permissions.
### SSM
```hcl
module "eks" {
source = "terraform-aws-modules/eks/aws"
...
access_entries = {
hybrid-node-role = {
principal_arn = module.eks_hybrid_node_role.arn
type = "HYBRID_LINUX"
}
}
}
module "eks_hybrid_node_role" {
source = "terraform-aws-modules/eks/aws//modules/hybrid-node-role"
name = "hybrid"
tags = {
Environment = "dev"
Terraform = "true"
}
}
```
### IAM Roles Anywhere
```hcl
module "eks" {
source = "terraform-aws-modules/eks/aws"
...
access_entries = {
hybrid-node-role = {
principal_arn = module.eks_hybrid_node_role.arn
type = "HYBRID_LINUX"
}
}
}
module "eks_hybrid_node_role" {
source = "terraform-aws-modules/eks/aws//modules/hybrid-node-role"
name = "hybrid-ira"
enable_ira = true
ira_trust_anchor_source_type = "CERTIFICATE_BUNDLE"
ira_trust_anchor_x509_certificate_data = <<-EOT
MIIFMzCCAxugAwIBAgIRAMnVXU7ncv/+Cl16eJbZ9hswDQYJKoZIhvcNAQELBQAw
...
MGx/BMRkrNUVcg3xA0lhECo/olodCkmZo5/mjybbjFQwJzDSKFoW
EOT
tags = {
Environment = "dev"
Terraform = "true"
}
}
```
<!-- BEGIN_TF_DOCS -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.79 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.79 |
## Modules
No modules.
## Resources
| Name | Type |
|------|------|
| [aws_iam_policy.intermediate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.intermediate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.intermediate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_rolesanywhere_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rolesanywhere_profile) | resource |
| [aws_rolesanywhere_trust_anchor.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/rolesanywhere_trust_anchor) | resource |
| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.intermediate](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.intermediate_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_cluster_arns"></a> [cluster\_arns](#input\_cluster\_arns) | List of EKS cluster ARNs to allow the node to describe | `list(string)` | <pre>[<br/> "*"<br/>]</pre> | no |
| <a name="input_create"></a> [create](#input\_create) | Controls if resources should be created (affects nearly all resources) | `bool` | `true` | no |
| <a name="input_description"></a> [description](#input\_description) | IAM role description | `string` | `"EKS Hybrid Node IAM role"` | no |
| <a name="input_enable_ira"></a> [enable\_ira](#input\_enable\_ira) | Enables IAM Roles Anywhere based IAM permissions on the node | `bool` | `false` | no |
| <a name="input_enable_pod_identity"></a> [enable\_pod\_identity](#input\_enable\_pod\_identity) | Enables EKS Pod Identity based IAM permissions on the node | `bool` | `true` | no |
| <a name="input_intermediate_policy_name"></a> [intermediate\_policy\_name](#input\_intermediate\_policy\_name) | Name of the IAM policy | `string` | `null` | no |
| <a name="input_intermediate_policy_statements"></a> [intermediate\_policy\_statements](#input\_intermediate\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_intermediate_policy_use_name_prefix"></a> [intermediate\_policy\_use\_name\_prefix](#input\_intermediate\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`intermediate_policy_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_intermediate_role_description"></a> [intermediate\_role\_description](#input\_intermediate\_role\_description) | IAM role description | `string` | `"EKS Hybrid Node IAM Roles Anywhere intermediate IAM role"` | no |
| <a name="input_intermediate_role_name"></a> [intermediate\_role\_name](#input\_intermediate\_role\_name) | Name of the IAM role | `string` | `null` | no |
| <a name="input_intermediate_role_path"></a> [intermediate\_role\_path](#input\_intermediate\_role\_path) | Path of the IAM role | `string` | `"/"` | no |
| <a name="input_intermediate_role_policies"></a> [intermediate\_role\_policies](#input\_intermediate\_role\_policies) | Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format | `map(string)` | `{}` | no |
| <a name="input_intermediate_role_use_name_prefix"></a> [intermediate\_role\_use\_name\_prefix](#input\_intermediate\_role\_use\_name\_prefix) | Determines whether the name of the IAM role (`intermediate_role_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_ira_profile_duration_seconds"></a> [ira\_profile\_duration\_seconds](#input\_ira\_profile\_duration\_seconds) | The number of seconds the vended session credentials are valid for. Defaults to `3600` | `number` | `null` | no |
| <a name="input_ira_profile_managed_policy_arns"></a> [ira\_profile\_managed\_policy\_arns](#input\_ira\_profile\_managed\_policy\_arns) | A list of managed policy ARNs that apply to the vended session credentials | `list(string)` | `[]` | no |
| <a name="input_ira_profile_name"></a> [ira\_profile\_name](#input\_ira\_profile\_name) | Name of the Roles Anywhere profile | `string` | `null` | no |
| <a name="input_ira_profile_require_instance_properties"></a> [ira\_profile\_require\_instance\_properties](#input\_ira\_profile\_require\_instance\_properties) | Specifies whether instance properties are required in [CreateSession](https://docs.aws.amazon.com/rolesanywhere/latest/APIReference/API_CreateSession.html) requests with this profile | `bool` | `null` | no |
| <a name="input_ira_profile_session_policy"></a> [ira\_profile\_session\_policy](#input\_ira\_profile\_session\_policy) | A session policy that applies to the trust boundary of the vended session credentials | `string` | `null` | no |
| <a name="input_ira_trust_anchor_acm_pca_arn"></a> [ira\_trust\_anchor\_acm\_pca\_arn](#input\_ira\_trust\_anchor\_acm\_pca\_arn) | The ARN of the ACM PCA that issued the trust anchor certificate | `string` | `null` | no |
| <a name="input_ira_trust_anchor_name"></a> [ira\_trust\_anchor\_name](#input\_ira\_trust\_anchor\_name) | Name of the Roles Anywhere trust anchor | `string` | `null` | no |
| <a name="input_ira_trust_anchor_notification_settings"></a> [ira\_trust\_anchor\_notification\_settings](#input\_ira\_trust\_anchor\_notification\_settings) | Notification settings for the trust anchor | `any` | `[]` | no |
| <a name="input_ira_trust_anchor_source_type"></a> [ira\_trust\_anchor\_source\_type](#input\_ira\_trust\_anchor\_source\_type) | The source type of the trust anchor | `string` | `null` | no |
| <a name="input_ira_trust_anchor_x509_certificate_data"></a> [ira\_trust\_anchor\_x509\_certificate\_data](#input\_ira\_trust\_anchor\_x509\_certificate\_data) | The X.509 certificate data of the trust anchor | `string` | `null` | no |
| <a name="input_max_session_duration"></a> [max\_session\_duration](#input\_max\_session\_duration) | Maximum API session duration in seconds between 3600 and 43200 | `number` | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | Name of the IAM role | `string` | `"EKSHybridNode"` | no |
| <a name="input_path"></a> [path](#input\_path) | Path of the IAM role | `string` | `"/"` | no |
| <a name="input_permissions_boundary_arn"></a> [permissions\_boundary\_arn](#input\_permissions\_boundary\_arn) | Permissions boundary ARN to use for the IAM role | `string` | `null` | no |
| <a name="input_policies"></a> [policies](#input\_policies) | Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format | `map(string)` | `{}` | no |
| <a name="input_policy_description"></a> [policy\_description](#input\_policy\_description) | IAM policy description | `string` | `"EKS Hybrid Node IAM role policy"` | no |
| <a name="input_policy_name"></a> [policy\_name](#input\_policy\_name) | Name of the IAM policy | `string` | `"EKSHybridNode"` | no |
| <a name="input_policy_path"></a> [policy\_path](#input\_policy\_path) | Path of the IAM policy | `string` | `"/"` | no |
| <a name="input_policy_statements"></a> [policy\_statements](#input\_policy\_statements) | A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed | `any` | `[]` | no |
| <a name="input_policy_use_name_prefix"></a> [policy\_use\_name\_prefix](#input\_policy\_use\_name\_prefix) | Determines whether the name of the IAM policy (`policy_name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of additional tags to add the the IAM role | `map(any)` | `{}` | no |
| <a name="input_trust_anchor_arns"></a> [trust\_anchor\_arns](#input\_trust\_anchor\_arns) | List of IAM Roles Anywhere trust anchor ARNs. Required if `enable_ira` is set to `true` | `list(string)` | `[]` | no |
| <a name="input_use_name_prefix"></a> [use\_name\_prefix](#input\_use\_name\_prefix) | Determines whether the name of the IAM role (`name`) is used as a prefix | `bool` | `true` | no |
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The Amazon Resource Name (ARN) specifying the node IAM role |
| <a name="output_intermediate_role_arn"></a> [intermediate\_role\_arn](#output\_intermediate\_role\_arn) | The Amazon Resource Name (ARN) specifying the node IAM role |
| <a name="output_intermediate_role_name"></a> [intermediate\_role\_name](#output\_intermediate\_role\_name) | The name of the node IAM role |
| <a name="output_intermediate_role_unique_id"></a> [intermediate\_role\_unique\_id](#output\_intermediate\_role\_unique\_id) | Stable and unique string identifying the node IAM role |
| <a name="output_name"></a> [name](#output\_name) | The name of the node IAM role |
| <a name="output_unique_id"></a> [unique\_id](#output\_unique\_id) | Stable and unique string identifying the node IAM role |
<!-- END_TF_DOCS -->

View File

@@ -0,0 +1,369 @@
data "aws_partition" "current" {
count = var.create ? 1 : 0
}
locals {
partition = try(data.aws_partition.current[0].partition, "aws")
}
################################################################################
# Node IAM Role
################################################################################
data "aws_iam_policy_document" "assume_role" {
count = var.create ? 1 : 0
# SSM
dynamic "statement" {
for_each = var.enable_ira ? [] : [1]
content {
actions = [
"sts:AssumeRole",
"sts:TagSession",
]
principals {
type = "Service"
identifiers = ["ssm.amazonaws.com"]
}
}
}
# IAM Roles Anywhere
dynamic "statement" {
for_each = var.enable_ira ? [1] : []
content {
actions = [
"sts:TagSession",
"sts:SetSourceIdentity",
]
principals {
type = "AWS"
identifiers = [aws_iam_role.intermediate[0].arn]
}
}
}
dynamic "statement" {
for_each = var.enable_ira ? [1] : []
content {
actions = [
"sts:AssumeRole",
"sts:TagSession",
]
principals {
type = "AWS"
identifiers = [aws_iam_role.intermediate[0].arn]
}
condition {
test = "StringEquals"
variable = "sts:RoleSessionName"
values = ["$${aws:PrincipalTag/x509Subject/CN}"]
}
}
}
}
resource "aws_iam_role" "this" {
count = var.create ? 1 : 0
name = var.use_name_prefix ? null : var.name
name_prefix = var.use_name_prefix ? "${var.name}-" : null
path = var.path
description = var.description
assume_role_policy = data.aws_iam_policy_document.assume_role[0].json
max_session_duration = var.max_session_duration
permissions_boundary = var.permissions_boundary_arn
force_detach_policies = true
tags = var.tags
}
################################################################################
# Node IAM Role Policy
################################################################################
data "aws_iam_policy_document" "this" {
count = var.create ? 1 : 0
statement {
actions = [
"ssm:DeregisterManagedInstance",
"ssm:DescribeInstanceInformation",
]
resources = ["*"]
}
statement {
actions = ["eks:DescribeCluster"]
resources = var.cluster_arns
}
dynamic "statement" {
for_each = var.enable_pod_identity ? [1] : []
content {
actions = ["eks-auth:AssumeRoleForPodIdentity"]
resources = ["*"]
}
}
dynamic "statement" {
for_each = var.policy_statements
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
dynamic "principals" {
for_each = try(statement.value.principals, [])
content {
type = principals.value.type
identifiers = principals.value.identifiers
}
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
content {
type = not_principals.value.type
identifiers = not_principals.value.identifiers
}
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
content {
test = condition.value.test
values = condition.value.values
variable = condition.value.variable
}
}
}
}
}
resource "aws_iam_policy" "this" {
count = var.create ? 1 : 0
name = var.policy_use_name_prefix ? null : var.policy_name
name_prefix = var.policy_use_name_prefix ? "${var.policy_name}-" : null
path = var.policy_path
description = var.policy_description
policy = data.aws_iam_policy_document.this[0].json
tags = var.tags
}
resource "aws_iam_role_policy_attachment" "this" {
for_each = { for k, v in merge(
{
node = try(aws_iam_policy.this[0].arn, null)
AmazonSSMManagedInstanceCore = "arn:${local.partition}:iam::aws:policy/AmazonSSMManagedInstanceCore"
AmazonEC2ContainerRegistryPullOnly = "arn:${local.partition}:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly"
},
var.policies
) : k => v if var.create }
policy_arn = each.value
role = aws_iam_role.this[0].name
}
################################################################################
# Roles Anywhere Profile
################################################################################
locals {
enable_ira = var.create && var.enable_ira
}
resource "aws_rolesanywhere_profile" "this" {
count = local.enable_ira ? 1 : 0
duration_seconds = var.ira_profile_duration_seconds
managed_policy_arns = var.ira_profile_managed_policy_arns
name = try(coalesce(var.ira_profile_name, var.name), null)
require_instance_properties = var.ira_profile_require_instance_properties
role_arns = [aws_iam_role.intermediate[0].arn]
session_policy = var.ira_profile_session_policy
tags = var.tags
}
################################################################################
# Roles Anywhere Trust Anchor
################################################################################
resource "aws_rolesanywhere_trust_anchor" "this" {
count = local.enable_ira ? 1 : 0
name = try(coalesce(var.ira_trust_anchor_name, var.name), null)
dynamic "notification_settings" {
for_each = var.ira_trust_anchor_notification_settings
content {
channel = try(notification_settings.value.channel, null)
enabled = try(notification_settings.value.enabled, null)
event = try(notification_settings.value.event, null)
threshold = try(notification_settings.value.threshold, null)
}
}
source {
source_data {
acm_pca_arn = var.ira_trust_anchor_acm_pca_arn
x509_certificate_data = var.ira_trust_anchor_x509_certificate_data
}
source_type = var.ira_trust_anchor_source_type
}
tags = var.tags
}
################################################################################
# Intermediate IAM Role
################################################################################
data "aws_iam_policy_document" "intermediate_assume_role" {
count = local.enable_ira ? 1 : 0
statement {
actions = [
"sts:AssumeRole",
"sts:TagSession",
"sts:SetSourceIdentity",
]
principals {
type = "Service"
identifiers = ["rolesanywhere.amazonaws.com"]
}
condition {
test = "ArnEquals"
variable = "aws:SourceArn"
values = concat(var.trust_anchor_arns, aws_rolesanywhere_trust_anchor.this[*].arn)
}
}
}
locals {
intermediate_role_use_name_prefix = coalesce(var.intermediate_role_use_name_prefix, var.use_name_prefix)
intermediate_role_name = coalesce(var.intermediate_role_name, "${var.name}-inter")
}
resource "aws_iam_role" "intermediate" {
count = local.enable_ira ? 1 : 0
name = local.intermediate_role_use_name_prefix ? null : local.intermediate_role_name
name_prefix = local.intermediate_role_use_name_prefix ? "${local.intermediate_role_name}-" : null
path = coalesce(var.intermediate_role_path, var.path)
description = var.intermediate_role_description
assume_role_policy = data.aws_iam_policy_document.intermediate_assume_role[0].json
max_session_duration = var.max_session_duration
permissions_boundary = var.permissions_boundary_arn
force_detach_policies = true
tags = var.tags
}
################################################################################
# Intermediate IAM Role Policy
################################################################################
data "aws_iam_policy_document" "intermediate" {
count = local.enable_ira ? 1 : 0
statement {
actions = ["eks:DescribeCluster"]
resources = var.cluster_arns
}
dynamic "statement" {
for_each = var.intermediate_policy_statements
content {
sid = try(statement.value.sid, null)
actions = try(statement.value.actions, null)
not_actions = try(statement.value.not_actions, null)
effect = try(statement.value.effect, null)
resources = try(statement.value.resources, null)
not_resources = try(statement.value.not_resources, null)
dynamic "principals" {
for_each = try(statement.value.principals, [])
content {
type = principals.value.type
identifiers = principals.value.identifiers
}
}
dynamic "not_principals" {
for_each = try(statement.value.not_principals, [])
content {
type = not_principals.value.type
identifiers = not_principals.value.identifiers
}
}
dynamic "condition" {
for_each = try(statement.value.conditions, [])
content {
test = condition.value.test
values = condition.value.values
variable = condition.value.variable
}
}
}
}
}
locals {
intermediate_policy_use_name_prefix = coalesce(var.intermediate_policy_use_name_prefix, var.policy_use_name_prefix)
intermediate_policy_name = coalesce(var.intermediate_policy_name, var.policy_name)
}
resource "aws_iam_policy" "intermediate" {
count = local.enable_ira ? 1 : 0
name = local.intermediate_policy_use_name_prefix ? null : local.intermediate_policy_name
name_prefix = local.intermediate_policy_use_name_prefix ? "${local.intermediate_policy_name}-" : null
path = var.policy_path
description = var.policy_description
policy = data.aws_iam_policy_document.intermediate[0].json
tags = var.tags
}
resource "aws_iam_role_policy_attachment" "intermediate" {
for_each = { for k, v in merge(
{
intermediate = try(aws_iam_policy.intermediate[0].arn, null)
AmazonEC2ContainerRegistryPullOnly = "arn:${local.partition}:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly"
},
var.intermediate_role_policies
) : k => v if local.enable_ira }
policy_arn = each.value
role = aws_iam_role.this[0].name
}

View File

@@ -0,0 +1,37 @@
################################################################################
# Node IAM Role
################################################################################
output "name" {
description = "The name of the node IAM role"
value = try(aws_iam_role.this[0].name, null)
}
output "arn" {
description = "The Amazon Resource Name (ARN) specifying the node IAM role"
value = try(aws_iam_role.this[0].arn, null)
}
output "unique_id" {
description = "Stable and unique string identifying the node IAM role"
value = try(aws_iam_role.this[0].unique_id, null)
}
################################################################################
# Intermedaite IAM Role
################################################################################
output "intermediate_role_name" {
description = "The name of the node IAM role"
value = try(aws_iam_role.intermediate[0].name, null)
}
output "intermediate_role_arn" {
description = "The Amazon Resource Name (ARN) specifying the node IAM role"
value = try(aws_iam_role.intermediate[0].arn, null)
}
output "intermediate_role_unique_id" {
description = "Stable and unique string identifying the node IAM role"
value = try(aws_iam_role.intermediate[0].unique_id, null)
}

View File

@@ -0,0 +1,239 @@
variable "create" {
description = "Controls if resources should be created (affects nearly all resources)"
type = bool
default = true
}
################################################################################
# Node IAM Role
################################################################################
variable "name" {
description = "Name of the IAM role"
type = string
default = "EKSHybridNode"
}
variable "use_name_prefix" {
description = "Determines whether the name of the IAM role (`name`) is used as a prefix"
type = bool
default = true
}
variable "path" {
description = "Path of the IAM role"
type = string
default = "/"
}
variable "description" {
description = "IAM role description"
type = string
default = "EKS Hybrid Node IAM role"
}
variable "max_session_duration" {
description = "Maximum API session duration in seconds between 3600 and 43200"
type = number
default = null
}
variable "permissions_boundary_arn" {
description = "Permissions boundary ARN to use for the IAM role"
type = string
default = null
}
variable "tags" {
description = "A map of additional tags to add the the IAM role"
type = map(any)
default = {}
}
variable "enable_ira" {
description = "Enables IAM Roles Anywhere based IAM permissions on the node"
type = bool
default = false
}
variable "trust_anchor_arns" {
description = "List of IAM Roles Anywhere trust anchor ARNs. Required if `enable_ira` is set to `true`"
type = list(string)
default = []
}
################################################################################
# Node IAM Role Policy
################################################################################
variable "policy_name" {
description = "Name of the IAM policy"
type = string
default = "EKSHybridNode"
}
variable "policy_use_name_prefix" {
description = "Determines whether the name of the IAM policy (`policy_name`) is used as a prefix"
type = bool
default = true
}
variable "policy_path" {
description = "Path of the IAM policy"
type = string
default = "/"
}
variable "policy_description" {
description = "IAM policy description"
type = string
default = "EKS Hybrid Node IAM role policy"
}
variable "policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
}
variable "policies" {
description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format"
type = map(string)
default = {}
}
variable "cluster_arns" {
description = "List of EKS cluster ARNs to allow the node to describe"
type = list(string)
default = ["*"]
}
variable "enable_pod_identity" {
description = "Enables EKS Pod Identity based IAM permissions on the node"
type = bool
default = true
}
################################################################################
# IAM Roles Anywhere Profile
################################################################################
variable "ira_profile_name" {
description = "Name of the Roles Anywhere profile"
type = string
default = null
}
variable "ira_profile_duration_seconds" {
description = "The number of seconds the vended session credentials are valid for. Defaults to `3600`"
type = number
default = null
}
variable "ira_profile_managed_policy_arns" {
description = "A list of managed policy ARNs that apply to the vended session credentials"
type = list(string)
default = []
}
variable "ira_profile_require_instance_properties" {
description = "Specifies whether instance properties are required in [CreateSession](https://docs.aws.amazon.com/rolesanywhere/latest/APIReference/API_CreateSession.html) requests with this profile"
type = bool
default = null
}
variable "ira_profile_session_policy" {
description = "A session policy that applies to the trust boundary of the vended session credentials"
type = string
default = null
}
################################################################################
# Roles Anywhere Trust Anchor
################################################################################
variable "ira_trust_anchor_name" {
description = "Name of the Roles Anywhere trust anchor"
type = string
default = null
}
variable "ira_trust_anchor_notification_settings" {
description = "Notification settings for the trust anchor"
type = any
default = []
}
variable "ira_trust_anchor_acm_pca_arn" {
description = "The ARN of the ACM PCA that issued the trust anchor certificate"
type = string
default = null
}
variable "ira_trust_anchor_x509_certificate_data" {
description = "The X.509 certificate data of the trust anchor"
type = string
default = null
}
variable "ira_trust_anchor_source_type" {
description = "The source type of the trust anchor"
type = string
default = null
}
################################################################################
# Intermediate IAM Role
################################################################################
variable "intermediate_role_name" {
description = "Name of the IAM role"
type = string
default = null
}
variable "intermediate_role_use_name_prefix" {
description = "Determines whether the name of the IAM role (`intermediate_role_name`) is used as a prefix"
type = bool
default = true
}
variable "intermediate_role_path" {
description = "Path of the IAM role"
type = string
default = "/"
}
variable "intermediate_role_description" {
description = "IAM role description"
type = string
default = "EKS Hybrid Node IAM Roles Anywhere intermediate IAM role"
}
################################################################################
# Intermediate IAM Role Policy
################################################################################
variable "intermediate_policy_name" {
description = "Name of the IAM policy"
type = string
default = null
}
variable "intermediate_policy_use_name_prefix" {
description = "Determines whether the name of the IAM policy (`intermediate_policy_name`) is used as a prefix"
type = bool
default = true
}
variable "intermediate_policy_statements" {
description = "A list of IAM policy [statements](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#statement) - used for adding specific IAM permissions as needed"
type = any
default = []
}
variable "intermediate_role_policies" {
description = "Policies to attach to the IAM role in `{'static_name' = 'policy_arn'}` format"
type = map(string)
default = {}
}

View File

@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.3.2"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.79"
}
}
}

View File

@@ -86,13 +86,13 @@ module "karpenter" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.75 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.79 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.75 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.79 |
## Modules

View File

@@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.75"
version = ">= 5.79"
}
}
}

View File

@@ -43,13 +43,13 @@ module "self_managed_node_group" {
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.75 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.79 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.75 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.79 |
## Modules

View File

@@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.75"
version = ">= 5.79"
}
}
}