Skip to content

Commit

Permalink
Allow overriding Fargate Profile name and Fargate Role name. Update F…
Browse files Browse the repository at this point in the history
…argate 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
  • Loading branch information
aknysh authored May 24, 2022
1 parent 3d415f5 commit 9ee484a
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 27 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Local .terraform directories
**/.terraform/*
**/.terraform

# .tfstate files
*.tfstate
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ Available targets:

| Name | Source | Version |
|------|--------|---------|
| <a name="module_label"></a> [label](#module\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_fargate_profile_label"></a> [fargate\_profile\_label](#module\_fargate\_profile\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_role_label"></a> [role\_label](#module\_role\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_this"></a> [this](#module\_this) | cloudposse/label/null | 0.25.0 |

## Resources
Expand All @@ -341,6 +342,8 @@ Available targets:
| <a name="input_descriptor_formats"></a> [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.<br>Map of maps. Keys are names of descriptors. Values are maps of the form<br>`{<br> format = string<br> labels = list(string)<br>}`<br>(Type is `any` so the map values can later be enhanced to provide additional options.)<br>`format` is a Terraform format string to be passed to the `format()` function.<br>`labels` is a list of labels, in order, to pass to `format()` function.<br>Label values will be normalized before being passed to `format()` so they will be<br>identical to how they appear in `id`.<br>Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| <a name="input_fargate_profile_iam_role_name"></a> [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 |
| <a name="input_fargate_profile_name"></a> [fargate\_profile\_name](#input\_fargate\_profile\_name) | Fargate profile name. If not provided, will be derived from the context | `string` | `null` | no |
| <a name="input_iam_role_kubernetes_namespace_delimiter"></a> [iam\_role\_kubernetes\_namespace\_delimiter](#input\_iam\_role\_kubernetes\_namespace\_delimiter) | Delimiter for the Kubernetes namespace in the IAM Role name | `string` | `"-"` | no |
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for keep the existing setting, which defaults to `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| <a name="input_kubernetes_labels"></a> [kubernetes\_labels](#input\_kubernetes\_labels) | Key-value mapping of Kubernetes labels for selection | `map(string)` | `{}` | no |
Expand All @@ -351,7 +354,7 @@ Available targets:
| <a name="input_labels_as_tags"></a> [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.<br>Default is to include all labels.<br>Tags with empty values will not be included in the `tags` output.<br>Set to `[]` to suppress all generated tags.<br>**Notes:**<br> The value of the `name` tag, if included, will be the `id`, not the `name`.<br> Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be<br> changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | <pre>[<br> "default"<br>]</pre> | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [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 |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached. | `string` | `null` | no |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached | `string` | `null` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_subnet_ids"></a> [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 |
Expand Down
7 changes: 5 additions & 2 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

| Name | Source | Version |
|------|--------|---------|
| <a name="module_label"></a> [label](#module\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_fargate_profile_label"></a> [fargate\_profile\_label](#module\_fargate\_profile\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_role_label"></a> [role\_label](#module\_role\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_this"></a> [this](#module\_this) | cloudposse/label/null | 0.25.0 |

## Resources
Expand All @@ -41,6 +42,8 @@
| <a name="input_descriptor_formats"></a> [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.<br>Map of maps. Keys are names of descriptors. Values are maps of the form<br>`{<br> format = string<br> labels = list(string)<br>}`<br>(Type is `any` so the map values can later be enhanced to provide additional options.)<br>`format` is a Terraform format string to be passed to the `format()` function.<br>`labels` is a list of labels, in order, to pass to `format()` function.<br>Label values will be normalized before being passed to `format()` so they will be<br>identical to how they appear in `id`.<br>Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| <a name="input_fargate_profile_iam_role_name"></a> [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 |
| <a name="input_fargate_profile_name"></a> [fargate\_profile\_name](#input\_fargate\_profile\_name) | Fargate profile name. If not provided, will be derived from the context | `string` | `null` | no |
| <a name="input_iam_role_kubernetes_namespace_delimiter"></a> [iam\_role\_kubernetes\_namespace\_delimiter](#input\_iam\_role\_kubernetes\_namespace\_delimiter) | Delimiter for the Kubernetes namespace in the IAM Role name | `string` | `"-"` | no |
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for keep the existing setting, which defaults to `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| <a name="input_kubernetes_labels"></a> [kubernetes\_labels](#input\_kubernetes\_labels) | Key-value mapping of Kubernetes labels for selection | `map(string)` | `{}` | no |
Expand All @@ -51,7 +54,7 @@
| <a name="input_labels_as_tags"></a> [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.<br>Default is to include all labels.<br>Tags with empty values will not be included in the `tags` output.<br>Set to `[]` to suppress all generated tags.<br>**Notes:**<br> The value of the `name` tag, if included, will be the `id`, not the `name`.<br> Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be<br> changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | <pre>[<br> "default"<br>]</pre> | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| <a name="input_namespace"></a> [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 |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached. | `string` | `null` | no |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | If provided, all IAM roles will be created with this permissions boundary attached | `string` | `null` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_subnet_ids"></a> [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 |
Expand Down
2 changes: 2 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
34 changes: 23 additions & 11 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand Down Expand Up @@ -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" {
Expand All @@ -99,35 +99,35 @@ 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 = (
length(var.ec2_ssh_key_name) < 2
)
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 = (
length(var.after_cluster_joining_userdata) < 2
)
error_message = "You may not specify more than one `after_cluster_joining_userdata`."
}
default = []
}

variable "ami_type" {
Expand All @@ -136,29 +136,41 @@ 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 = (
length(var.ami_release_version) == 0 ? true : length(regexall("^\\d+\\.\\d+\\.\\d+-[\\da-z]+$", var.ami_release_version[0])) == 1
)
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
}
37 changes: 28 additions & 9 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
}

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/src/examples_complete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Loading

0 comments on commit 9ee484a

Please sign in to comment.