Skip to content

Commit

Permalink
Add eks-access-entry module
Browse files Browse the repository at this point in the history
  • Loading branch information
posquit0 committed May 20, 2024
1 parent 9222036 commit 3f08a47
Show file tree
Hide file tree
Showing 9 changed files with 364 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .github/labeler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
":floppy_disk: ecr-repository":
- modules/ecr-repository/**/*

":floppy_disk: eks-access-entry":
- modules/eks-access-entry/**/*

":floppy_disk: eks-addon":
- modules/eks-addon/**/*

Expand Down
3 changes: 3 additions & 0 deletions .github/labels.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
- color: "fbca04"
description: "This issue or pull request is related to ecr-repository module."
name: ":floppy_disk: ecr-repository"
- color: "fbca04"
description: "This issue or pull request is related to eks-access-entry module."
name: ":floppy_disk: eks-access-entry"
- color: "fbca04"
description: "This issue or pull request is related to eks-addon module."
name: ":floppy_disk: eks-addon"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Terraform module which creates resources for container services on AWS.

- [ecr-registry](./modules/ecr-registry)
- [ecr-repository](./modules/ecr-repository)
- [eks-access-entry](./modules/eks-access-entry)
- [eks-addon](./modules/eks-addon)
- [eks-aws-auth](./modules/eks-aws-auth)
- [eks-cluster](./modules/eks-cluster)
Expand Down
67 changes: 67 additions & 0 deletions modules/eks-access-entry/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# eks-access-entry

This module creates following resources.

- `aws_eks_access_entry`
- `aws_eks_access_policy_association` (optional)

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.6 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.42 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.50.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_resource_group"></a> [resource\_group](#module\_resource\_group) | tedilabs/misc/aws//modules/resource-group | ~> 0.10.0 |

## Resources

| Name | Type |
|------|------|
| [aws_eks_access_entry.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource |
| [aws_eks_access_policy_association.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_policy_association) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | (Required) The name of the Amazon EKS cluster to create IAM access entries. | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | (Required) The name of the Amazon EKS access entry. | `string` | n/a | yes |
| <a name="input_principal"></a> [principal](#input\_principal) | (Required) 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. | `string` | n/a | yes |
| <a name="input_kubernetes_groups"></a> [kubernetes\_groups](#input\_kubernetes\_groups) | (Optional) A set of groups within the Kubernetes cluster. Only used when `type` is `STANDARD`. | `set(string)` | `[]` | no |
| <a name="input_kubernetes_permissions"></a> [kubernetes\_permissions](#input\_kubernetes\_permissions) | (Optional) A list of permissions for EKS access entry to the EKS cluster. Each item of `kubernetes_permissions` block as defined below.<br> (Required) `policy` - The ARN of the access policy that you're associating.<br> (Optional) `scope` - The type of access scope that you're associating. Valid values are `NAMESPACE`, `CLUSTER`. Defaults to `CLUSTER`.<br> (Optional) `namespaces` - A set of namespaces to which the access scope applies. You can enter plain text namespaces, or wildcard namespaces such as `dev-*`. | <pre>list(object({<br> policy = string<br> scope = optional(string, "CLUSTER")<br> namespaces = optional(set(string), [])<br> }))</pre> | `[]` | no |
| <a name="input_kubernetes_username"></a> [kubernetes\_username](#input\_kubernetes\_username) | (Optional) 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. Only used when `type` is `STANDARD`. | `string` | `null` | no |
| <a name="input_module_tags_enabled"></a> [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
| <a name="input_resource_group_description"></a> [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
| <a name="input_resource_group_enabled"></a> [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 |
| <a name="input_resource_group_name"></a> [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 |
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no |
| <a name="input_timeouts"></a> [timeouts](#input\_timeouts) | (Optional) How long to wait for the EKS access entry to be created/deleted. | <pre>object({<br> create = optional(string, "20m")<br> delete = optional(string, "40m")<br> })</pre> | `{}` | no |
| <a name="input_type"></a> [type](#input\_type) | (Optional) The type of the access entry. Valid values are `EC2_LINUX`, `EC2_WINDOWS`, `FARGATE_LINUX`, `STANDARD`. Defaults to `STANDARD`. | `string` | `"STANDARD"` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The Amazon Resource Name (ARN) of the EKS access entry. |
| <a name="output_cluster_name"></a> [cluster\_name](#output\_cluster\_name) | The name of the EKS cluster. |
| <a name="output_created_at"></a> [created\_at](#output\_created\_at) | Date and time in RFC3339 format that the EKS access entry was created. |
| <a name="output_kubernetes_groups"></a> [kubernetes\_groups](#output\_kubernetes\_groups) | The authenticated groups in Kubernetes cluster. |
| <a name="output_kubernetes_permissions"></a> [kubernetes\_permissions](#output\_kubernetes\_permissions) | The list of permissions for EKS access entry to the EKS cluster. |
| <a name="output_kubernetes_username"></a> [kubernetes\_username](#output\_kubernetes\_username) | The authenticated username in Kubernetes cluster. |
| <a name="output_name"></a> [name](#output\_name) | The name of the EKS access entry. |
| <a name="output_principal"></a> [principal](#output\_principal) | The ARN of one, and only one, existing IAM principal to grant access to Kubernetes objects on the cluster. |
| <a name="output_type"></a> [type](#output\_type) | The type of the access entry. |
| <a name="output_updated_at"></a> [updated\_at](#output\_updated\_at) | Date and time in RFC3339 format that the EKS access entry was updated. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
76 changes: 76 additions & 0 deletions modules/eks-access-entry/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
locals {
metadata = {
package = "terraform-aws-container"
version = trimspace(file("${path.module}/../../VERSION"))
module = basename(path.module)
name = "${var.cluster_name}/${var.name}"
}
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
} : {}
}


###################################################
# Access Entry
###################################################

resource "aws_eks_access_entry" "this" {
cluster_name = var.cluster_name
type = var.type
principal_arn = var.principal

user_name = (var.type == "STANDARD"
? var.kubernetes_username
: null
)
kubernetes_groups = (var.type == "STANDARD"
? var.kubernetes_groups
: []
)

timeouts {
create = var.timeouts.create
delete = var.timeouts.delete
}

tags = merge(
{
"Name" = var.name
},
local.module_tags,
var.tags,
)
}


###################################################
# Access Poilcy for Standard Access Entry
###################################################

resource "aws_eks_access_policy_association" "this" {
for_each = {
for permission in var.kubernetes_permissions :
trimprefix("arn:aws:eks::aws:cluster-access-policy/", permission.policy) => permission
}

cluster_name = aws_eks_access_entry.this.cluster_name
principal_arn = aws_eks_access_entry.this.principal_arn

policy_arn = each.value.policy

access_scope {
type = lower(each.value.scope)
namespaces = each.value.namespaces
}

timeouts {
create = var.timeouts.create
delete = var.timeouts.delete
}
}

49 changes: 49 additions & 0 deletions modules/eks-access-entry/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
output "name" {
description = "The name of the EKS access entry."
value = var.name
}

output "cluster_name" {
description = "The name of the EKS cluster."
value = var.cluster_name
}

output "arn" {
description = "The Amazon Resource Name (ARN) of the EKS access entry."
value = aws_eks_access_entry.this.access_entry_arn
}

output "type" {
description = "The type of the access entry."
value = aws_eks_access_entry.this.type
}

output "principal" {
description = "The ARN of one, and only one, existing IAM principal to grant access to Kubernetes objects on the cluster."
value = aws_eks_access_entry.this.principal_arn
}

output "kubernetes_username" {
description = "The authenticated username in Kubernetes cluster."
value = aws_eks_access_entry.this.user_name
}

output "kubernetes_groups" {
description = "The authenticated groups in Kubernetes cluster."
value = aws_eks_access_entry.this.kubernetes_groups
}

output "kubernetes_permissions" {
description = "The list of permissions for EKS access entry to the EKS cluster."
value = var.kubernetes_permissions
}

output "created_at" {
description = "Date and time in RFC3339 format that the EKS access entry was created."
value = aws_eks_access_entry.this.created_at
}

output "updated_at" {
description = "Date and time in RFC3339 format that the EKS access entry was updated."
value = aws_eks_access_entry.this.modified_at
}
31 changes: 31 additions & 0 deletions modules/eks-access-entry/resource-group.tf
Original file line number Diff line number Diff line change
@@ -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,
)
}
124 changes: 124 additions & 0 deletions modules/eks-access-entry/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
variable "name" {
description = "(Required) The name of the Amazon EKS access entry."
type = string
nullable = false
}

variable "cluster_name" {
description = "(Required) The name of the Amazon EKS cluster to create IAM access entries."
type = string
nullable = false
}

variable "type" {
description = "(Optional) The type of the access entry. Valid values are `EC2_LINUX`, `EC2_WINDOWS`, `FARGATE_LINUX`, `STANDARD`. Defaults to `STANDARD`."
type = string
default = "STANDARD"
nullable = false

validation {
condition = contains(["EC2_LINUX", "EC2_WINDOWS", "FARGATE_LINUX", "STANDARD"], var.type)
error_message = "Valid values for `type` are `EC2_LINUX`, `EC2_WINDOWS`, `FARGATE_LINUX`, `STANDARD`."
}
}

variable "principal" {
description = "(Required) 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."
type = string
nullable = false
}

variable "kubernetes_username" {
description = "(Optional) 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. Only used when `type` is `STANDARD`."
type = string
default = null
nullable = true
}

variable "kubernetes_groups" {
description = "(Optional) A set of groups within the Kubernetes cluster. Only used when `type` is `STANDARD`."
type = set(string)
default = []
nullable = false
}

variable "kubernetes_permissions" {
description = <<EOF
(Optional) A list of permissions for EKS access entry to the EKS cluster. Each item of `kubernetes_permissions` block as defined below.
(Required) `policy` - The ARN of the access policy that you're associating.
(Optional) `scope` - The type of access scope that you're associating. Valid values are `NAMESPACE`, `CLUSTER`. Defaults to `CLUSTER`.
(Optional) `namespaces` - A set of namespaces to which the access scope applies. You can enter plain text namespaces, or wildcard namespaces such as `dev-*`.
EOF
type = list(object({
policy = string
scope = optional(string, "CLUSTER")
namespaces = optional(set(string), [])
}))
default = []
nullable = false

validation {
condition = alltrue([
for permission in var.kubernetes_permissions :
contains(["NAMESPACE", "CLUSTER"], permission.scope)
])
error_message = "Valid values for `scope` are `NAMESPACE`, `CLUSTER`."
}
validation {
condition = alltrue([
for permission in var.kubernetes_permissions :
startswith(permission.policy, "arn:aws:eks::aws:cluster-access-policy/")
])
error_message = "Valid values for `policy` are `arn:aws:eks::aws:cluster-access-policy/*`."
}
}

variable "timeouts" {
description = "(Optional) How long to wait for the EKS access entry to be created/deleted."
type = object({
create = optional(string, "20m")
delete = optional(string, "40m")
})
default = {}
nullable = false
}

variable "tags" {
description = "(Optional) A map of tags to add to all resources."
type = map(string)
default = {}
nullable = false
}

variable "module_tags_enabled" {
description = "(Optional) Whether to create AWS Resource Tags for the module informations."
type = bool
default = true
nullable = false
}


###################################################
# Resource Group
###################################################

variable "resource_group_enabled" {
description = "(Optional) Whether to create Resource Group to find and group AWS resources which are created by this module."
type = bool
default = true
nullable = false
}

variable "resource_group_name" {
description = "(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`."
type = string
default = ""
nullable = false
}

variable "resource_group_description" {
description = "(Optional) The description of Resource Group."
type = string
default = "Managed by Terraform."
nullable = false
}
10 changes: 10 additions & 0 deletions modules/eks-access-entry/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.6"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.42"
}
}
}

0 comments on commit 3f08a47

Please sign in to comment.