diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5ff3c08..d921b00 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.4.0 hooks: - id: check-added-large-files args: ['--maxkb=500'] @@ -17,8 +17,8 @@ repos: - id: detect-aws-credentials args: ['--allow-missing-credentials'] - id: trailing-whitespace -- repo: git://github.com/antonbabenko/pre-commit-terraform - rev: 48bc03ca3f0f2f782d2f430069868019a6892062 +- repo: https://github.com/antonbabenko/pre-commit-terraform + rev: v1.79.1 hooks: - id: terraform_fmt - id: terraform_docs diff --git a/README.md b/README.md index c8fe39e..ec61d8d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Terraform module to provision EKS Managed Node Group ```hcl module "eks-node-group" { source = "native-cube/eks-node-group/aws" - version = "~> 1.0.0" + version = "~> 1.1.0" cluster_name = aws_eks_cluster.cluster.id @@ -61,13 +61,13 @@ module "eks-node-group" { | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0.0 | -| [aws](#requirement\_aws) | >= 4.0.0 | +| [aws](#requirement\_aws) | >= 4.64.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 4.0.0 | +| [aws](#provider\_aws) | >= 4.64.0 | ## Modules @@ -78,6 +78,7 @@ No modules. | Name | Type | |------|------| | [aws_eks_node_group.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group) | resource | +| [aws_eks_node_group.main_create_before_destroy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group) | resource | | [aws_iam_role.main](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | ## Inputs @@ -88,6 +89,7 @@ No modules. | [ami\_type](#input\_ami\_type) | Type of Amazon Machine Image (AMI) associated with the EKS Node Group. Valid values: AL2\_x86\_64 \| AL2\_x86\_64\_GPU \| AL2\_ARM\_64 \| CUSTOM \| BOTTLEROCKET\_ARM\_64 \| BOTTLEROCKET\_x86\_64. Terraform will only perform drift detection if a configuration value is provided. | `string` | `null` | no | | [capacity\_type](#input\_capacity\_type) | Type of capacity associated with the EKS Node Group. Defaults to ON\_DEMAND. Valid values: ON\_DEMAND, SPOT. | `string` | `"ON_DEMAND"` | no | | [cluster\_name](#input\_cluster\_name) | The name of the EKS cluster. | `string` | n/a | yes | +| [create\_before\_destroy](#input\_create\_before\_destroy) | Create new node group before destroying an old one. To be used with node\_group\_name\_prefix argument. | `bool` | `false` | no | | [create\_iam\_role](#input\_create\_iam\_role) | Create IAM role for node group. Set to false if pass `node_role_arn` as an argument | `bool` | `true` | no | | [desired\_size](#input\_desired\_size) | Desired number of worker nodes. | `number` | n/a | yes | | [disk\_size](#input\_disk\_size) | Disk size in GiB for worker nodes. Defaults to 20. Terraform will only perform drift detection if a configuration value is provided. | `number` | `null` | no | @@ -108,6 +110,7 @@ No modules. | [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch resources in. | `list(string)` | n/a | yes | | [tags](#input\_tags) | A map of tags (key-value pairs) passed to resources. | `map(string)` | `{}` | no | | [taints](#input\_taints) | List of objects containing Kubernetes taints which will be applied to the nodes in the node group. Maximum of 50 taints per node group. | `list(object({ key = string, value = any, effect = string }))` | `[]` | no | +| [timeouts](#input\_timeouts) | Create, update, and delete timeout configurations for the node group | `map(string)` | `{}` | no | | [update\_config](#input\_update\_config) | Update config configuration block which is a key-value map. Accepted argmuents are `max_unavailable` and `max_unavailable_percentage`. | `map(any)` | `{}` | no | ## Outputs diff --git a/examples/single-node-group-with-launch-template/versions.tf b/examples/single-node-group-with-launch-template/versions.tf new file mode 100644 index 0000000..3b23820 --- /dev/null +++ b/examples/single-node-group-with-launch-template/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.64.0" + } + } +} diff --git a/examples/single-node-group/versions.tf b/examples/single-node-group/versions.tf new file mode 100644 index 0000000..3b23820 --- /dev/null +++ b/examples/single-node-group/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.64.0" + } + } +} diff --git a/main.tf b/main.tf index 18b2965..bd09c52 100644 --- a/main.tf +++ b/main.tf @@ -1,9 +1,11 @@ resource "aws_eks_node_group" "main" { + count = var.create_before_destroy ? 0 : 1 + cluster_name = var.cluster_name node_group_name_prefix = var.node_group_name_prefix node_group_name = var.node_group_name - node_role_arn = var.node_role_arn == null ? join("", aws_iam_role.main.*.arn) : var.node_role_arn + node_role_arn = var.node_role_arn == null ? aws_iam_role.main[0].arn : var.node_role_arn subnet_ids = var.subnet_ids @@ -61,7 +63,94 @@ resource "aws_eks_node_group" "main" { } } + timeouts { + create = lookup(var.timeouts, "create", null) + update = lookup(var.timeouts, "update", null) + delete = lookup(var.timeouts, "delete", null) + } + + lifecycle { + ignore_changes = [ + scaling_config[0].desired_size + ] + } +} + +resource "aws_eks_node_group" "main_create_before_destroy" { + count = var.create_before_destroy ? 1 : 0 + + cluster_name = var.cluster_name + + node_group_name_prefix = var.node_group_name_prefix + node_group_name = var.node_group_name + node_role_arn = var.node_role_arn == null ? aws_iam_role.main[0].arn : var.node_role_arn + + subnet_ids = var.subnet_ids + + ami_type = var.ami_type + disk_size = var.disk_size + instance_types = var.instance_types + capacity_type = var.capacity_type + + labels = var.labels + + release_version = var.ami_release_version + version = var.kubernetes_version + + force_update_version = var.force_update_version + + tags = var.tags + + scaling_config { + desired_size = var.desired_size + max_size = var.max_size + min_size = var.min_size + } + + dynamic "taint" { + for_each = var.taints + content { + key = lookup(taint.value, "key") + value = lookup(taint.value, "value") + effect = lookup(taint.value, "effect") + } + } + + dynamic "remote_access" { + for_each = var.ec2_ssh_key != null || var.source_security_group_ids != null ? ["true"] : [] + content { + ec2_ssh_key = var.ec2_ssh_key + source_security_group_ids = var.source_security_group_ids + } + } + + dynamic "update_config" { + for_each = length(var.update_config) == 0 ? [] : [var.update_config] + content { + max_unavailable = lookup(update_config.value, "max_unavailable", null) + max_unavailable_percentage = lookup(update_config.value, "max_unavailable_percentage", null) + } + } + + dynamic "launch_template" { + for_each = length(var.launch_template) == 0 ? [] : [var.launch_template] + content { + id = lookup(launch_template.value, "id", null) + name = lookup(launch_template.value, "name", null) + version = lookup(launch_template.value, "version") + } + } + + timeouts { + create = lookup(var.timeouts, "create", null) + update = lookup(var.timeouts, "update", null) + delete = lookup(var.timeouts, "delete", null) + } + lifecycle { - ignore_changes = [scaling_config.0.desired_size] + create_before_destroy = true + ignore_changes = [ + scaling_config[0].desired_size + ] } } diff --git a/outputs.tf b/outputs.tf index 0a28922..005b373 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,14 +1,14 @@ output "iam_role_arn" { description = "IAM role ARN used by node group." - value = join("", aws_iam_role.main.*.arn) + value = try(aws_iam_role.main[0].arn, null) } output "iam_role_id" { description = "IAM role ID used by node group." - value = join("", aws_iam_role.main.*.id) + value = try(aws_iam_role.main[0].id, null) } output "node_group" { description = "Outputs from EKS node group. See `aws_eks_node_group` Terraform documentation for values" - value = aws_eks_node_group.main + value = var.create_before_destroy ? try(aws_eks_node_group.main_create_before_destroy[0], null) : try(aws_eks_node_group.main[0], null) } diff --git a/variables.tf b/variables.tf index afca795..9937c6c 100644 --- a/variables.tf +++ b/variables.tf @@ -142,3 +142,15 @@ variable "taints" { description = "List of objects containing Kubernetes taints which will be applied to the nodes in the node group. Maximum of 50 taints per node group." default = [] } + +variable "create_before_destroy" { + type = bool + description = "Create new node group before destroying an old one. To be used with node_group_name_prefix argument." + default = false +} + +variable "timeouts" { + description = "Create, update, and delete timeout configurations for the node group" + type = map(string) + default = {} +} diff --git a/versions.tf b/versions.tf index 97f0cf5..c7d3f4c 100644 --- a/versions.tf +++ b/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 4.0.0" + version = ">= 4.64.0" } } }