From 9ee484a7f13b9e3b8c2ce9744c629f761c16f052 Mon Sep 17 00:00:00 2001 From: Andriy Knysh Date: Tue, 24 May 2022 16:16:22 -0400 Subject: [PATCH] Allow overriding Fargate Profile name and Fargate Role name. Update Fargate Profile naming (#26) * Allow overriding Fargate profile name and Role name. Update Fargate profile naming derived from the context * Allow overriding Fargate profile name and Role name. Update Fargate profile naming derived from the context --- .gitignore | 1 + README.md | 7 ++++-- docs/terraform.md | 7 ++++-- examples/complete/main.tf | 2 ++ examples/complete/variables.tf | 34 ++++++++++++++++++--------- main.tf | 37 ++++++++++++++++++++++-------- test/src/examples_complete_test.go | 2 +- variables.tf | 16 +++++++++++-- 8 files changed, 79 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 0c6f3c5..c7672f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Local .terraform directories **/.terraform/* +**/.terraform # .tfstate files *.tfstate diff --git a/README.md b/README.md index 1cfd528..4f2c89b 100644 --- a/README.md +++ b/README.md @@ -316,7 +316,8 @@ Available targets: | Name | Source | Version | |------|--------|---------| -| [label](#module\_label) | cloudposse/label/null | 0.25.0 | +| [fargate\_profile\_label](#module\_fargate\_profile\_label) | cloudposse/label/null | 0.25.0 | +| [role\_label](#module\_role\_label) | cloudposse/label/null | 0.25.0 | | [this](#module\_this) | cloudposse/label/null | 0.25.0 | ## Resources @@ -341,6 +342,8 @@ Available targets: | [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | +| [fargate\_profile\_iam\_role\_name](#input\_fargate\_profile\_iam\_role\_name) | Fargate profile IAM role name. If not provided, will be derived from the context | `string` | `null` | no | +| [fargate\_profile\_name](#input\_fargate\_profile\_name) | Fargate profile name. If not provided, will be derived from the context | `string` | `null` | no | | [iam\_role\_kubernetes\_namespace\_delimiter](#input\_iam\_role\_kubernetes\_namespace\_delimiter) | Delimiter for the Kubernetes namespace in the IAM Role name | `string` | `"-"` | no | | [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | | [kubernetes\_labels](#input\_kubernetes\_labels) | Key-value mapping of Kubernetes labels for selection | `map(string)` | `{}` | no | @@ -351,7 +354,7 @@ Available targets: | [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | | [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | | [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | -| [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached. | `string` | `null` | no | +| [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached | `string` | `null` | no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | [subnet\_ids](#input\_subnet\_ids) | Identifiers of private EC2 Subnets to associate with the EKS Fargate Profile. These subnets must have the following resource tag: kubernetes.io/cluster/CLUSTER\_NAME (where CLUSTER\_NAME is replaced with the name of the EKS Cluster) | `list(string)` | n/a | yes | diff --git a/docs/terraform.md b/docs/terraform.md index c6f06c5..a703c0a 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -16,7 +16,8 @@ | Name | Source | Version | |------|--------|---------| -| [label](#module\_label) | cloudposse/label/null | 0.25.0 | +| [fargate\_profile\_label](#module\_fargate\_profile\_label) | cloudposse/label/null | 0.25.0 | +| [role\_label](#module\_role\_label) | cloudposse/label/null | 0.25.0 | | [this](#module\_this) | cloudposse/label/null | 0.25.0 | ## Resources @@ -41,6 +42,8 @@ | [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | +| [fargate\_profile\_iam\_role\_name](#input\_fargate\_profile\_iam\_role\_name) | Fargate profile IAM role name. If not provided, will be derived from the context | `string` | `null` | no | +| [fargate\_profile\_name](#input\_fargate\_profile\_name) | Fargate profile name. If not provided, will be derived from the context | `string` | `null` | no | | [iam\_role\_kubernetes\_namespace\_delimiter](#input\_iam\_role\_kubernetes\_namespace\_delimiter) | Delimiter for the Kubernetes namespace in the IAM Role name | `string` | `"-"` | no | | [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no | | [kubernetes\_labels](#input\_kubernetes\_labels) | Key-value mapping of Kubernetes labels for selection | `map(string)` | `{}` | no | @@ -51,7 +54,7 @@ | [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no | | [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no | | [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no | -| [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached. | `string` | `null` | no | +| [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached | `string` | `null` | no | | [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no | | [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | [subnet\_ids](#input\_subnet\_ids) | Identifiers of private EC2 Subnets to associate with the EKS Fargate Profile. These subnets must have the following resource tag: kubernetes.io/cluster/CLUSTER\_NAME (where CLUSTER\_NAME is replaced with the name of the EKS Cluster) | `list(string)` | n/a | yes | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 63fe993..c1c8650 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -182,6 +182,8 @@ module "eks_fargate_profile" { kubernetes_namespace = var.kubernetes_namespace kubernetes_labels = var.kubernetes_labels iam_role_kubernetes_namespace_delimiter = var.iam_role_kubernetes_namespace_delimiter + fargate_profile_name = var.fargate_profile_name + fargate_profile_iam_role_name = var.fargate_profile_iam_role_name context = module.this.context } diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 518545a..c029549 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -15,14 +15,14 @@ variable "vpc_cidr_block" { variable "kubernetes_version" { type = string - default = null description = "Desired Kubernetes master version. If you do not specify a value, the latest available version is used" + default = null } variable "oidc_provider_enabled" { type = bool - default = false description = "Create an IAM OIDC identity provider for the cluster, then you can create IAM roles to associate with a service account in the cluster, instead of using kiam or kube2iam. For more information, see https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html" + default = false } variable "kubernetes_namespace" { @@ -67,20 +67,20 @@ variable "iam_role_kubernetes_namespace_delimiter" { variable "local_exec_interpreter" { type = list(string) - default = ["/bin/sh", "-c"] description = "shell to use for local_exec" + default = ["/bin/sh", "-c"] } variable "enabled_cluster_log_types" { type = list(string) - default = [] description = "A list of the desired control plane logging to enable. For more information, see https://docs.aws.amazon.com/en_us/eks/latest/userguide/control-plane-logs.html. Possible values [`api`, `audit`, `authenticator`, `controllerManager`, `scheduler`]" + default = [] } variable "cluster_log_retention_period" { type = number + description = "Number of days to retain cluster logs. Requires `enabled_cluster_log_types` to be set. See https://docs.aws.amazon.com/en_us/eks/latest/userguide/control-plane-logs.html" default = 0 - description = "Number of days to retain cluster logs. Requires `enabled_cluster_log_types` to be set. See https://docs.aws.amazon.com/en_us/eks/latest/userguide/control-plane-logs.html." } variable "kubernetes_taints" { @@ -99,7 +99,6 @@ variable "kubernetes_taints" { variable "ec2_ssh_key_name" { type = list(string) - default = [] description = "SSH key pair name to use to access the worker nodes" validation { condition = ( @@ -107,20 +106,20 @@ variable "ec2_ssh_key_name" { ) error_message = "You may not specify more than one `ec2_ssh_key_name`." } + default = [] } variable "update_config" { type = list(map(number)) - default = [] description = <<-EOT Configuration for the `eks_node_group` [`update_config` Configuration Block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group#update_config-configuration-block). Specify exactly one of `max_unavailable` (node count) or `max_unavailable_percentage` (percentage of nodes). EOT + default = [] } variable "after_cluster_joining_userdata" { type = list(string) - default = [] description = "Additional `bash` commands to execute on each worker node after joining the EKS cluster (after executing the `bootstrap.sh` script). For more info, see https://kubedex.com/90-days-of-aws-eks-in-production" validation { condition = ( @@ -128,6 +127,7 @@ variable "after_cluster_joining_userdata" { ) error_message = "You may not specify more than one `after_cluster_joining_userdata`." } + default = [] } variable "ami_type" { @@ -136,18 +136,17 @@ variable "ami_type" { Type of Amazon Machine Image (AMI) associated with the EKS Node Group. Defaults to `AL2_x86_64`. Valid values: `AL2_x86_64`, `AL2_x86_64_GPU`, `AL2_ARM_64`, `BOTTLEROCKET_x86_64`, and `BOTTLEROCKET_ARM_64`. EOT - default = "AL2_x86_64" validation { condition = ( contains(["AL2_x86_64", "AL2_x86_64_GPU", "AL2_ARM_64", "BOTTLEROCKET_x86_64", "BOTTLEROCKET_ARM_64"], var.ami_type) ) error_message = "Var ami_type must be one of \"AL2_x86_64\", \"AL2_x86_64_GPU\", \"AL2_ARM_64\", \"BOTTLEROCKET_x86_64\", and \"BOTTLEROCKET_ARM_64\"." } + default = "AL2_x86_64" } variable "ami_release_version" { type = list(string) - default = [] description = "EKS AMI version to use, e.g. \"1.16.13-20200821\" (no \"v\"). Defaults to latest version for Kubernetes version." validation { condition = ( @@ -155,10 +154,23 @@ variable "ami_release_version" { ) error_message = "Var ami_release_version, if supplied, must be like \"1.16.13-20200821\" (no \"v\")." } + default = [] } variable "before_cluster_joining_userdata" { type = string - default = "" description = "Additional commands to execute on each worker node before joining the EKS cluster (before executing the `bootstrap.sh` script). For more info, see https://kubedex.com/90-days-of-aws-eks-in-production" + default = "" +} + +variable "fargate_profile_name" { + type = string + description = "Fargate profile name. If not provided, will be derived from the context" + default = null +} + +variable "fargate_profile_iam_role_name" { + type = string + description = "Fargate profile IAM role name. If not provided, will be derived from the context" + default = null } diff --git a/main.tf b/main.tf index 067a768..2085c73 100644 --- a/main.tf +++ b/main.tf @@ -7,22 +7,41 @@ locals { "kubernetes.io/cluster/${var.cluster_name}" = "owned" } ) + + fargate_profile_name = var.fargate_profile_name != null ? var.fargate_profile_name : module.fargate_profile_label.id + + fargate_profile_iam_role_name = var.fargate_profile_iam_role_name != null ? var.fargate_profile_iam_role_name : ( + "${module.role_label.id}${var.iam_role_kubernetes_namespace_delimiter}${var.kubernetes_namespace}") } -data "aws_partition" "current" { - count = local.enabled ? 1 : 0 +module "fargate_profile_label" { + source = "cloudposse/label/null" + version = "0.25.0" + + # Append the provided Kubernetes namespace to the Fargate Profile name + attributes = [var.kubernetes_namespace] + + tags = local.tags + + context = module.this.context } -module "label" { +module "role_label" { source = "cloudposse/label/null" version = "0.25.0" - attributes = compact(concat(module.this.attributes, ["fargate"])) - tags = local.tags + # Append 'fargate' to the Fargate Role name to specify that the role is for Fargate + attributes = ["fargate"] + + tags = local.tags context = module.this.context } +data "aws_partition" "current" { + count = local.enabled ? 1 : 0 +} + data "aws_iam_policy_document" "assume_role" { count = local.enabled ? 1 : 0 @@ -40,9 +59,9 @@ data "aws_iam_policy_document" "assume_role" { resource "aws_iam_role" "default" { count = local.enabled ? 1 : 0 - name = "${module.label.id}${var.iam_role_kubernetes_namespace_delimiter}${var.kubernetes_namespace}" + name = local.fargate_profile_iam_role_name assume_role_policy = join("", data.aws_iam_policy_document.assume_role.*.json) - tags = module.label.tags + tags = module.role_label.tags permissions_boundary = var.permissions_boundary } @@ -57,10 +76,10 @@ resource "aws_eks_fargate_profile" "default" { count = local.enabled ? 1 : 0 cluster_name = var.cluster_name - fargate_profile_name = module.label.id + fargate_profile_name = local.fargate_profile_name pod_execution_role_arn = join("", aws_iam_role.default.*.arn) subnet_ids = var.subnet_ids - tags = module.label.tags + tags = module.fargate_profile_label.tags selector { namespace = var.kubernetes_namespace diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 4871689..32905f2 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -143,7 +143,7 @@ func TestExamplesComplete(t *testing.T) { // Run `terraform output` to get the value of an output variable eksFargateProfileId := terraform.Output(t, terraformOptions, "eks_fargate_profile_id") // Verify we're getting back the outputs we expect - assert.Equal(t, "eg-test-eks-fargate-"+randID+"-cluster:eg-test-eks-fargate-"+randID+"-fargate", eksFargateProfileId) + assert.Equal(t, "eg-test-eks-fargate-"+randID+"-cluster:eg-test-eks-fargate-"+randID+"-default", eksFargateProfileId) // Run `terraform output` to get the value of an output variable eksFargateProfileRoleName := terraform.Output(t, terraformOptions, "eks_fargate_profile_role_name") diff --git a/variables.tf b/variables.tf index 7bdf367..b2c630e 100644 --- a/variables.tf +++ b/variables.tf @@ -4,8 +4,8 @@ variable "cluster_name" { } variable "subnet_ids" { - description = "Identifiers of private EC2 Subnets to associate with the EKS Fargate Profile. These subnets must have the following resource tag: kubernetes.io/cluster/CLUSTER_NAME (where CLUSTER_NAME is replaced with the name of the EKS Cluster)" type = list(string) + description = "Identifiers of private EC2 Subnets to associate with the EKS Fargate Profile. These subnets must have the following resource tag: kubernetes.io/cluster/CLUSTER_NAME (where CLUSTER_NAME is replaced with the name of the EKS Cluster)" } variable "kubernetes_namespace" { @@ -27,6 +27,18 @@ variable "iam_role_kubernetes_namespace_delimiter" { variable "permissions_boundary" { type = string + description = "If provided, all IAM roles will be created with this permissions boundary attached" + default = null +} + +variable "fargate_profile_name" { + type = string + description = "Fargate profile name. If not provided, will be derived from the context" + default = null +} + +variable "fargate_profile_iam_role_name" { + type = string + description = "Fargate profile IAM role name. If not provided, will be derived from the context" default = null - description = "If provided, all IAM roles will be created with this permissions boundary attached." }