diff --git a/.github/workflows/linter-analysis.yaml b/.github/workflows/linter-analysis.yaml index b4454d04..a7a4407a 100644 --- a/.github/workflows/linter-analysis.yaml +++ b/.github/workflows/linter-analysis.yaml @@ -58,11 +58,16 @@ jobs: # with the plugin, not needed for regular project use. - name: Initializing modules run: | + terraform init terraform -chdir=modules/aws_autoscaling init + terraform -chdir=modules/aws_fsx_ontap init terraform -chdir=modules/aws_ebs_csi init + terraform -chdir=modules/aws_vm init + terraform -chdir=modules/aws_vpc init + terraform -chdir=modules/kubeconfig init - name: Initializing TFLint - run: TFLINT_LOG=info tflint --init -c "$(pwd)/linting-configs/.tflint.hcl" + run: TFLINT_LOG=info tflint --recursive --init -c "$(pwd)/linting-configs/.tflint.hcl" - name: Run TFLint Action run: TFLINT_LOG=info tflint -c "$(pwd)/linting-configs/.tflint.hcl" --recursive diff --git a/Dockerfile b/Dockerfile index 0d95a637..ce1296a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,20 +2,28 @@ ARG TERRAFORM_VERSION=1.9.6 ARG AWS_CLI_VERSION=2.17.58 FROM hashicorp/terraform:$TERRAFORM_VERSION AS terraform +FROM almalinux:minimal AS amin +WORKDIR /app +USER root +ARG KUBECTL_VERSION=1.30.6 +ARG KUBECTL_CHECKSUM=7a3adf80ca74b1b2afdfc7f4570f0005ca03c2812367ffb6ee2f731d66e45e61 +RUN /usr/bin/bash -eux \ + && curl -fSLO https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl \ + && chmod 755 ./kubectl \ + && sha256sum --check --strict <(echo ${KUBECTL_CHECKSUM} kubectl) + FROM amazon/aws-cli:$AWS_CLI_VERSION -ARG KUBECTL_VERSION=1.29.8 WORKDIR /viya4-iac-aws +COPY --from=amin /app/kubectl /usr/local/bin/kubectl COPY --from=terraform /bin/terraform /bin/terraform COPY . . RUN yum -y install git openssh jq which \ && yum -y update openssl-libs glib2 vim-minimal vim-data curl \ && yum clean all && rm -rf /var/cache/yum \ - && curl -sLO https://storage.googleapis.com/kubernetes-release/release/v$KUBECTL_VERSION/bin/linux/amd64/kubectl \ - && chmod 755 ./kubectl /viya4-iac-aws/docker-entrypoint.sh \ - && mv ./kubectl /usr/local/bin/kubectl \ + && chmod 755 /viya4-iac-aws/docker-entrypoint.sh \ && git config --system --add safe.directory /viya4-iac-aws \ && terraform init \ && chmod g=u -R /etc/passwd /etc/group /viya4-iac-aws diff --git a/README.md b/README.md index 3a317d99..6187ccfd 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ The following are also required: #### Terraform Requirements: - [Terraform](https://www.terraform.io/downloads.html) v1.9.6 -- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) - v1.29.8 +- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) - v1.30.6 - [jq](https://stedolan.github.io/jq/) v1.6 - [AWS CLI](https://aws.amazon.com/cli) (optional; useful as an alternative to the AWS Web Console) v2.17.58 diff --git a/docs/CONFIG-VARS.md b/docs/CONFIG-VARS.md index 5e736322..19420fd9 100644 --- a/docs/CONFIG-VARS.md +++ b/docs/CONFIG-VARS.md @@ -257,7 +257,7 @@ Custom policy: |
Name
|
Description
|
Type
|
Default
|
Notes
| | :--- | :--- | :--- | :--- | :--- | | create_static_kubeconfig | Allows the user to create a provider- or service account-based kubeconfig file | bool | true | A value of `false` defaults to using the cloud provider's mechanism for generating the kubeconfig file. A value of `true` creates a static kubeconfig that uses a service account and cluster role binding to provide credentials. | -| kubernetes_version | The EKS cluster Kubernetes version | string | "1.29" | | +| kubernetes_version | The EKS cluster Kubernetes version | string | "1.30" | | | create_jump_vm | Create bastion host (jump VM) | bool | true| | | create_jump_public_ip | Add public IP address to jump VM | bool | true | | | jump_vm_admin | OS admin user for the jump VM | string | "jumpuser" | | diff --git a/examples/sample-input-byo.tfvars b/examples/sample-input-byo.tfvars index 4d51be85..4480b756 100644 --- a/examples/sample-input-byo.tfvars +++ b/examples/sample-input-byo.tfvars @@ -37,7 +37,7 @@ postgres_servers = { } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 2 default_nodepool_vm_type = "m5.2xlarge" default_nodepool_custom_data = "" diff --git a/examples/sample-input-connect.tfvars b/examples/sample-input-connect.tfvars index 04d178e1..09a03035 100644 --- a/examples/sample-input-connect.tfvars +++ b/examples/sample-input-connect.tfvars @@ -27,7 +27,7 @@ postgres_servers = { } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 2 default_nodepool_vm_type = "m5.2xlarge" default_nodepool_custom_data = "" diff --git a/examples/sample-input-custom-data.tfvars b/examples/sample-input-custom-data.tfvars index 4de8346b..640990dc 100644 --- a/examples/sample-input-custom-data.tfvars +++ b/examples/sample-input-custom-data.tfvars @@ -27,7 +27,7 @@ postgres_servers = { } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 2 default_nodepool_vm_type = "m5.2xlarge" default_nodepool_custom_data = "" diff --git a/examples/sample-input-gpu.tfvars b/examples/sample-input-gpu.tfvars index a47a493d..2e1de0b7 100644 --- a/examples/sample-input-gpu.tfvars +++ b/examples/sample-input-gpu.tfvars @@ -27,7 +27,7 @@ postgres_servers = { } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 2 default_nodepool_vm_type = "m5.2xlarge" default_nodepool_custom_data = "" diff --git a/examples/sample-input-ha.tfvars b/examples/sample-input-ha.tfvars index 587c6be2..5bbe63ec 100644 --- a/examples/sample-input-ha.tfvars +++ b/examples/sample-input-ha.tfvars @@ -27,7 +27,7 @@ postgres_servers = { } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 2 default_nodepool_vm_type = "m5.2xlarge" default_nodepool_custom_data = "" diff --git a/examples/sample-input-minimal.tfvars b/examples/sample-input-minimal.tfvars index 3d36f70c..592ea798 100644 --- a/examples/sample-input-minimal.tfvars +++ b/examples/sample-input-minimal.tfvars @@ -27,7 +27,7 @@ tags = {} # e.g., { "key1" = "value1", "key2" = "value2" } # } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 1 default_nodepool_vm_type = "m5.large" default_nodepool_custom_data = "" diff --git a/examples/sample-input-singlestore.tfvars b/examples/sample-input-singlestore.tfvars index cd4b5baa..7d3fef4e 100644 --- a/examples/sample-input-singlestore.tfvars +++ b/examples/sample-input-singlestore.tfvars @@ -27,7 +27,7 @@ postgres_servers = { } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 2 default_nodepool_vm_type = "m5.2xlarge" default_nodepool_custom_data = "" diff --git a/examples/sample-input.tfvars b/examples/sample-input.tfvars index 656f1b04..df70cd60 100644 --- a/examples/sample-input.tfvars +++ b/examples/sample-input.tfvars @@ -27,7 +27,7 @@ postgres_servers = { } ## Cluster config -kubernetes_version = "1.29" +kubernetes_version = "1.30" default_nodepool_node_count = 2 default_nodepool_vm_type = "m5.2xlarge" default_nodepool_custom_data = "" diff --git a/linting-configs/.hadolint.yaml b/linting-configs/.hadolint.yaml index e3c7d2c0..c50f26c8 100644 --- a/linting-configs/.hadolint.yaml +++ b/linting-configs/.hadolint.yaml @@ -5,3 +5,5 @@ ignored: # Specify version with yum install -y - - https://github.com/hadolint/hadolint/wiki/DL3033 - DL3033 + - DL3002 + - SC3001 diff --git a/linting-configs/.tflint.hcl b/linting-configs/.tflint.hcl index 024d17eb..88351afd 100644 --- a/linting-configs/.tflint.hcl +++ b/linting-configs/.tflint.hcl @@ -13,12 +13,13 @@ config { plugin "aws" { enabled = true - version = "0.27.0" + version = "0.34.0" source = "github.com/terraform-linters/tflint-ruleset-aws" } plugin "terraform" { enabled = true + preset = "recommended" } # Disallow // comments in favor of #. @@ -56,37 +57,10 @@ rule "terraform_module_version" { enabled = true } -# Enforces naming conventions +## Enforces naming conventions rule "terraform_naming_convention" { - enabled = true - custom = "^([a-zA-Z0-9])+([_-][a-zA-Z0-9]+)*$" - -#Require specific naming structure - -# variable { -# format = "snake_case" -# } - -# locals { -# format = "snake_case" -# } - -# output { -# format = "snake_case" -# } - -#Allow any format -# resource { -# format = "none" -# } - -# module { -# format = "none" -# } - -# data { -# format = "none" -# } + enabled = false +# custom = "^([a-zA-Z0-9])+([_-][a-zA-Z0-9]+)*$" } diff --git a/locals.tf b/locals.tf index e3f57521..ccebde10 100755 --- a/locals.tf +++ b/locals.tf @@ -7,8 +7,7 @@ locals { aws_caller_identity_user_name = element(split("/", data.aws_caller_identity.terraform.arn), length(split("/", data.aws_caller_identity.terraform.arn)) - 1) # General - sec_group = (length(aws_security_group.sg_a) == 0 && length(aws_security_group.sg_b) == 0) ? null : coalescelist(aws_security_group.sg_a, aws_security_group.sg_b) - security_group_id = var.security_group_id == null ? local.sec_group[0].id : data.aws_security_group.sg[0].id + security_group_id = var.security_group_id == null ? aws_security_group.sg[0].id : data.aws_security_group.sg[0].id cluster_security_group_id = var.cluster_security_group_id == null ? aws_security_group.cluster_security_group[0].id : var.cluster_security_group_id workers_security_group_id = var.workers_security_group_id == null ? aws_security_group.workers_security_group[0].id : var.workers_security_group_id cluster_name = "${var.prefix}-eks" @@ -166,7 +165,16 @@ locals { postgres_servers = var.postgres_servers == null ? {} : { for k, v in var.postgres_servers : k => merge(var.postgres_server_defaults, v, ) } postgres_sgr_ports = var.postgres_servers != null ? length(local.postgres_servers) != 0 ? [for k, v in local.postgres_servers : v.server_port - ] : [] : null + ] : [] : [] + postgres_cidr_port_pairs = setproduct(local.postgres_sgr_ports, local.postgres_public_access_cidrs) + + ingress_pairs = length(local.postgres_cidr_port_pairs) != 0 ? { for pair in local.postgres_cidr_port_pairs : + "${pair[0]}-${pair[1]}" => { + "server_port" : pair[0], + "cidr" : pair[1] + } + } : {} + postgres_outputs = length(module.postgresql) != 0 ? { for k, v in module.postgresql : k => { diff --git a/security.tf b/security.tf index 0153fbd9..1c129c85 100644 --- a/security.tf +++ b/security.tf @@ -6,224 +6,219 @@ data "aws_security_group" "sg" { id = var.security_group_id } +# Note: +# Using aws_vpc_security_group_egress_rule and aws_vpc_security_group_ingress_rule resources is the current best practice. +# Avoid using the aws_security_group_rule resource and the ingress and egress arguments of the aws_security_group resource +# for configuring in-line rules, as they struggle with managing multiple CIDR blocks, and tags and descriptions due to the +# historical lack of unique IDs. + # Security Groups - https://www.terraform.io/docs/providers/aws/r/security_group.html -resource "aws_security_group" "sg_a" { - count = var.security_group_id == null && var.vpc_private_endpoints_enabled == false ? 1 : 0 +resource "aws_security_group" "sg" { + count = var.security_group_id == null ? 1 : 0 name = "${var.prefix}-sg" vpc_id = module.vpc.vpc_id description = "Auxiliary security group associated with RDS ENIs and VPC Endpoint ENIs as well as Jump/NFS VM ENIs when they have public IPs" - egress { - description = "Allow all outbound traffic." - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } + tags = merge(local.tags, { "Name" : "${var.prefix}-sg" }) } -# Security Groups - https://www.terraform.io/docs/providers/aws/r/security_group.html -resource "aws_security_group" "sg_b" { - count = var.security_group_id == null && var.vpc_private_endpoints_enabled ? 1 : 0 - name = "${var.prefix}-sg" - vpc_id = module.vpc.vpc_id +resource "aws_vpc_security_group_egress_rule" "sg" { + + security_group_id = local.security_group_id + + description = "Allow all outbound traffic." + ip_protocol = "-1" + cidr_ipv4 = "0.0.0.0/0" - description = "Auxiliary security group associated with RDS ENIs and VPC Endpoint ENIs as well as Jump/NFS VM ENIs when they have public IPs" - egress { - description = "Allow all outbound traffic." - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - ingress { - description = "Allow tcp port 443 ingress to all AWS Services targeted by the VPC endpoints" - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = local.vpc_endpoint_private_access_cidrs - } tags = merge(local.tags, { "Name" : "${var.prefix}-sg" }) } -resource "aws_security_group_rule" "vms" { - count = (length(local.vm_public_access_cidrs) > 0 - && var.security_group_id == null - && ((var.create_jump_public_ip && var.create_jump_vm) - || (var.create_nfs_public_ip && var.storage_type == "standard") - ) - ? 1 : 0 - ) - type = "ingress" - description = "Allow SSH from source" - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = local.vm_public_access_cidrs +# Only create this/these ingress rule(s) if we are using VPC Endpoints +# Creates an ingress rules for each vpc_endpoint_private_access_cidrs in the list +resource "aws_vpc_security_group_ingress_rule" "sg" { + + for_each = var.security_group_id == null && var.vpc_private_endpoints_enabled ? toset(local.vpc_endpoint_private_access_cidrs) : toset([]) + security_group_id = local.security_group_id + description = "Allow tcp port 443 ingress to all AWS Services targeted by the VPC endpoints" + ip_protocol = "tcp" + from_port = 443 + to_port = 443 + cidr_ipv4 = each.key + + tags = merge(local.tags, { "Name" : "${var.prefix}-sg" }) } -resource "aws_security_group_rule" "all" { - type = "ingress" - description = "Allow internal security group communication." - from_port = 0 - to_port = 0 - protocol = "all" +resource "aws_vpc_security_group_ingress_rule" "vms" { + + for_each = var.security_group_id == null && ((var.create_jump_public_ip && var.create_jump_vm)) ? toset(local.vm_public_access_cidrs) : toset([]) + security_group_id = local.security_group_id - self = true -} + description = "Allow SSH from source" + from_port = 22 + to_port = 22 + ip_protocol = "tcp" + cidr_ipv4 = each.key +} -resource "aws_security_group_rule" "postgres_internal" { - for_each = local.postgres_sgr_ports != null ? toset(local.postgres_sgr_ports) : toset([]) - type = "ingress" - description = "Allow Postgres within network" - from_port = each.key - to_port = each.key - protocol = "tcp" - self = true +resource "aws_vpc_security_group_ingress_rule" "all" { security_group_id = local.security_group_id + + description = "Allow internal security group communication." + ip_protocol = "-1" + referenced_security_group_id = local.security_group_id } -resource "aws_security_group_rule" "postgres_external" { +resource "aws_vpc_security_group_ingress_rule" "postgres_internal" { + + for_each = local.postgres_sgr_ports != null ? toset(local.postgres_sgr_ports) : toset([]) + + description = "Allow Postgress within network" + from_port = each.key + to_port = each.key + ip_protocol = "tcp" + security_group_id = local.security_group_id + referenced_security_group_id = local.security_group_id +} + +resource "aws_vpc_security_group_ingress_rule" "postgres_external" { + for_each = (length(local.postgres_public_access_cidrs) > 0 ? local.postgres_sgr_ports != null - ? toset(local.postgres_sgr_ports) - : toset([]) - : toset([]) + ? local.ingress_pairs + : {} + : {} ) - type = "ingress" + description = "Allow Postgres from source" - from_port = each.key - to_port = each.key - protocol = "tcp" - cidr_blocks = local.postgres_public_access_cidrs + from_port = each.value.server_port + to_port = each.value.server_port + ip_protocol = "tcp" + cidr_ipv4 = each.value.cidr security_group_id = local.security_group_id } - resource "aws_security_group" "cluster_security_group" { - name = "${var.prefix}-eks_cluster_sg" - vpc_id = module.vpc.vpc_id - tags = merge(local.tags, { "Name" : "${var.prefix}-eks_cluster_sg" }) count = var.cluster_security_group_id == null ? 1 : 0 + name = "${var.prefix}-eks_cluster_sg" + vpc_id = module.vpc.vpc_id description = "EKS cluster security group." - egress { - description = "Allow all outbound traffic." - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - ingress { - description = "Allow additional HTTPS/443 ingress to private EKS cluster API server endpoint per var.cluster_endpoint_private_access_cidrs" - from_port = 443 - to_port = 443 - protocol = "tcp" - cidr_blocks = local.cluster_endpoint_private_access_cidrs - } + + tags = merge(local.tags, { "Name" : "${var.prefix}-eks_cluster_sg" }) } -resource "aws_security_group_rule" "cluster_ingress" { +resource "aws_vpc_security_group_egress_rule" "cluster_security_group" { + + count = var.cluster_security_group_id == null ? 1 : 0 + + description = "Allow all outbound traffic." + ip_protocol = "-1" + cidr_ipv4 = "0.0.0.0/0" + security_group_id = local.cluster_security_group_id +} + +resource "aws_vpc_security_group_ingress_rule" "cluster_security_group" { + + for_each = var.cluster_security_group_id == null ? toset(local.cluster_endpoint_private_access_cidrs) : toset([]) + + description = "Allow additional HTTPS/443 ingress to private EKS cluster API server endpoint per var.cluster_endpoint_private_access_cidrs" + from_port = 443 + to_port = 443 + ip_protocol = "tcp" + cidr_ipv4 = each.key + security_group_id = local.cluster_security_group_id +} + + +resource "aws_vpc_security_group_ingress_rule" "cluster_ingress" { count = var.cluster_security_group_id == null ? 1 : 0 - type = "ingress" - description = "Allow pods to communicate with the EKS cluster API." - from_port = 443 - to_port = 443 - protocol = "tcp" - source_security_group_id = local.workers_security_group_id - security_group_id = local.cluster_security_group_id + description = "Allow pods to communicate with the EKS cluster API." + from_port = 443 + to_port = 443 + ip_protocol = "tcp" + referenced_security_group_id = local.workers_security_group_id + security_group_id = local.cluster_security_group_id } resource "aws_security_group" "workers_security_group" { - name = "${var.prefix}-eks_worker_sg" - vpc_id = module.vpc.vpc_id + + count = var.workers_security_group_id == null ? 1 : 0 + + description = "Security group for all nodes in the cluster." + name = "${var.prefix}-eks_worker_sg" + vpc_id = module.vpc.vpc_id tags = merge(local.tags, { "Name" : "${var.prefix}-eks_worker_sg" }, { "kubernetes.io/cluster/${local.cluster_name}" : "owned" } ) +} + +resource "aws_vpc_security_group_egress_rule" "workers_security_group" { count = var.workers_security_group_id == null ? 1 : 0 - description = "Security group for all nodes in the cluster." - egress = [ - { - cidr_blocks = [ - "0.0.0.0/0", - ] - ipv6_cidr_blocks = [] - prefix_list_ids = [] - self = false - security_groups = [] - description = "Allow cluster egress access to the Internet." - from_port = 0 - to_port = 0 - protocol = "-1" - }, - ] - -} - -resource "aws_security_group_rule" "worker_self" { + cidr_ipv4 = "0.0.0.0/0" + security_group_id = local.workers_security_group_id + description = "Allow cluster egress access to the Internet." + ip_protocol = "-1" + +} + +resource "aws_vpc_security_group_ingress_rule" "worker_self" { count = var.workers_security_group_id == null ? 1 : 0 - type = "ingress" - description = "Allow node to communicate with each other." - from_port = 0 - protocol = "-1" - self = true - to_port = 0 - security_group_id = aws_security_group.workers_security_group[0].id + description = "Allow node to communicate with each other." + ip_protocol = "-1" + referenced_security_group_id = aws_security_group.workers_security_group[0].id + security_group_id = aws_security_group.workers_security_group[0].id } -resource "aws_security_group_rule" "worker_cluster_api" { +resource "aws_vpc_security_group_ingress_rule" "worker_cluster_api" { count = var.workers_security_group_id == null ? 1 : 0 - type = "ingress" - description = "Allow worker pods to receive communication from the cluster control plane." - from_port = 1025 - protocol = "tcp" - source_security_group_id = local.cluster_security_group_id - to_port = 65535 - security_group_id = aws_security_group.workers_security_group[0].id + description = "Allow worker pods to receive communication from the cluster control plane." + from_port = 1025 + to_port = 65535 + ip_protocol = "tcp" + referenced_security_group_id = local.cluster_security_group_id + security_group_id = aws_security_group.workers_security_group[0].id } -resource "aws_security_group_rule" "worker_cluster_api_443" { +resource "aws_vpc_security_group_ingress_rule" "worker_cluster_api_443" { count = var.workers_security_group_id == null ? 1 : 0 - type = "ingress" - description = "Allow pods running extension API servers on port 443 to receive communication from cluster control plane." - from_port = 443 - protocol = "tcp" - source_security_group_id = local.cluster_security_group_id - to_port = 443 - security_group_id = aws_security_group.workers_security_group[0].id + description = "Allow pods running extension API servers on port 443 to receive communication from cluster control plane." + from_port = 443 + to_port = 443 + ip_protocol = "tcp" + referenced_security_group_id = local.cluster_security_group_id + security_group_id = aws_security_group.workers_security_group[0].id } +# TODO: Make sure tags are applied to all resources -resource "aws_security_group_rule" "vm_private_access_22" { +resource "aws_vpc_security_group_ingress_rule" "vm_private_access_22" { - count = (length(local.vm_private_access_cidrs) > 0 + for_each = (length(local.vm_private_access_cidrs) > 0 && var.workers_security_group_id == null && ((var.create_jump_public_ip == false && var.create_jump_vm) - || (var.create_nfs_public_ip == false && var.storage_type == "standard") - ) - ? 1 : 0 + || (var.create_nfs_public_ip == false && var.storage_type == "standard")) ? toset(local.vm_private_access_cidrs) : toset([]) ) - type = "ingress" + description = "Allow SSH to a private IP based Jump VM per var.vm_private_access_cidrs. Required for DAC baseline client VM." from_port = 22 to_port = 22 - protocol = "tcp" - cidr_blocks = local.vm_private_access_cidrs + ip_protocol = "tcp" + cidr_ipv4 = each.key security_group_id = aws_security_group.workers_security_group[0].id } diff --git a/variables.tf b/variables.tf index afb628c0..713867ca 100644 --- a/variables.tf +++ b/variables.tf @@ -149,7 +149,7 @@ variable "efs_throughput_rate" { variable "kubernetes_version" { description = "The EKS cluster Kubernetes version." type = string - default = "1.29" + default = "1.30" } variable "tags" {