diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 540602a..66880e2 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -17,6 +17,9 @@ ":floppy_disk: eks-fargate-profile": - modules/eks-fargate-profile/**/* +":floppy_disk: eks-iam-access": +- modules/eks-iam-access/**/* + ":floppy_disk: eks-max-pods": - modules/eks-max-pods/**/* diff --git a/.github/labels.yaml b/.github/labels.yaml index 570717b..f5a6b2f 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -58,6 +58,9 @@ - color: "fbca04" description: "This issue or pull request is related to eks-fargate-profile module." name: ":floppy_disk: eks-fargate-profile" +- color: "fbca04" + description: "This issue or pull request is related to eks-iam-access module." + name: ":floppy_disk: eks-iam-access" - color: "fbca04" description: "This issue or pull request is related to eks-max-pods module." name: ":floppy_disk: eks-max-pods" diff --git a/README.md b/README.md index 3696531..cee79c7 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ Terraform module which creates resources for container services on AWS. - [eks-aws-auth](./modules/eks-aws-auth) - [eks-cluster](./modules/eks-cluster) - [eks-fargate-profile](./modules/eks-fargate-profile) +- [eks-iam-access](./modules/eks-iam-access) - [eks-max-pods](./modules/eks-max-pods) @@ -31,6 +32,7 @@ Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws- - Add-on - Self-Managed Node Group (with ASG) - Fargate Profile + - Access Entry & Access Policy ## Self Promotion @@ -42,4 +44,4 @@ Like this project? Follow the repository on [GitHub](https://github.com/tedilabs Provided under the terms of the [Apache License](LICENSE). -Copyright © 2021-2023, [Byungjin Park](https://www.posquit0.com). +Copyright © 2021-2024, [Byungjin Park](https://www.posquit0.com). diff --git a/modules/eks-iam-access/README.md b/modules/eks-iam-access/README.md new file mode 100644 index 0000000..42e675b --- /dev/null +++ b/modules/eks-iam-access/README.md @@ -0,0 +1,56 @@ +# eks-iam-access + +This module creates following resources. + +- `aws_eks_access_entry` (optional) +- `aws_eks_access_policy_association` (optional) + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.6 | +| [aws](#requirement\_aws) | >= 5.42 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.50.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_eks_access_entry.node](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_entry.user](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cluster\_name](#input\_cluster\_name) | (Required) The name of the Amazon EKS cluster to create IAM access entries. | `string` | n/a | yes | +| [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no | +| [node\_access\_entries](#input\_node\_access\_entries) | (Optional) A list of configurations for EKS access entries for nodes (EC2 instances, Fargate) that are allowed to access the EKS cluster. Each item of `node_access_entries` block as defined below.
(Required) `name` - A unique name for the access entry. This value is only used internally within Terraform code.
(Required) `type` - The type of the access entry. Valid values are `EC2_LINUX`, `EC2_WINDOWS`, `FARGATE_LINUX`.
(Required) `principal` - The ARN of one, and only one, existing IAM principal to grant access to Kubernetes objects on the cluster. An IAM principal can't be included in more than one access entry. |
list(object({
name = string
type = string
principal = string
}))
| `[]` | no | +| [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | +| [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | +| [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | +| [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | +| [timeouts](#input\_timeouts) | (Optional) How long to wait for the EKS Cluster to be created/updated/deleted. |
object({
create = optional(string, "30m")
update = optional(string, "60m")
delete = optional(string, "15m")
})
| `{}` | no | +| [user\_access\_entries](#input\_user\_access\_entries) | (Optional) A list of configurations for EKS access entries for users (IAM roles, users) that are allowed to access the EKS cluster. Each item of `user_access_entries` block as defined below.
(Required) `name` - A unique name for the access entry. This value is only used internally within Terraform code.
(Required) `principal` - The ARN of one, and only one, existing IAM principal to grant access to Kubernetes objects on the cluster. An IAM principal can't be included in more than one access entry.
(Optional) `username` - The username to authenticate to Kubernetes with. We recommend not specifying a username and letting Amazon EKS specify it for you. Defaults to the IAM principal ARN.
(Optional) `groups` - A set of groups within the Kubernetes cluster. |
list(object({
name = string
principal = string
username = optional(string)
groups = optional(set(string), [])
}))
| `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [cluster\_name](#output\_cluster\_name) | The name of the EKS cluster. | +| [node\_access\_entries](#output\_node\_access\_entries) | The list of configurations for EKS access entries for nodes (EC2 instances, Fargate). | +| [user\_access\_entries](#output\_user\_access\_entries) | The list of configurations for EKS access entries for users (IAM roles, users). | + diff --git a/modules/eks-iam-access/main.tf b/modules/eks-iam-access/main.tf new file mode 100644 index 0000000..f219146 --- /dev/null +++ b/modules/eks-iam-access/main.tf @@ -0,0 +1,69 @@ +locals { + metadata = { + package = "terraform-aws-container" + version = trimspace(file("${path.module}/../../VERSION")) + module = basename(path.module) + name = "eks/${var.cluster_name}/iam-access" + } + module_tags = var.module_tags_enabled ? { + "module.terraform.io/package" = local.metadata.package + "module.terraform.io/version" = local.metadata.version + "module.terraform.io/name" = local.metadata.module + "module.terraform.io/full-name" = "${local.metadata.package}/${local.metadata.module}" + "module.terraform.io/instance" = local.metadata.name + } : {} +} + + +################################################### +# Node Access Entries +################################################### + +# INFO: Not supported attributes +# - `user_name` +# - `kubernetes_groups` +resource "aws_eks_access_entry" "node" { + for_each = { + for entry in var.node_access_entries : + entry.name => entry + } + + cluster_name = var.cluster_name + type = each.value.type + principal_arn = each.value.principal + + tags = merge( + { + "Name" = each.key + }, + local.module_tags, + var.tags, + ) +} + + +################################################### +# User Access Entries +################################################### + +resource "aws_eks_access_entry" "user" { + for_each = { + for entry in var.user_access_entries : + entry.name => entry + } + + cluster_name = var.cluster_name + type = "STANDARD" + principal_arn = each.value.principal + + user_name = each.value.username + kubernetes_groups = each.value.groups + + tags = merge( + { + "Name" = each.key + }, + local.module_tags, + var.tags, + ) +} diff --git a/modules/eks-iam-access/outputs.tf b/modules/eks-iam-access/outputs.tf new file mode 100644 index 0000000..053087c --- /dev/null +++ b/modules/eks-iam-access/outputs.tf @@ -0,0 +1,40 @@ +output "cluster_name" { + description = "The name of the EKS cluster." + value = var.cluster_name +} + +output "node_access_entries" { + description = < { + arn = entry.access_entry_arn + type = entry.type + principal = entry.principal_arn + username = entry.user_name + groups = entry.kubernetes_groups + created_at = entry.created_at + updated_at = entry.modified_at + } + } +} + +output "user_access_entries" { + description = < { + arn = entry.access_entry_arn + type = entry.type + principal = entry.principal_arn + username = entry.user_name + groups = entry.kubernetes_groups + created_at = entry.created_at + updated_at = entry.modified_at + } + } +} diff --git a/modules/eks-iam-access/resource-group.tf b/modules/eks-iam-access/resource-group.tf new file mode 100644 index 0000000..7487ba0 --- /dev/null +++ b/modules/eks-iam-access/resource-group.tf @@ -0,0 +1,31 @@ +locals { + resource_group_name = (var.resource_group_name != "" + ? var.resource_group_name + : join(".", [ + local.metadata.package, + local.metadata.module, + replace(local.metadata.name, "/[^a-zA-Z0-9_\\.-]/", "-"), + ]) + ) +} + + +module "resource_group" { + source = "tedilabs/misc/aws//modules/resource-group" + version = "~> 0.10.0" + + count = (var.resource_group_enabled && var.module_tags_enabled) ? 1 : 0 + + name = local.resource_group_name + description = var.resource_group_description + + query = { + resource_tags = local.module_tags + } + + module_tags_enabled = false + tags = merge( + local.module_tags, + var.tags, + ) +} diff --git a/modules/eks-iam-access/variables.tf b/modules/eks-iam-access/variables.tf new file mode 100644 index 0000000..0c7d5be --- /dev/null +++ b/modules/eks-iam-access/variables.tf @@ -0,0 +1,98 @@ +variable "cluster_name" { + description = "(Required) The name of the Amazon EKS cluster to create IAM access entries." + type = string + nullable = false +} + +variable "node_access_entries" { + description = <