diff --git a/.github/renovate.json b/.github/renovate.json index 909df094..3156e540 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,6 +1,6 @@ { "extends": [ - "config:base", + "config:recommended", ":preserveSemverRanges", ":rebaseStalePrs" ], @@ -9,6 +9,18 @@ "dependencyDashboardAutoclose": true, "enabledManagers": ["terraform"], "terraform": { - "ignorePaths": ["**/context.tf"] - } + "ignorePaths": ["**/context.tf", "**/examples/obsolete*/**"] + }, + "timezone": "America/New_York", + "packageRules": [ + { + "matchFileNames": [ + "/*.tf", + "examples/complete/*.tf" + ], + "groupName": "all", + "schedule": ["every 4 weeks on wednesday at 04:00 am"], + "groupSlug": "monthly" + } + ] } diff --git a/LICENSE b/LICENSE index 7afefb95..861ef185 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2018-2023 Cloud Posse, LLC + Copyright 2018-2024 Cloud Posse, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index eca4d525..de1911df 100644 --- a/README.md +++ b/README.md @@ -45,154 +45,22 @@ Terraform module to provision an [EKS](https://aws.amazon.com/eks/) cluster on A The module provisions the following resources: -- EKS cluster of master nodes that can be used together with the [terraform-aws-eks-workers](https://github.com/cloudposse/terraform-aws-eks-workers), +- EKS cluster of master nodes that can be used together with the [terraform-aws-eks-node-group](https://github.com/cloudposse/terraform-aws-eks-node-group) and [terraform-aws-eks-fargate-profile](https://github.com/cloudposse/terraform-aws-eks-fargate-profile) - modules to create a full-blown cluster + modules to create a full-blown EKS/Kubernetes cluster. You can also use the [terraform-aws-eks-workers](https://github.com/cloudposse/terraform-aws-eks-workers) + module to provision worker nodes for the cluster, but it is now rare for that to be a better choice than to use `terraform-aws-eks-node-group`. - IAM Role to allow the cluster to access other AWS services -- Optionally, the module creates and automatically applies an authentication ConfigMap (`aws-auth`) to allow the - worker nodes to join the cluster and to add additional users/roles/accounts. (This option is enabled - by default, but has some caveats noted below. Set `apply_config_map_aws_auth` to `false` to avoid these issues.) +- EKS access entries to allow IAM users to access and administer the cluster -> [!WARNING] -> Release `2.0.0` (previously released as version `0.45.0`) contains some changes that -> could result in your existing EKS cluster being replaced (destroyed and recreated). -> To prevent this, follow the instructions in the [v1 to v2 migration path](./docs/migration-v1-v2.md). - -> [!NOTE] -> Every Terraform module that provisions an EKS cluster has faced the challenge that access to the cluster -> is partly controlled by a resource inside the cluster, a ConfigMap called `aws-auth`. You need to be able to access -> the cluster through the Kubernetes API to modify the ConfigMap, because -> [there is no AWS API for it](https://github.com/aws/containers-roadmap/issues/185). This presents -> a problem: how do you authenticate to an API endpoint that you have not yet created? - -We use the Terraform Kubernetes provider to access the cluster, and it uses the same underlying library -that `kubectl` uses, so configuration is very similar. However, every kind of configuration we have tried -has failed at some point. -- An authentication token can be retrieved using the `aws_eks_cluster_auth` data source. This works as -long as the token does not expire while Terraform is running, and the token is refreshed during the "plan" -phase before trying to refresh the state, and the token does not expire in the interval between -"plan" and "apply". Unfortunately, failures of all these types have been seen. Nevertheless, -this is the only method that is compatible with Terraform Cloud, so it is the default. It is the only -method we fully support until AWS [provides an API for managing `aws-auth`](https://github.com/aws/containers-roadmap/issues/185). -- After creating the EKS cluster, you can generate a `KUBECONFIG` file that configures access to it. -This works most of the time, but if the file was present and used as part of the configuration to create -the cluster, and then the file gets deleted (as would happen in a CI system like Terraform Cloud), Terraform -would not cause the file to be regenerated in time to use it to refresh Terraform's state and the "plan" phase will fail. -So any `KUBECONFIG` file has to be managed separately. -- An authentication token can be retrieved on demand by using the `exec` feature of the Kubernetes provider -to call `aws eks get-token`. This requires that the `aws` CLI be installed and available to Terraform and that it -has access to sufficient credentials to perform the authentication and is configured to use them. When those -conditions are met, this is the most reliable method, and the one Cloud Posse prefers to use. However, since -it has these requirements that are not always easily met, it is not the default method and it is not -fully supported. - -All of the above methods can face additional challenges when using `terraform import` to import -resources into the Terraform state. The `KUBECONFIG` file method is the only sure way to `import` resources, due to -[Terraform limitations](https://github.com/hashicorp/terraform/issues/27934) on providers. You will need to create -the file, of course, but that is easily done with `aws eks update-kubeconfig`. Depending on the situation, -you may also be able to import resources by setting `-var apply_config_map_aws_auth=false` during import. - -At the moment, the `exec` option appears to be the most reliable method, so we recommend using it if possible, -but because of the extra requirements it has, we use the data source as the default authentication method. - -> [!IMPORTANT] -> All of the above methods require network connectivity between the host running the -> `terraform` command and the EKS endpoint. If your EKS cluster does not have public access enabled, this means -> you need to take extra steps, such as using a VPN to provide access to the private endpoint, or running -> `terraform` on a host in the same VPC as the EKS cluster. - -> [!WARNING] -> ### Failure during `destroy` -> -> If the cluster is destroyed (via Terraform or otherwise) before the Terraform resource -> responsible for the `aws-auth` ConfigMap is destroyed, Terraform will get stuck trying to delete the ConfigMap, -> because it cannot contact the now destroyed cluster. This can show up as a `connection refused` error (usually -> to `https://localhost/`). The easiest ways to handle this is either to add `-var apply_config_map_aws_auth=false` -> to the `destroy` command or to remove the ConfigMap (`...kubernetes_config_map.aws_auth[0]`) from the Terraform -> state with `terraform state rm`. -> [!NOTE] -> We give you the `kubernetes_config_map_ignore_role_changes` option and default it to `true` for the following reasons: -> - We provision the EKS cluster -> - Then we wait for the cluster to become available (see `null_resource.wait_for_cluster` in [auth.tf](auth.tf) -> - Then we provision the Kubernetes Auth ConfigMap to map and add additional roles/users/accounts to Kubernetes groups -> - That is all we do in this module, but after that, we expect you to use [terraform-aws-eks-node-group](https://github.com/cloudposse/terraform-aws-eks-node-group) -> to provision a managed Node Group -> - Then EKS updates the Auth ConfigMap and adds worker roles to it (for the worker nodes to join the cluster) -> - Since the ConfigMap is modified outside of Terraform state, Terraform wants to update it to to remove the worker roles EKS added -> - If you update the ConfigMap without including the worker nodes that EKS added, you will disconnect them from the cluster - -However, it is possible to get the worker node roles from the terraform-aws-eks-node-group via Terraform "remote state" -and include them with any other roles you want to add (example code to be published later), so we make -ignoring the role changes optional. (This is what we do for Cloud Posse clients.) -If you do not ignore changes then you will have no problem with making future intentional changes. - -The downside of having `kubernetes_config_map_ignore_role_changes` set to true is that if you later want to make changes, -such as adding other IAM roles to Kubernetes groups, you cannot do so via Terraform, because the role changes are ignored. -Because of Terraform restrictions, you cannot simply change `kubernetes_config_map_ignore_role_changes` from `true` -to `false`, apply changes, and set it back to `true` again. Terraform does not allow the -"ignore" settings to be changed on a resource, so `kubernetes_config_map_ignore_role_changes` is implemented as -2 different resources, one with ignore settings and one without. If you want to switch from ignoring to not ignoring, -or vice versa, you must manually move the `aws_auth` resource in the terraform state. Change the setting of -`kubernetes_config_map_ignore_role_changes`, run `terraform plan`, and you will see that an `aws_auth` resource -is planned to be destroyed and another one is planned to be created. Use `terraform state mv` to move the destroyed -resource to the created resource "address", something like -``` -terraform state mv 'module.eks_cluster.kubernetes_config_map.aws_auth_ignore_changes[0]' 'module.eks_cluster.kubernetes_config_map.aws_auth[0]' -``` -Then run `terraform plan` again and you should see only your desired changes made "in place". After applying your -changes, if you want to set `kubernetes_config_map_ignore_role_changes` back to `true`, you will again need to use -`terraform state mv` to move the `auth-map` back to its old "address". - - -> [!TIP] -> #### Use Terraform Reference Architectures for AWS -> -> Use Cloud Posse's ready-to-go [terraform architecture blueprints](https://cloudposse.com/reference-architecture/) for AWS to get up and running quickly. -> -> βœ… We build it with you.
-> βœ… You own everything.
-> βœ… Your team wins.
-> -> Request Quote ->
πŸ“š Learn More -> ->
-> -> Cloud Posse is the leading [**DevOps Accelerator**](https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-eks-cluster&utm_content=commercial_support) for funded startups and enterprises. -> -> *Your team can operate like a pro today.* -> -> Ensure that your team succeeds by using Cloud Posse's proven process and turnkey blueprints. Plus, we stick around until you succeed. -> #### Day-0: Your Foundation for Success -> - **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code. -> - **Deployment Strategy.** Adopt a proven deployment strategy with GitHub Actions, enabling automated, repeatable, and reliable software releases. -> - **Site Reliability Engineering.** Gain total visibility into your applications and services with Datadog, ensuring high availability and performance. -> - **Security Baseline.** Establish a secure environment from the start, with built-in governance, accountability, and comprehensive audit logs, safeguarding your operations. -> - **GitOps.** Empower your team to manage infrastructure changes confidently and efficiently through Pull Requests, leveraging the full power of GitHub Actions. -> -> Request Quote -> -> #### Day-2: Your Operational Mastery -> - **Training.** Equip your team with the knowledge and skills to confidently manage the infrastructure, ensuring long-term success and self-sufficiency. -> - **Support.** Benefit from a seamless communication over Slack with our experts, ensuring you have the support you need, whenever you need it. -> - **Troubleshooting.** Access expert assistance to quickly resolve any operational challenges, minimizing downtime and maintaining business continuity. -> - **Code Reviews.** Enhance your team’s code quality with our expert feedback, fostering continuous improvement and collaboration. -> - **Bug Fixes.** Rely on our team to troubleshoot and resolve any issues, ensuring your systems run smoothly. -> - **Migration Assistance.** Accelerate your migration process with our dedicated support, minimizing disruption and speeding up time-to-value. -> - **Customer Workshops.** Engage with our team in weekly workshops, gaining insights and strategies to continuously improve and innovate. -> -> Request Quote ->
## Usage - For a complete example, see [examples/complete](examples/complete). -For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which tests and deploys the example on AWS), see [test](test). +For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which tests and deploys the example on AWS), see [test/src](test/scc). Other examples: @@ -203,6 +71,47 @@ Other examples: region = var.region } + # Note: This example creates an explicit access entry for the current user, + # but in practice, you should use a static map of IAM users or roles that should have access to the cluster. + # Granting access to the current user in this way is not recommended for production use. + data "aws_caller_identity" "current" {} + + # IAM session context converts an assumed role ARN into an IAM Role ARN. + # Again, this is primarily to simplify the example, and in practice, you should use a static map of IAM users or roles. + data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn + } + + locals { + # The usage of the specific kubernetes.io/cluster/* resource tags below are required + # for EKS and Kubernetes to discover and manage networking resources + # https://aws.amazon.com/premiumsupport/knowledge-center/eks-vpc-subnet-discovery/ + # https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/deploy/subnet_discovery.md + tags = { "kubernetes.io/cluster/${module.label.id}" = "shared" } + + # required tags to make ALB ingress work https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html + public_subnets_additional_tags = { + "kubernetes.io/role/elb" : 1 + } + private_subnets_additional_tags = { + "kubernetes.io/role/internal-elb" : 1 + } + + # Enable the IAM user creating the cluster to administer it, + # without using the bootstrap_cluster_creator_admin_permissions option, + # as an example of how to use the access_entry_map feature. + # In practice, this should be replaced with a static map of IAM users or roles + # that should have access to the cluster, but we use the current user + # to simplify the example. + access_entry_map = { + (data.aws_iam_session_context.current.issuer_arn) = { + access_policy_associations = { + ClusterAdmin = {} + } + } + } + } + module "label" { source = "cloudposse/label/null" # Cloud Posse recommends pinning every module to a specific version @@ -212,22 +121,15 @@ Other examples: name = var.name stage = var.stage delimiter = var.delimiter - attributes = ["cluster"] tags = var.tags } - locals { - # Prior to Kubernetes 1.19, the usage of the specific kubernetes.io/cluster/* resource tags below are required - # for EKS and Kubernetes to discover and manage networking resources - # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking - tags = { "kubernetes.io/cluster/${module.label.id}" = "shared" } - } - module "vpc" { source = "cloudposse/vpc/aws" # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - cidr_block = "172.16.0.0/16" + + ipv4_primary_cidr_block = "172.16.0.0/16" tags = local.tags context = module.label.context @@ -240,11 +142,14 @@ Other examples: availability_zones = var.availability_zones vpc_id = module.vpc.vpc_id - igw_id = module.vpc.igw_id - cidr_block = module.vpc.vpc_cidr_block + igw_id = [module.vpc.igw_id] + ipv4_cidr_block = [module.vpc.vpc_cidr_block] nat_gateway_enabled = true nat_instance_enabled = false + public_subnets_additional_tags = local.public_subnets_additional_tags + private_subnets_additional_tags = local.private_subnets_additional_tags + tags = local.tags context = module.label.context } @@ -254,20 +159,17 @@ Other examples: # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - instance_types = [var.instance_type] - subnet_ids = module.subnets.public_subnet_ids - health_check_type = var.health_check_type - min_size = var.min_size - max_size = var.max_size - cluster_name = module.eks_cluster.eks_cluster_id + instance_types = [var.instance_type] + subnet_ids = module.subnets.private_subnet_ids + health_check_type = var.health_check_type + min_size = var.min_size + max_size = var.max_size + cluster_name = module.eks_cluster.eks_cluster_id # Enable the Kubernetes cluster auto-scaler to find the auto-scaling group cluster_autoscaler_enabled = var.autoscaling_policies_enabled context = module.label.context - - # Ensure the cluster is fully created before trying to add the node group - module_depends_on = module.eks_cluster.kubernetes_config_map_id } module "eks_cluster" { @@ -275,35 +177,33 @@ Other examples: # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - vpc_id = module.vpc.vpc_id - subnet_ids = module.subnets.public_subnet_ids - + subnet_ids = concat(module.subnets.private_subnet_ids, module.subnets.public_subnet_ids) kubernetes_version = var.kubernetes_version oidc_provider_enabled = true addons = [ - // https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html#vpc-cni-latest-available-version + # https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html#vpc-cni-latest-available-version { addon_name = "vpc-cni" addon_version = var.vpc_cni_version - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" - service_account_role_arn = null + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "OVERWRITE" + service_account_role_arn = var.vpc_cni_service_account_role_arn # Creating this role is outside the scope of this example }, - // https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html + # https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html { addon_name = "kube-proxy" addon_version = var.kube_proxy_version - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "OVERWRITE" service_account_role_arn = null }, - // https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html + # https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html { addon_name = "coredns" addon_version = var.coredns_version - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "OVERWRITE" service_account_role_arn = null }, ] @@ -322,7 +222,7 @@ Module usage with two unmanaged worker groups: # Unfortunately, the `aws_ami` data source attribute `most_recent` (https://github.com/cloudposse/terraform-aws-eks-workers/blob/34a43c25624a6efb3ba5d2770a601d7cb3c0d391/main.tf#L141) # does not work as you might expect. If you are not going to use a custom AMI you should # use the `eks_worker_ami_name_filter` variable to set the right kubernetes version for EKS workers, - # otherwise the first version of Kubernetes supported by AWS (v1.11) for EKS workers will be selected, but + # otherwise the first version of Kubernetes supported by AWS (v1.11) for EKS workers will be selected, but the # EKS control plane will ignore it to use one that matches the version specified by the `kubernetes_version` variable. eks_worker_ami_name_filter = "amazon-eks-node-${var.kubernetes_version}*" } @@ -386,19 +286,32 @@ Module usage with two unmanaged worker groups: # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - vpc_id = module.vpc.vpc_id - subnet_ids = module.subnets.public_subnet_ids - + subnet_ids = concat(module.subnets.private_subnet_ids, module.subnets.public_subnet_ids) kubernetes_version = var.kubernetes_version - oidc_provider_enabled = false + oidc_provider_enabled = true # needed for VPC CNI - workers_role_arns = [module.eks_workers.workers_role_arn, module.eks_workers_2.workers_role_arn] - allowed_security_group_ids = [module.eks_workers.security_group_id, module.eks_workers_2.security_group_id] + access_entries_for_nodes = { + EC2_LINUX = [module.eks_workers.workers_role_arn, module.eks_workers_2.workers_role_arn] + } context = module.label.context } ``` +> [!WARNING] +> Release `4.0.0` contains major breaking changes that will require you to update your existing EKS cluster +> and configuration to use this module. Please see the [v3 to v4 migration path](./docs/migration-v3-v4.md) for more information. +> Release `2.0.0` (previously released as version `0.45.0`) contains some changes that, +> if applied to a cluster created with an earlier version of this module, +> could result in your existing EKS cluster being replaced (destroyed and recreated). +> To prevent this, follow the instructions in the [v1 to v2 migration path](./docs/migration-v1-v2.md). + +> [!NOTE] +> Prior to v4 of this module, AWS did not provide an API to manage access to the EKS cluster, +> causing numerous challenges. With v4 of this module, it exclusively uses the AWS API, resolving +> many issues you may read about that had affected prior versions. See the version 2 README and release notes +> for more information on the challenges and workarounds that were required prior to v3. + > [!IMPORTANT] > In Cloud Posse's examples, we avoid pinning modules to specific versions to prevent discrepancies between the documentation > and the latest released versions. However, for your own projects, we strongly advise pinning each module to the exact version @@ -430,18 +343,14 @@ Available targets: | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.3.0 | -| [aws](#requirement\_aws) | >= 5.0.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.7.1 | -| [null](#requirement\_null) | >= 2.0 | +| [aws](#requirement\_aws) | >= 5.34.0 | | [tls](#requirement\_tls) | >= 3.1.0, != 4.0.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.0.0 | -| [kubernetes](#provider\_kubernetes) | >= 2.7.1 | -| [null](#provider\_null) | >= 2.0 | +| [aws](#provider\_aws) | >= 5.34.0 | | [tls](#provider\_tls) | >= 3.1.0, != 4.0.0 | ## Modules @@ -456,6 +365,12 @@ Available targets: | Name | Type | |------|------| | [aws_cloudwatch_log_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_eks_access_entry.linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_entry.map](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_entry.standard](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_entry.windows](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_policy_association.list](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_policy_association) | resource | +| [aws_eks_access_policy_association.map](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_policy_association) | resource | | [aws_eks_addon.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) | resource | | [aws_eks_cluster.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_cluster) | resource | | [aws_iam_openid_connect_provider.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider) | resource | @@ -466,18 +381,9 @@ Available targets: | [aws_iam_role_policy_attachment.cluster_elb_service_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_kms_alias.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | | [aws_kms_key.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.custom_ingress_rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_workers](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.managed_ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.managed_ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [kubernetes_config_map.aws_auth](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource | -| [kubernetes_config_map.aws_auth_ignore_changes](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource | -| [null_resource.wait_for_cluster](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | -| [aws_eks_cluster_auth.eks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster_auth) | data source | +| [aws_vpc_security_group_ingress_rule.custom_ingress_rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.managed_ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.managed_ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | | [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.cluster_elb_service_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | @@ -487,16 +393,18 @@ Available targets: | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [access\_config](#input\_access\_config) | Access configuration for the EKS cluster. |
object({
authentication_mode = optional(string, "API")
bootstrap_cluster_creator_admin_permissions = optional(bool, false)
})
| `{}` | no | +| [access\_entries](#input\_access\_entries) | List of IAM principles to allow to access the EKS cluster.
It is recommended to use the default `user_name` because the default includes
the IAM role or user name and the session name for assumed roles.
Use when Principal ARN is not known at plan time. |
list(object({
principal_arn = string
user_name = optional(string, null)
kubernetes_groups = optional(list(string), null)
}))
| `[]` | no | +| [access\_entries\_for\_nodes](#input\_access\_entries\_for\_nodes) | Map of list of IAM roles for the EKS non-managed worker nodes.
The map key is the node type, either `EC2_LINUX` or `EC2_WINDOWS`,
and the list contains the IAM roles of the nodes of that type.
There is no need for or utility in creating Fargate access entries, as those
are always created automatically by AWS, just as with managed nodes.
Use when Principal ARN is not known at plan time. | `map(list(string))` | `{}` | no | +| [access\_entry\_map](#input\_access\_entry\_map) | Map of IAM Principal ARNs to access configuration.
Preferred over other inputs as this configuration remains stable
when elements are added or removed, but it requires that the Principal ARNs
and Policy ARNs are known at plan time.
Can be used along with other `access_*` inputs, but do not duplicate entries.
Map `access_policy_associations` keys are policy ARNs, policy
full name (AmazonEKSViewPolicy), or short name (View).
It is recommended to use the default `user_name` because the default includes
IAM role or user name and the session name for assumed roles.
As a special case in support of backwards compatibility, membership in the
`system:masters` group is is translated to an association with the ClusterAdmin policy.
In all other cases, including any `system:*` group in `kubernetes_groups` is prohibited. |
map(object({
# key is principal_arn
user_name = optional(string)
# Cannot assign "system:*" groups to IAM users, use ClusterAdmin and Admin instead
kubernetes_groups = optional(list(string), [])
type = optional(string, "STANDARD")
access_policy_associations = optional(map(object({
# key is policy_arn or policy_name
access_scope = optional(object({
type = optional(string, "cluster")
namespaces = optional(list(string))
}), {}) # access_scope
})), {}) # access_policy_associations
}))
| `{}` | no | +| [access\_policy\_associations](#input\_access\_policy\_associations) | List of AWS managed EKS access policies to associate with IAM principles.
Use when Principal ARN or Policy ARN is not known at plan time.
`policy_arn` can be the full ARN, the full name (AmazonEKSViewPolicy) or short name (View). |
list(object({
principal_arn = string
policy_arn = string
access_scope = object({
type = optional(string, "cluster")
namespaces = optional(list(string))
})
}))
| `[]` | no | | [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | -| [addons](#input\_addons) | Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources |
list(object({
addon_name = string
addon_version = optional(string, null)
configuration_values = optional(string, null)
resolve_conflicts_on_create = optional(string, null)
resolve_conflicts_on_update = optional(string, null)
service_account_role_arn = optional(string, null)
create_timeout = optional(string, null)
update_timeout = optional(string, null)
delete_timeout = optional(string, null)
}))
| `[]` | no | +| [addons](#input\_addons) | Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources.
Note: `resolve_conflicts` is deprecated. If `resolve_conflicts` is set and
`resolve_conflicts_on_create` or `resolve_conflicts_on_update` is not set,
`resolve_conflicts` will be used instead. If `resolve_conflicts_on_create` is
not set and `resolve_conflicts` is `PRESERVE`, `resolve_conflicts_on_create`
will be set to `NONE`. |
list(object({
addon_name = string
addon_version = optional(string, null)
configuration_values = optional(string, null)
# resolve_conflicts is deprecated, but we keep it for backwards compatibility
# and because if not declared, Terraform will silently ignore it.
resolve_conflicts = optional(string, null)
resolve_conflicts_on_create = optional(string, null)
resolve_conflicts_on_update = optional(string, null)
service_account_role_arn = optional(string, null)
create_timeout = optional(string, null)
update_timeout = optional(string, null)
delete_timeout = optional(string, null)
}))
| `[]` | no | | [addons\_depends\_on](#input\_addons\_depends\_on) | If provided, all addons will depend on this object, and therefore not be installed until this object is finalized.
This is useful if you want to ensure that addons are not applied before some other condition is met, e.g. node groups are created.
See [issue #170](https://github.com/cloudposse/terraform-aws-eks-cluster/issues/170) for more details. | `any` | `null` | no | | [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | A list of IPv4 CIDRs to allow access to the cluster.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | | [allowed\_security\_group\_ids](#input\_allowed\_security\_group\_ids) | A list of IDs of Security Groups to allow access to the cluster. | `list(string)` | `[]` | no | -| [allowed\_security\_groups](#input\_allowed\_security\_groups) | DEPRECATED: Use `allowed_security_group_ids` instead.
Historical description: List of Security Group IDs to be allowed to connect to the EKS cluster.
Historical default: `[]` | `list(string)` | `[]` | no | -| [apply\_config\_map\_aws\_auth](#input\_apply\_config\_map\_aws\_auth) | Whether to apply the ConfigMap to allow worker nodes to join the EKS cluster and allow additional users, accounts and roles to acces the cluster | `bool` | `true` | no | | [associated\_security\_group\_ids](#input\_associated\_security\_group\_ids) | A list of IDs of Security Groups to associate the cluster with.
These security groups will not be modified. | `list(string)` | `[]` | no | | [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | -| [aws\_auth\_yaml\_strip\_quotes](#input\_aws\_auth\_yaml\_strip\_quotes) | If true, remove double quotes from the generated aws-auth ConfigMap YAML to reduce spurious diffs in plans | `bool` | `true` | no | | [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | If provided, the KMS Key ID to use to encrypt AWS CloudWatch logs | `string` | `null` | no | | [cluster\_attributes](#input\_cluster\_attributes) | Override label module default cluster attributes | `list(string)` |
[
"cluster"
]
| no | | [cluster\_depends\_on](#input\_cluster\_depends\_on) | If provided, the EKS will depend on this object, and therefore not be created until this object is finalized.
This is useful if you want to ensure that the cluster is not created before some other condition is met, e.g. VPNs into the subnet are created. | `any` | `null` | no | @@ -509,11 +417,9 @@ Available targets: | [cluster\_log\_retention\_period](#input\_cluster\_log\_retention\_period) | 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. | `number` | `0` | no | | [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | | [create\_eks\_service\_role](#input\_create\_eks\_service\_role) | Set `false` to use existing `eks_cluster_service_role_arn` instead of creating one | `bool` | `true` | no | -| [create\_security\_group](#input\_create\_security\_group) | Set to `true` to create and configure an additional Security Group for the cluster.
Only for backwards compatibility, if you are updating this module to the latest version on existing clusters, not recommended for new clusters.
EKS creates a managed Security Group for the cluster automatically, places the control plane and managed nodes into the Security Group,
and you can also allow unmanaged nodes to communicate with the cluster by using the `allowed_security_group_ids` variable.
The additional Security Group is kept in the module for backwards compatibility and will be removed in future releases along with this variable.
See https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html for more details. | `bool` | `false` | no | | [custom\_ingress\_rules](#input\_custom\_ingress\_rules) | A List of Objects, which are custom security group rules that |
list(object({
description = string
from_port = number
to_port = number
protocol = string
source_security_group_id = string
}))
| `[]` | no | | [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | [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 | -| [dummy\_kubeapi\_server](#input\_dummy\_kubeapi\_server) | URL of a dummy API server for the Kubernetes server to use when the real one is unknown.
This is a workaround to ignore connection failures that break Terraform even though the results do not matter.
You can disable it by setting it to `null`; however, as of Kubernetes provider v2.3.2, doing so \_will\_
cause Terraform to fail in several situations unless you provide a valid `kubeconfig` file
via `kubeconfig_path` and set `kubeconfig_path_enabled` to `true`. | `string` | `"https://jsonplaceholder.typicode.com"` | no | | [eks\_cluster\_service\_role\_arn](#input\_eks\_cluster\_service\_role\_arn) | The ARN of an IAM role for the EKS cluster to use that provides permissions
for the Kubernetes control plane to perform needed AWS API operations.
Required if `create_eks_service_role` is `false`, ignored otherwise. | `string` | `null` | no | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [enabled\_cluster\_log\_types](#input\_enabled\_cluster\_log\_types) | 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`] | `list(string)` | `[]` | no | @@ -521,27 +427,13 @@ Available targets: | [endpoint\_public\_access](#input\_endpoint\_public\_access) | Indicates whether or not the Amazon EKS public API server endpoint is enabled. Default to AWS EKS resource and it is true | `bool` | `true` | 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 | | [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 | -| [kube\_data\_auth\_enabled](#input\_kube\_data\_auth\_enabled) | If `true`, use an `aws_eks_cluster_auth` data source to authenticate to the EKS cluster.
Disabled by `kubeconfig_path_enabled` or `kube_exec_auth_enabled`. | `bool` | `true` | no | -| [kube\_exec\_auth\_aws\_profile](#input\_kube\_exec\_auth\_aws\_profile) | The AWS config profile for `aws eks get-token` to use | `string` | `""` | no | -| [kube\_exec\_auth\_aws\_profile\_enabled](#input\_kube\_exec\_auth\_aws\_profile\_enabled) | If `true`, pass `kube_exec_auth_aws_profile` as the `profile` to `aws eks get-token` | `bool` | `false` | no | -| [kube\_exec\_auth\_enabled](#input\_kube\_exec\_auth\_enabled) | If `true`, use the Kubernetes provider `exec` feature to execute `aws eks get-token` to authenticate to the EKS cluster.
Disabled by `kubeconfig_path_enabled`, overrides `kube_data_auth_enabled`. | `bool` | `false` | no | -| [kube\_exec\_auth\_role\_arn](#input\_kube\_exec\_auth\_role\_arn) | The role ARN for `aws eks get-token` to use | `string` | `""` | no | -| [kube\_exec\_auth\_role\_arn\_enabled](#input\_kube\_exec\_auth\_role\_arn\_enabled) | If `true`, pass `kube_exec_auth_role_arn` as the role ARN to `aws eks get-token` | `bool` | `false` | no | -| [kubeconfig\_context](#input\_kubeconfig\_context) | Context to choose from the Kubernetes kube config file | `string` | `""` | no | -| [kubeconfig\_path](#input\_kubeconfig\_path) | The Kubernetes provider `config_path` setting to use when `kubeconfig_path_enabled` is `true` | `string` | `""` | no | -| [kubeconfig\_path\_enabled](#input\_kubeconfig\_path\_enabled) | If `true`, configure the Kubernetes provider with `kubeconfig_path` and use it for authenticating to the EKS cluster | `bool` | `false` | no | -| [kubernetes\_config\_map\_ignore\_role\_changes](#input\_kubernetes\_config\_map\_ignore\_role\_changes) | Set to `true` to ignore IAM role changes in the Kubernetes Auth ConfigMap | `bool` | `true` | no | | [kubernetes\_network\_ipv6\_enabled](#input\_kubernetes\_network\_ipv6\_enabled) | Set true to use IPv6 addresses for Kubernetes pods and services | `bool` | `false` | no | | [kubernetes\_version](#input\_kubernetes\_version) | Desired Kubernetes master version. If you do not specify a value, the latest available version is used | `string` | `"1.21"` | no | | [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | | [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | | [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | | [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 | -| [local\_exec\_interpreter](#input\_local\_exec\_interpreter) | shell to use for local\_exec | `list(string)` |
[
"/bin/sh",
"-c"
]
| no | | [managed\_security\_group\_rules\_enabled](#input\_managed\_security\_group\_rules\_enabled) | Flag to enable/disable the ingress and egress rules for the EKS managed Security Group | `bool` | `true` | no | -| [map\_additional\_aws\_accounts](#input\_map\_additional\_aws\_accounts) | Additional AWS account numbers to add to `config-map-aws-auth` ConfigMap | `list(string)` | `[]` | no | -| [map\_additional\_iam\_roles](#input\_map\_additional\_iam\_roles) | Additional IAM roles to add to `config-map-aws-auth` ConfigMap |
list(object({
rolearn = string
username = string
groups = list(string)
}))
| `[]` | no | -| [map\_additional\_iam\_users](#input\_map\_additional\_iam\_users) | Additional IAM users to add to `config-map-aws-auth` ConfigMap |
list(object({
userarn = string
username = string
groups = list(string)
}))
| `[]` | 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 | | [oidc\_provider\_enabled](#input\_oidc\_provider\_enabled) | 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 [EKS User Guide](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html). | `bool` | `false` | no | @@ -554,10 +446,6 @@ Available targets: | [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch the cluster in | `list(string)` | n/a | yes | | [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | | [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | -| [vpc\_id](#input\_vpc\_id) | VPC ID for the EKS cluster | `string` | n/a | yes | -| [wait\_for\_cluster\_command](#input\_wait\_for\_cluster\_command) | `local-exec` command to execute to determine if the EKS cluster is healthy. Cluster endpoint URL is available as environment variable `ENDPOINT` | `string` | `"if test -n \"$ENDPOINT\"; then curl --silent --fail --retry 30 --retry-delay 10 --retry-connrefused --max-time 11 --insecure --output /dev/null $ENDPOINT/healthz; fi"` | no | -| [workers\_role\_arns](#input\_workers\_role\_arns) | List of Role ARNs of the worker nodes | `list(string)` | `[]` | no | -| [workers\_security\_group\_ids](#input\_workers\_security\_group\_ids) | DEPRECATED: Use `allowed_security_group_ids` instead.
Historical description: Security Group IDs of the worker nodes.
Historical default: `[]` | `list(string)` | `[]` | no | ## Outputs @@ -575,13 +463,10 @@ Available targets: | [eks\_cluster\_id](#output\_eks\_cluster\_id) | The name of the cluster | | [eks\_cluster\_identity\_oidc\_issuer](#output\_eks\_cluster\_identity\_oidc\_issuer) | The OIDC Identity issuer for the cluster | | [eks\_cluster\_identity\_oidc\_issuer\_arn](#output\_eks\_cluster\_identity\_oidc\_issuer\_arn) | The OIDC Identity issuer ARN for the cluster that can be used to associate IAM roles with a service account | +| [eks\_cluster\_ipv6\_service\_cidr](#output\_eks\_cluster\_ipv6\_service\_cidr) | The IPv6 CIDR block that Kubernetes pod and service IP addresses are assigned from
if `kubernetes_network_ipv6_enabled` is set to true. If set to false this output will be null. | | [eks\_cluster\_managed\_security\_group\_id](#output\_eks\_cluster\_managed\_security\_group\_id) | Security Group ID that was created by EKS for the cluster.
EKS creates a Security Group and applies it to the ENI that are attached to EKS Control Plane master nodes and to any managed workloads. | | [eks\_cluster\_role\_arn](#output\_eks\_cluster\_role\_arn) | ARN of the EKS cluster IAM role | | [eks\_cluster\_version](#output\_eks\_cluster\_version) | The Kubernetes server version of the cluster | -| [kubernetes\_config\_map\_id](#output\_kubernetes\_config\_map\_id) | ID of `aws-auth` Kubernetes ConfigMap | -| [security\_group\_arn](#output\_security\_group\_arn) | (Deprecated) ARN of the optionally created additional Security Group for the EKS cluster | -| [security\_group\_id](#output\_security\_group\_id) | (Deprecated) ID of the optionally created additional Security Group for the EKS cluster | -| [security\_group\_name](#output\_security\_group\_name) | Name of the optionally created additional Security Group for the EKS cluster | @@ -589,6 +474,8 @@ Available targets: Check out these related projects. +- [terraform-aws-components eks/clusters](https://github.com/cloudposse/terraform-aws-components/tree/main/modules/eks/cluster) - Cloud Posse's component (root module) using this module to provision an EKS cluster +- [terraform-aws-components eks/karpenter and eks/karpenter-provisioner](https://github.com/cloudposse/terraform-aws-components/tree/main/modules/eks/karpenter) - Cloud Posse's components (root modules) deploying Karpenter to manage auto-scaling of EKS node groups - [terraform-aws-eks-workers](https://github.com/cloudposse/terraform-aws-eks-workers) - Terraform module to provision an AWS AutoScaling Group, IAM Role, and Security Group for EKS Workers - [terraform-aws-ec2-autoscale-group](https://github.com/cloudposse/terraform-aws-ec2-autoscale-group) - Terraform module to provision Auto Scaling Group and Launch Template on AWS - [terraform-aws-ecs-container-definition](https://github.com/cloudposse/terraform-aws-ecs-container-definition) - Terraform module to generate well-formed JSON documents (container definitions) that are passed to the aws_ecs_task_definition Terraform resource @@ -601,6 +488,45 @@ Check out these related projects. - [terraform-aws-ec2-instance-group](https://github.com/cloudposse/terraform-aws-ec2-instance-group) - Terraform module for provisioning multiple general purpose EC2 hosts for stateful applications +> [!TIP] +> #### Use Terraform Reference Architectures for AWS +> +> Use Cloud Posse's ready-to-go [terraform architecture blueprints](https://cloudposse.com/reference-architecture/) for AWS to get up and running quickly. +> +> βœ… We build it with you.
+> βœ… You own everything.
+> βœ… Your team wins.
+> +> Request Quote +>
πŸ“š Learn More +> +>
+> +> Cloud Posse is the leading [**DevOps Accelerator**](https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-eks-cluster&utm_content=commercial_support) for funded startups and enterprises. +> +> *Your team can operate like a pro today.* +> +> Ensure that your team succeeds by using Cloud Posse's proven process and turnkey blueprints. Plus, we stick around until you succeed. +> #### Day-0: Your Foundation for Success +> - **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code. +> - **Deployment Strategy.** Adopt a proven deployment strategy with GitHub Actions, enabling automated, repeatable, and reliable software releases. +> - **Site Reliability Engineering.** Gain total visibility into your applications and services with Datadog, ensuring high availability and performance. +> - **Security Baseline.** Establish a secure environment from the start, with built-in governance, accountability, and comprehensive audit logs, safeguarding your operations. +> - **GitOps.** Empower your team to manage infrastructure changes confidently and efficiently through Pull Requests, leveraging the full power of GitHub Actions. +> +> Request Quote +> +> #### Day-2: Your Operational Mastery +> - **Training.** Equip your team with the knowledge and skills to confidently manage the infrastructure, ensuring long-term success and self-sufficiency. +> - **Support.** Benefit from a seamless communication over Slack with our experts, ensuring you have the support you need, whenever you need it. +> - **Troubleshooting.** Access expert assistance to quickly resolve any operational challenges, minimizing downtime and maintaining business continuity. +> - **Code Reviews.** Enhance your team’s code quality with our expert feedback, fostering continuous improvement and collaboration. +> - **Bug Fixes.** Rely on our team to troubleshoot and resolve any issues, ensuring your systems run smoothly. +> - **Migration Assistance.** Accelerate your migration process with our dedicated support, minimizing disruption and speeding up time-to-value. +> - **Customer Workshops.** Engage with our team in weekly workshops, gaining insights and strategies to continuously improve and innovate. +> +> Request Quote +>
## ✨ Contributing diff --git a/README.yaml b/README.yaml index 4a578698..c21ecf2b 100644 --- a/README.yaml +++ b/README.yaml @@ -29,6 +29,12 @@ badges: # List any related terraform modules that this module may be used with or that this module depends on. related: + - name: terraform-aws-components eks/clusters + description: Cloud Posse's component (root module) using this module to provision an EKS cluster + url: https://github.com/cloudposse/terraform-aws-components/tree/main/modules/eks/cluster + - name: terraform-aws-components eks/karpenter and eks/karpenter-provisioner + description: Cloud Posse's components (root modules) deploying Karpenter to manage auto-scaling of EKS node groups + url: https://github.com/cloudposse/terraform-aws-components/tree/main/modules/eks/karpenter - name: terraform-aws-eks-workers description: Terraform module to provision an AWS AutoScaling Group, IAM Role, and Security Group for EKS Workers url: https://github.com/cloudposse/terraform-aws-eks-workers @@ -65,111 +71,18 @@ description: Terraform module to provision an [EKS](https://aws.amazon.com/eks/) introduction: |- The module provisions the following resources: - - EKS cluster of master nodes that can be used together with the [terraform-aws-eks-workers](https://github.com/cloudposse/terraform-aws-eks-workers), + - EKS cluster of master nodes that can be used together with the [terraform-aws-eks-node-group](https://github.com/cloudposse/terraform-aws-eks-node-group) and [terraform-aws-eks-fargate-profile](https://github.com/cloudposse/terraform-aws-eks-fargate-profile) - modules to create a full-blown cluster + modules to create a full-blown EKS/Kubernetes cluster. You can also use the [terraform-aws-eks-workers](https://github.com/cloudposse/terraform-aws-eks-workers) + module to provision worker nodes for the cluster, but it is now rare for that to be a better choice than to use `terraform-aws-eks-node-group`. - IAM Role to allow the cluster to access other AWS services - - Optionally, the module creates and automatically applies an authentication ConfigMap (`aws-auth`) to allow the - worker nodes to join the cluster and to add additional users/roles/accounts. (This option is enabled - by default, but has some caveats noted below. Set `apply_config_map_aws_auth` to `false` to avoid these issues.) - - > [!WARNING] - > Release `2.0.0` (previously released as version `0.45.0`) contains some changes that - > could result in your existing EKS cluster being replaced (destroyed and recreated). - > To prevent this, follow the instructions in the [v1 to v2 migration path](./docs/migration-v1-v2.md). - - > [!NOTE] - > Every Terraform module that provisions an EKS cluster has faced the challenge that access to the cluster - > is partly controlled by a resource inside the cluster, a ConfigMap called `aws-auth`. You need to be able to access - > the cluster through the Kubernetes API to modify the ConfigMap, because - > [there is no AWS API for it](https://github.com/aws/containers-roadmap/issues/185). This presents - > a problem: how do you authenticate to an API endpoint that you have not yet created? - - We use the Terraform Kubernetes provider to access the cluster, and it uses the same underlying library - that `kubectl` uses, so configuration is very similar. However, every kind of configuration we have tried - has failed at some point. - - An authentication token can be retrieved using the `aws_eks_cluster_auth` data source. This works as - long as the token does not expire while Terraform is running, and the token is refreshed during the "plan" - phase before trying to refresh the state, and the token does not expire in the interval between - "plan" and "apply". Unfortunately, failures of all these types have been seen. Nevertheless, - this is the only method that is compatible with Terraform Cloud, so it is the default. It is the only - method we fully support until AWS [provides an API for managing `aws-auth`](https://github.com/aws/containers-roadmap/issues/185). - - After creating the EKS cluster, you can generate a `KUBECONFIG` file that configures access to it. - This works most of the time, but if the file was present and used as part of the configuration to create - the cluster, and then the file gets deleted (as would happen in a CI system like Terraform Cloud), Terraform - would not cause the file to be regenerated in time to use it to refresh Terraform's state and the "plan" phase will fail. - So any `KUBECONFIG` file has to be managed separately. - - An authentication token can be retrieved on demand by using the `exec` feature of the Kubernetes provider - to call `aws eks get-token`. This requires that the `aws` CLI be installed and available to Terraform and that it - has access to sufficient credentials to perform the authentication and is configured to use them. When those - conditions are met, this is the most reliable method, and the one Cloud Posse prefers to use. However, since - it has these requirements that are not always easily met, it is not the default method and it is not - fully supported. - - All of the above methods can face additional challenges when using `terraform import` to import - resources into the Terraform state. The `KUBECONFIG` file method is the only sure way to `import` resources, due to - [Terraform limitations](https://github.com/hashicorp/terraform/issues/27934) on providers. You will need to create - the file, of course, but that is easily done with `aws eks update-kubeconfig`. Depending on the situation, - you may also be able to import resources by setting `-var apply_config_map_aws_auth=false` during import. - - At the moment, the `exec` option appears to be the most reliable method, so we recommend using it if possible, - but because of the extra requirements it has, we use the data source as the default authentication method. - - > [!IMPORTANT] - > All of the above methods require network connectivity between the host running the - > `terraform` command and the EKS endpoint. If your EKS cluster does not have public access enabled, this means - > you need to take extra steps, such as using a VPN to provide access to the private endpoint, or running - > `terraform` on a host in the same VPC as the EKS cluster. - - > [!WARNING] - > ### Failure during `destroy` - > - > If the cluster is destroyed (via Terraform or otherwise) before the Terraform resource - > responsible for the `aws-auth` ConfigMap is destroyed, Terraform will get stuck trying to delete the ConfigMap, - > because it cannot contact the now destroyed cluster. This can show up as a `connection refused` error (usually - > to `https://localhost/`). The easiest ways to handle this is either to add `-var apply_config_map_aws_auth=false` - > to the `destroy` command or to remove the ConfigMap (`...kubernetes_config_map.aws_auth[0]`) from the Terraform - > state with `terraform state rm`. - - > [!NOTE] - > We give you the `kubernetes_config_map_ignore_role_changes` option and default it to `true` for the following reasons: - > - We provision the EKS cluster - > - Then we wait for the cluster to become available (see `null_resource.wait_for_cluster` in [auth.tf](auth.tf) - > - Then we provision the Kubernetes Auth ConfigMap to map and add additional roles/users/accounts to Kubernetes groups - > - That is all we do in this module, but after that, we expect you to use [terraform-aws-eks-node-group](https://github.com/cloudposse/terraform-aws-eks-node-group) - > to provision a managed Node Group - > - Then EKS updates the Auth ConfigMap and adds worker roles to it (for the worker nodes to join the cluster) - > - Since the ConfigMap is modified outside of Terraform state, Terraform wants to update it to to remove the worker roles EKS added - > - If you update the ConfigMap without including the worker nodes that EKS added, you will disconnect them from the cluster - - However, it is possible to get the worker node roles from the terraform-aws-eks-node-group via Terraform "remote state" - and include them with any other roles you want to add (example code to be published later), so we make - ignoring the role changes optional. (This is what we do for Cloud Posse clients.) - If you do not ignore changes then you will have no problem with making future intentional changes. - - The downside of having `kubernetes_config_map_ignore_role_changes` set to true is that if you later want to make changes, - such as adding other IAM roles to Kubernetes groups, you cannot do so via Terraform, because the role changes are ignored. - Because of Terraform restrictions, you cannot simply change `kubernetes_config_map_ignore_role_changes` from `true` - to `false`, apply changes, and set it back to `true` again. Terraform does not allow the - "ignore" settings to be changed on a resource, so `kubernetes_config_map_ignore_role_changes` is implemented as - 2 different resources, one with ignore settings and one without. If you want to switch from ignoring to not ignoring, - or vice versa, you must manually move the `aws_auth` resource in the terraform state. Change the setting of - `kubernetes_config_map_ignore_role_changes`, run `terraform plan`, and you will see that an `aws_auth` resource - is planned to be destroyed and another one is planned to be created. Use `terraform state mv` to move the destroyed - resource to the created resource "address", something like - ``` - terraform state mv 'module.eks_cluster.kubernetes_config_map.aws_auth_ignore_changes[0]' 'module.eks_cluster.kubernetes_config_map.aws_auth[0]' - ``` - Then run `terraform plan` again and you should see only your desired changes made "in place". After applying your - changes, if you want to set `kubernetes_config_map_ignore_role_changes` back to `true`, you will again need to use - `terraform state mv` to move the `auth-map` back to its old "address". - -usage: |2- + - EKS access entries to allow IAM users to access and administer the cluster +usage: |- For a complete example, see [examples/complete](examples/complete). - For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which tests and deploys the example on AWS), see [test](test). + For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which tests and deploys the example on AWS), see [test/src](test/scc). Other examples: @@ -180,6 +93,47 @@ usage: |2- region = var.region } + # Note: This example creates an explicit access entry for the current user, + # but in practice, you should use a static map of IAM users or roles that should have access to the cluster. + # Granting access to the current user in this way is not recommended for production use. + data "aws_caller_identity" "current" {} + + # IAM session context converts an assumed role ARN into an IAM Role ARN. + # Again, this is primarily to simplify the example, and in practice, you should use a static map of IAM users or roles. + data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn + } + + locals { + # The usage of the specific kubernetes.io/cluster/* resource tags below are required + # for EKS and Kubernetes to discover and manage networking resources + # https://aws.amazon.com/premiumsupport/knowledge-center/eks-vpc-subnet-discovery/ + # https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/deploy/subnet_discovery.md + tags = { "kubernetes.io/cluster/${module.label.id}" = "shared" } + + # required tags to make ALB ingress work https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html + public_subnets_additional_tags = { + "kubernetes.io/role/elb" : 1 + } + private_subnets_additional_tags = { + "kubernetes.io/role/internal-elb" : 1 + } + + # Enable the IAM user creating the cluster to administer it, + # without using the bootstrap_cluster_creator_admin_permissions option, + # as an example of how to use the access_entry_map feature. + # In practice, this should be replaced with a static map of IAM users or roles + # that should have access to the cluster, but we use the current user + # to simplify the example. + access_entry_map = { + (data.aws_iam_session_context.current.issuer_arn) = { + access_policy_associations = { + ClusterAdmin = {} + } + } + } + } + module "label" { source = "cloudposse/label/null" # Cloud Posse recommends pinning every module to a specific version @@ -189,22 +143,15 @@ usage: |2- name = var.name stage = var.stage delimiter = var.delimiter - attributes = ["cluster"] tags = var.tags } - locals { - # Prior to Kubernetes 1.19, the usage of the specific kubernetes.io/cluster/* resource tags below are required - # for EKS and Kubernetes to discover and manage networking resources - # https://www.terraform.io/docs/providers/aws/guides/eks-getting-started.html#base-vpc-networking - tags = { "kubernetes.io/cluster/${module.label.id}" = "shared" } - } - module "vpc" { source = "cloudposse/vpc/aws" # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - cidr_block = "172.16.0.0/16" + + ipv4_primary_cidr_block = "172.16.0.0/16" tags = local.tags context = module.label.context @@ -217,10 +164,13 @@ usage: |2- availability_zones = var.availability_zones vpc_id = module.vpc.vpc_id - igw_id = module.vpc.igw_id - cidr_block = module.vpc.vpc_cidr_block + igw_id = [module.vpc.igw_id] + ipv4_cidr_block = [module.vpc.vpc_cidr_block] nat_gateway_enabled = true nat_instance_enabled = false + + public_subnets_additional_tags = local.public_subnets_additional_tags + private_subnets_additional_tags = local.private_subnets_additional_tags tags = local.tags context = module.label.context @@ -231,20 +181,17 @@ usage: |2- # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - instance_types = [var.instance_type] - subnet_ids = module.subnets.public_subnet_ids - health_check_type = var.health_check_type - min_size = var.min_size - max_size = var.max_size - cluster_name = module.eks_cluster.eks_cluster_id + instance_types = [var.instance_type] + subnet_ids = module.subnets.private_subnet_ids + health_check_type = var.health_check_type + min_size = var.min_size + max_size = var.max_size + cluster_name = module.eks_cluster.eks_cluster_id # Enable the Kubernetes cluster auto-scaler to find the auto-scaling group cluster_autoscaler_enabled = var.autoscaling_policies_enabled context = module.label.context - - # Ensure the cluster is fully created before trying to add the node group - module_depends_on = module.eks_cluster.kubernetes_config_map_id } module "eks_cluster" { @@ -252,42 +199,40 @@ usage: |2- # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - vpc_id = module.vpc.vpc_id - subnet_ids = module.subnets.public_subnet_ids - + subnet_ids = concat(module.subnets.private_subnet_ids, module.subnets.public_subnet_ids) kubernetes_version = var.kubernetes_version oidc_provider_enabled = true - + addons = [ - // https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html#vpc-cni-latest-available-version + # https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html#vpc-cni-latest-available-version { addon_name = "vpc-cni" addon_version = var.vpc_cni_version - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" - service_account_role_arn = null + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "OVERWRITE" + service_account_role_arn = var.vpc_cni_service_account_role_arn # Creating this role is outside the scope of this example }, - // https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html + # https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html { addon_name = "kube-proxy" addon_version = var.kube_proxy_version - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "OVERWRITE" service_account_role_arn = null }, - // https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html + # https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html { addon_name = "coredns" addon_version = var.coredns_version - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "OVERWRITE" service_account_role_arn = null }, ] addons_depends_on = [module.eks_node_group] context = module.label.context - + cluster_depends_on = [module.subnets] } ``` @@ -299,7 +244,7 @@ usage: |2- # Unfortunately, the `aws_ami` data source attribute `most_recent` (https://github.com/cloudposse/terraform-aws-eks-workers/blob/34a43c25624a6efb3ba5d2770a601d7cb3c0d391/main.tf#L141) # does not work as you might expect. If you are not going to use a custom AMI you should # use the `eks_worker_ami_name_filter` variable to set the right kubernetes version for EKS workers, - # otherwise the first version of Kubernetes supported by AWS (v1.11) for EKS workers will be selected, but + # otherwise the first version of Kubernetes supported by AWS (v1.11) for EKS workers will be selected, but the # EKS control plane will ignore it to use one that matches the version specified by the `kubernetes_version` variable. eks_worker_ami_name_filter = "amazon-eks-node-${var.kubernetes_version}*" } @@ -363,21 +308,40 @@ usage: |2- # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" - vpc_id = module.vpc.vpc_id - subnet_ids = module.subnets.public_subnet_ids - + subnet_ids = concat(module.subnets.private_subnet_ids, module.subnets.public_subnet_ids) kubernetes_version = var.kubernetes_version - oidc_provider_enabled = false + oidc_provider_enabled = true # needed for VPC CNI - workers_role_arns = [module.eks_workers.workers_role_arn, module.eks_workers_2.workers_role_arn] - allowed_security_group_ids = [module.eks_workers.security_group_id, module.eks_workers_2.security_group_id] + access_entries_for_nodes = { + EC2_LINUX = [module.eks_workers.workers_role_arn, module.eks_workers_2.workers_role_arn] + } context = module.label.context } ``` + > [!WARNING] + > Release `4.0.0` contains major breaking changes that will require you to update your existing EKS cluster + > and configuration to use this module. Please see the [v3 to v4 migration path](./docs/migration-v3-v4.md) for more information. + > Release `2.0.0` (previously released as version `0.45.0`) contains some changes that, + > if applied to a cluster created with an earlier version of this module, + > could result in your existing EKS cluster being replaced (destroyed and recreated). + > To prevent this, follow the instructions in the [v1 to v2 migration path](./docs/migration-v1-v2.md). + + > [!NOTE] + > Prior to v4 of this module, AWS did not provide an API to manage access to the EKS cluster, + > causing numerous challenges. With v4 of this module, it exclusively uses the AWS API, resolving + > many issues you may read about that had affected prior versions. See the version 2 README and release notes + > for more information on the challenges and workarounds that were required prior to v3. + include: - docs/targets.md - docs/terraform.md -contributors: [] +contributors: + - name: "Erik Osterman" + github: "osterman" + - name: "Andriy Knysh" + github: "aknysh" + - name: "Nuru" + github: "Nuru" diff --git a/auth.tf b/auth.tf index 09da88b8..bb71510f 100644 --- a/auth.tf +++ b/auth.tf @@ -1,157 +1,130 @@ -# The EKS service does not provide a cluster-level API parameter or resource to automatically configure the underlying Kubernetes cluster -# to allow worker nodes to join the cluster via AWS IAM role authentication. - -# NOTE: To automatically apply the Kubernetes configuration to the cluster (which allows the worker nodes to join the cluster), -# the requirements outlined here must be met: -# https://learn.hashicorp.com/terraform/aws/eks-intro#preparation -# https://learn.hashicorp.com/terraform/aws/eks-intro#configuring-kubectl-for-eks -# https://learn.hashicorp.com/terraform/aws/eks-intro#required-kubernetes-configuration-to-join-worker-nodes - -# Additional links -# https://learn.hashicorp.com/terraform/aws/eks-intro -# https://itnext.io/how-does-client-authentication-work-on-amazon-eks-c4f2b90d943b -# https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html -# https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html -# https://docs.aws.amazon.com/cli/latest/reference/eks/update-kubeconfig.html -# https://docs.aws.amazon.com/en_pv/eks/latest/userguide/create-kubeconfig.html -# https://itnext.io/kubernetes-authorization-via-open-policy-agent-a9455d9d5ceb -# http://marcinkaszynski.com/2018/07/12/eks-auth.html -# https://cloud.google.com/kubernetes-engine/docs/concepts/configmap -# http://yaml-multiline.info -# https://github.com/terraform-providers/terraform-provider-kubernetes/issues/216 -# https://www.terraform.io/docs/cloud/run/install-software.html -# https://stackoverflow.com/questions/26123740/is-it-possible-to-install-aws-cli-package-without-root-permission -# https://stackoverflow.com/questions/58232731/kubectl-missing-form-terraform-cloud -# https://docs.aws.amazon.com/cli/latest/userguide/install-bundle.html -# https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html - locals { - yaml_quote = var.aws_auth_yaml_strip_quotes ? "" : "\"" - - need_kubernetes_provider = local.enabled && var.apply_config_map_aws_auth - - kubeconfig_path_enabled = local.need_kubernetes_provider && var.kubeconfig_path_enabled - kube_exec_auth_enabled = local.kubeconfig_path_enabled ? false : local.need_kubernetes_provider && var.kube_exec_auth_enabled - kube_data_auth_enabled = local.kube_exec_auth_enabled ? false : local.need_kubernetes_provider && var.kube_data_auth_enabled - - exec_profile = local.kube_exec_auth_enabled && var.kube_exec_auth_aws_profile_enabled ? ["--profile", var.kube_exec_auth_aws_profile] : [] - exec_role = local.kube_exec_auth_enabled && var.kube_exec_auth_role_arn_enabled ? ["--role-arn", var.kube_exec_auth_role_arn] : [] - - cluster_endpoint_data = join("", aws_eks_cluster.default[*].endpoint) # use `join` instead of `one` to keep the value a string - cluster_auth_map_endpoint = var.apply_config_map_aws_auth ? local.cluster_endpoint_data : var.dummy_kubeapi_server - - certificate_authority_data_list = coalescelist(aws_eks_cluster.default[*].certificate_authority, [[{ data : "" }]]) - certificate_authority_data_list_internal = local.certificate_authority_data_list[0] - certificate_authority_data_map = local.certificate_authority_data_list_internal[0] - certificate_authority_data = local.certificate_authority_data_map["data"] - - # Add worker nodes role ARNs (could be from many un-managed worker groups) to the ConfigMap - # Note that we don't need to do this for managed Node Groups since EKS adds their roles to the ConfigMap automatically - map_worker_roles = [ - for role_arn in var.workers_role_arns : { - rolearn = role_arn - username = "system:node:{{EC2PrivateDNSName}}" - groups = [ - "system:bootstrappers", - "system:nodes" - ] - } - ] -} + # Extract the cluster certificate for use in OIDC configuration + certificate_authority_data = try(aws_eks_cluster.default[0].certificate_authority[0]["data"], "") + + eks_policy_short_abbreviation_map = { + # List available policies with `aws eks list-access-policies --output table` + + Admin = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy" + ClusterAdmin = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" + Edit = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSEditPolicy" + View = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy" + # Add new policies here + } + + eks_policy_abbreviation_map = merge({ for k, v in local.eks_policy_short_abbreviation_map : format("AmazonEKS%sPolicy", k) => v }, + local.eks_policy_short_abbreviation_map) -resource "null_resource" "wait_for_cluster" { - count = local.enabled && var.apply_config_map_aws_auth ? 1 : 0 - depends_on = [ - aws_eks_cluster.default, - aws_security_group_rule.custom_ingress_rules, - aws_security_group_rule.managed_ingress_security_groups, - aws_security_group_rule.managed_ingress_cidr_blocks, - ] - - provisioner "local-exec" { - command = var.wait_for_cluster_command - interpreter = var.local_exec_interpreter - environment = { - ENDPOINT = local.cluster_endpoint_data - } + + # Expand abbreviated access policies to full ARNs + access_entry_expanded_map = { for k, v in var.access_entry_map : k => merge({ + # Expand abbreviated policies to full ARNs + access_policy_associations = { for kk, vv in v.access_policy_associations : try(local.eks_policy_abbreviation_map[kk], kk) => vv } + # Copy over all other fields + }, { for kk, vv in v : kk => vv if kk != "access_policy_associations" }) + } + + # Replace membership in "system:masters" group with association to "ClusterAdmin" policy + access_entry_map = { for k, v in local.access_entry_expanded_map : k => merge({ + # Remove "system:masters" group from standard users + kubernetes_groups = [for group in v.kubernetes_groups : group if group != "system:masters" || v.type != "STANDARD"] + access_policy_associations = merge( + # copy all existing associations + v.access_policy_associations, + # add "ClusterAdmin" policy if the user was in "system:masters" group and is a standard user + contains(v.kubernetes_groups, "system:masters") && v.type == "STANDARD" ? { + "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" = { + access_scope = { + type = "cluster" + namespaces = null + } + } + } : {} + ) + # Copy over all other fields + }, { for kk, vv in v : kk => vv if kk != "kubernetes_groups" && kk != "access_policy_associations" }) } + + eks_access_policy_association_product_map = merge(flatten([ + for k, v in local.access_entry_map : [for kk, vv in v.access_policy_associations : { format("%s-%s", k, kk) = { + principal_arn = k + policy_arn = kk + } + }] + ])...) } +# The preferred way to keep track of entries is by key, but we also support list, +# because keys need to be known at plan time, but list values do not. +resource "aws_eks_access_entry" "map" { + for_each = local.enabled ? local.access_entry_map : {} + + cluster_name = local.eks_cluster_id + principal_arn = each.key + kubernetes_groups = each.value.kubernetes_groups + type = each.value.type -# Get an authentication token to communicate with the EKS cluster. -# By default (before other roles are added to the Auth ConfigMap), you can authenticate to EKS cluster only by assuming the role that created the cluster. -# `aws_eks_cluster_auth` uses IAM credentials from the AWS provider to generate a temporary token. -# If the AWS provider assumes an IAM role, `aws_eks_cluster_auth` will use the same IAM role to get the auth token. -# https://www.terraform.io/docs/providers/aws/d/eks_cluster_auth.html -# -# You can set `kube_exec_auth_enabled` to use a different IAM Role or AWS config profile to fetch the auth token -# -data "aws_eks_cluster_auth" "eks" { - count = local.kube_data_auth_enabled ? 1 : 0 - name = one(aws_eks_cluster.default[*].id) + tags = module.this.tags } +resource "aws_eks_access_policy_association" "map" { + for_each = local.enabled ? local.eks_access_policy_association_product_map : {} + + cluster_name = local.eks_cluster_id + principal_arn = each.value.principal_arn + policy_arn = each.value.policy_arn -provider "kubernetes" { - # Without a dummy API server configured, the provider will throw an error and prevent a "plan" from succeeding - # in situations where Terraform does not provide it with the cluster endpoint before triggering an API call. - # Since those situations are limited to ones where we do not care about the failure, such as fetching the - # ConfigMap before the cluster has been created or in preparation for deleting it, and the worst that will - # happen is that the aws-auth ConfigMap will be unnecessarily updated, it is just better to ignore the error - # so we can proceed with the task of creating or destroying the cluster. - # - # If this solution bothers you, you can disable it by setting var.dummy_kubeapi_server = null - host = local.cluster_auth_map_endpoint - cluster_ca_certificate = local.enabled && !local.kubeconfig_path_enabled ? base64decode(local.certificate_authority_data) : null - token = local.kube_data_auth_enabled ? one(data.aws_eks_cluster_auth.eks[*].token) : null - # The Kubernetes provider will use information from KUBECONFIG if it exists, but if the default cluster - # in KUBECONFIG is some other cluster, this will cause problems, so we override it always. - config_path = local.kubeconfig_path_enabled ? var.kubeconfig_path : "" - config_context = var.kubeconfig_context - - dynamic "exec" { - for_each = local.kube_exec_auth_enabled && length(local.cluster_endpoint_data) > 0 ? ["exec"] : [] - content { - api_version = "client.authentication.k8s.io/v1beta1" - command = "aws" - args = concat(local.exec_profile, ["eks", "get-token", "--cluster-name", try(aws_eks_cluster.default[0].id, "deleted")], local.exec_role) - } + access_scope { + type = local.access_entry_map[each.value.principal_arn].access_policy_associations[each.value.policy_arn].access_scope.type + namespaces = local.access_entry_map[each.value.principal_arn].access_policy_associations[each.value.policy_arn].access_scope.namespaces } } -resource "kubernetes_config_map" "aws_auth_ignore_changes" { - count = local.enabled && var.apply_config_map_aws_auth && var.kubernetes_config_map_ignore_role_changes ? 1 : 0 - depends_on = [null_resource.wait_for_cluster] +# We could combine all the list access entries into a single resource, +# but separating them by category minimizes the ripple effect of changes +# due to adding and removing items from the list. +resource "aws_eks_access_entry" "standard" { + count = local.enabled ? length(var.access_entries) : 0 - metadata { - name = "aws-auth" - namespace = "kube-system" - } + cluster_name = local.eks_cluster_id + principal_arn = var.access_entries[count.index].principal_arn + kubernetes_groups = var.access_entries[count.index].kubernetes_groups + type = "STANDARD" - data = { - mapRoles = yamlencode(distinct(concat(local.map_worker_roles, var.map_additional_iam_roles))) - mapUsers = yamlencode(var.map_additional_iam_users) - mapAccounts = yamlencode(var.map_additional_aws_accounts) - } + tags = module.this.tags +} - lifecycle { - ignore_changes = [data["mapRoles"]] - } +resource "aws_eks_access_entry" "linux" { + count = local.enabled ? length(lookup(var.access_entries_for_nodes, "EC2_LINUX", [])) : 0 + + cluster_name = local.eks_cluster_id + principal_arn = var.access_entries_for_nodes.EC2_LINUX[count.index] + type = "EC2_LINUX" + + tags = module.this.tags } -resource "kubernetes_config_map" "aws_auth" { - count = local.enabled && var.apply_config_map_aws_auth && var.kubernetes_config_map_ignore_role_changes == false ? 1 : 0 - depends_on = [null_resource.wait_for_cluster] +resource "aws_eks_access_entry" "windows" { + count = local.enabled ? length(lookup(var.access_entries_for_nodes, "EC2_WINDOWS", [])) : 0 - metadata { - name = "aws-auth" - namespace = "kube-system" - } + cluster_name = local.eks_cluster_id + principal_arn = var.access_entries_for_nodes.EC2_WINDOWS[count.index] + type = "EC2_WINDOWS" + + tags = module.this.tags +} + +resource "aws_eks_access_policy_association" "list" { + count = local.enabled ? length(var.access_policy_associations) : 0 + + cluster_name = local.eks_cluster_id + principal_arn = var.access_policy_associations[count.index].principal_arn + policy_arn = try(local.eks_policy_abbreviation_map[var.access_policy_associations[count.index].policy_arn], + var.access_policy_associations[count.index].policy_arn) - data = { - mapRoles = replace(yamlencode(distinct(concat(local.map_worker_roles, var.map_additional_iam_roles))), "\"", local.yaml_quote) - mapUsers = replace(yamlencode(var.map_additional_iam_users), "\"", local.yaml_quote) - mapAccounts = replace(yamlencode(var.map_additional_aws_accounts), "\"", local.yaml_quote) + access_scope { + type = var.access_policy_associations[count.index].access_scope.type + namespaces = var.access_policy_associations[count.index].access_scope.namespaces } } diff --git a/docs/migration-v1-v2.md b/docs/migration-v1-v2.md index 7f4cbd97..48463084 100644 --- a/docs/migration-v1-v2.md +++ b/docs/migration-v1-v2.md @@ -10,7 +10,9 @@ by the user, to ensure the nodes and control plane can communicate. Before version 2, this module, by default, created an additional Security Group. Prior to version `0.19.0` of this module, that additional Security Group was the only one exposed by this module (because EKS at the time did not create the managed Security Group for the cluster), and it was intended that all worker nodes (managed and unmanaged) be placed in this additional Security Group. With version `0.19.0`, this module exposed the managed Security Group created by the EKS cluster, in which all managed node groups are placed by default. We now -recommend placing non-managed node groups in the EKS-created Security Group as well by using the `allowed_security_group_ids` variable, and not create an additional Security Group. +recommend placing non-managed node groups in the EKS-created Security Group +as well by using the `eks_cluster_managed_security_group_id` output to +associate the node groups with it, and not create an additional Security Group. See https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html for more details. diff --git a/docs/migration-v3-v4.md b/docs/migration-v3-v4.md new file mode 100644 index 00000000..b674e42c --- /dev/null +++ b/docs/migration-v3-v4.md @@ -0,0 +1,732 @@ +# Migration From Version 2 or 3 to Version 4 + +Users new to this module can skip this document and proceed to the main README. +This document is for users who are updating from version 2 or 3 to version 4. +Unfortunately, there is no "tl;dr" for this document, as the changes are +substantial and require careful consideration. + +This guild consists of 4 parts: + +1. [Summary and Background](#summary-and-background): A brief overview of the + changes in version 4, what motivated them, and what they mean for you. +2. [Configuration Migration Overview](#configuration-migration-overview): A + high-level overview of the changes you will need to make to your + configuration to update to version 4. The inputs to this module have + changed substantially, and you will need to update your configuration to + match the new inputs. +3. [Configuration Migration Details](#configuration-migration-details): A + detailed explanation of the changes you will need to make to your + configuration to update to version 4. +4. [Cluster Migration Steps](#cluster-migration-steps): Detailed instructions + for migrating your EKS cluster to be managed by version 4. After you have + updated your configuration, you will still need to take some additional + manual steps to have Terraform upgrade and manage your existing EKS + cluster with the new version 4 configuration. This step can be skipped if + you can tolerate simply creating a new EKS cluster and deleting the old one. + + +#### Usage notes + +> [!CAUTION] +> Hopefully, and likely, the following does not apply to you, but just in case: +> +> It has always been considered a bad practice to manage resources +> created by one resource (in this case, the EKS cluster) with another +> resource (in this case resources provided by the `kubernetes` or +> `helm` providers) in the same Terraform configuration, because of +> issues with lifecycle management, timing, atomicity, etc. This +> `eks-cluster` module used to do it anyway because it was the only +> way to manage access control for the EKS cluster, but it did suffer +> from those issues. Now that it is no longer necessary, the module no +> longer does it, and it is a requirement that you remove the +> "kubernetes" and "helm" providers from your root module or +> component, if present, and therefore any `kubernetes_*` or `helm_*` +> resources that were being managed by it. In most cases, this will be a +> non-issue, because you should already be managing such resources +> elsewhere, but if you had been integrating Kubernetes deployments into your +> EKS cluster configuration and find changing that too challenging, then you +> should delay the upgrade to version 4 of this module until you can address it. + +- We recommend leaving `bootstrap_cluster_creator_admin_permissions` set to + `false`. When set to `true`, EKS automatically adds an access entry for the + EKS cluster creator during creation, but this interferes with Terraform's + management of the access entries, and it is not recommended for Terraform + users. Note that now that there is an API for managing access to the EKS + cluster, it is no longer necessary to have admin access to the cluster in + order to manage access to it. You only need to have the separate IAM + permission [`eks:CreateAccessEntry`](https://docs.aws.amazon.com/eks/latest/APIReference/API_CreateAccessEntry.html) + to add an access entry to the cluster and `eks:AssociateAccessPolicy` to give + that entry ClusterAdmin permissions. +- As of the release of version 4 of this module, it remains an issue that + AWS Identity Center auto-generates IAM roles with non-deterministic ARNs + to correspond to Permission Sets. Changes to the Permission Set will cause + the ARN of the corresponding IAM role to change. This will invalidate any + EKS Access Entry that used the old IAM role ARN, requiring you to remove + the old access entry and add the new one. Follow [`containers-roadmap` + issue 474](https://github.com/aws/containers-roadmap/issues/474) for + updates on features that will mitigate this issue. +- For new clusters, we recommend setting `access_config.authentication_mode + = "API"` to use the new access control API exclusively, so that is the + default. However, AWS does not support a direct upgrade from the legacy + `CONFIG_MAP` mode to the `API` mode, so when upgrading an existing EKS + cluster, you must manually configure the `API_AND_CONFIG_MAP` mode for the initial upgrade. + +## Summary and Background + +Version 4 of this module introduces several breaking changes that will +require updates to your existing configuration. Major changes include: + +- Removal of any management of the `aws-auth` ConfigMap. This module now + uses the AWS API to manage access to the EKS cluster, and no longer interacts + with the ConfigMap directly in any way. +- Removal of the Kubernetes Terraform provider. It was only used to interact with + the `aws-auth` ConfigMap, and is no longer necessary. +- Addition of Kubernetes access control via the AWS API, specifically + Access Entries and Associated Access Policies. +- Replacement of inputs associated with configuring the `aws-auth` ConfigMap + with new inputs for configuring access control using the new AWS API. This + was done in part to ensure that there is no ambiguity about which format + of IAM Principal ARN is required, and what restrictions apply to the + Kubernetes group memberships. +- Restoration of the path component in any IAM Principal ARNs. When using + the legacy `aws-auth` ConfigMap, the path component in any IAM Principal + ARN had to be removed from the ARN, and the modified ARN was used in the + ConfigMap. This was a workaround for a limitation in the AWS + Implementation. With full AWS API support for access control, the path + component is no longer removed, and the full ARN is required. +- Removal of any support for creating an additional Security Group for + worker nodes. This module now only allows some addition of rules to the + EKS-managed Security Group. Normally you would associate all worker nodes + with that Security Group. (Worker nodes can be associated with additional + Security Groups as well if desired.). This includes the removal of the + `vpc_id` input, which was only needed for creating the additional Security + Group. +- Replacement of `aws_security_group_rule` resources with the newer + `aws_vpc_security_group_ingress_rule` resources for adding ingress rules to + the EKS-managed Security Group. For people who were adding ingress rules to + the EKS-managed Security Group, This will cause a brief interruption in + communication as the old rules are removed and the new rules are added. The + benefit is that you can then use the new + `aws_vpc_security_group_ingress_rule` and + `aws_vpc_security_group_egress_rule` resources to manage the rules in your + root module or a separate component, allowing you much more control and + flexibility over the rules than this module provides. + +### Access to the EKS cluster + +The primary credential used for accessing any AWS resource is your AWS IAM +user or role, more generally referred to as an IAM principal. Previously, +EKS clusters contained a Kubernetes ConfigMap called `aws-auth` that was used +to map IAM principals to Kubernetes RBAC roles. This was the only way to +grant access to the EKS cluster, and this module managed the `aws-auth` ConfigMap +for you. However, managing a Kubernetes resource from Terraform was not ideal, +and managing any resource created by another resource in the same Terraform +configuration is not supported by Terraform. Prior to v4, this module relied +on a series of tricks to get around these limitations, but it was far from +a complete solution. + +In v4, this module now uses the [new AWS API](https://github.com/aws/containers-roadmap/issues/185#issuecomment-1863025784) +to manage access to the EKS cluster and no longer interacts with the +`aws-auth` ConfigMap directly. + +### Security Groups + +This module creates an EKS cluster, which automatically creates an EKS-managed +Security Group in which all managed nodes are placed automatically by EKS, and +unmanaged nodes could be placed by the user, to ensure the nodes and control +plane can communicate. + +In version 2, there was legacy support for creating an additional Security Group +for worker nodes. (See the [version 2 migration documentation] +(migration-v1-v2.md) for more information about the legacy support.) +This support has been removed in version 4, and this module now only supports +some configuration of the EKS-managed Security Group, enabled by the +`managed_security_group_rules_enabled` variable. + + +## Configuration Migration Overview + +If you are deploying a new EKS cluster with this module, no special steps +need to be taken, although we recommend setting +`access_config.authentication_mode = "API"` to use the new access control +API exclusively. By default, the module enables both the API and the `aws-auth` +ConfigMap to allow for a smooth transition from the old method to the new one. + +### Removed variables + +- Variables deprecated in version 2 have been removed in version 4. These + include anything related to creating or managing a Security Group + distinct from the one automatically created for the cluster by EKS. + +- Any variables relating to the Kubernetes Terraform provider or the + `aws-auth` ConfigMap have been removed, and the provider itself has been + removed. + +- Any variables configuring access to the EKS cluster, such + as `map_additional_iam_roles` and `workers_role_arns`, have been removed and + replaced with new variables with names starting with `access_` that configure + access control using the new AWS API. + +### Removed outputs + +- The `kubernetes_config_map_id` output has been removed, as the module no + longer manages the `aws-auth` ConfigMap. If you had been using this output + to "depend_on" before creating other resources, you probably no longer + need to configure an explicit dependency. + +- Any outputs related to the additional Security Group have been removed. + +## Configuration Migration Steps + +### Access Control Configuration + +The primary change in version 4 is the new way of configuring access to the +EKS cluster. This is done using the new AWS API for managing access to the +EKS cluster, specifically Access Entries and Associated Access Policies. +To support the transition of existing clusters, AWS now allows the cluster +to be in one of 3 configuration modes: "CONFIG_MAP", "API", or +"API_AND_CONFIG_MAP". This module defaults to "API", which is the recommended +configuration for new clusters. However, existing clusters will be using the +"CONFIG_MAP" configuration (previously the only option available), and AWS +does not support direct upgrade from "CONFIG_MAP" to "API". Therefore: + +> [!NOTE] +> When updating an existing cluster, you will need to set `authentication_mode` +> to "API_AND_CONFIG_MAP" in your configuration, and then update the cluster. +> After the cluster has been updated, you can set `authentication_mode` to +> the default value of "API" and update the cluster again, but you cannot +> directly upgrade from "CONFIG_MAP" to "API". + +### Consideration: Information Known and Unknown at Plan Time + +Previously, all access control information could be unknown at plan time +without causing any problems, because at plan time Terraform only cares about +whether a resource (technically, a resource address) is created or not, and the +single `aws-auth` ConfigMap was always created. + +Now, each piece of the access control configuration is a separate resource, +which means it has to be created via either `count` or `for_each`. There are +tradeoffs to both approaches, so you will have to decide which is best for +your situation. See [Count vs For Each](https://docs.cloudposse.com/reference/terraform-in-depth/terraform-count-vs-for-each/) +for a discussion of the issues that arise when creating resources from +lists using `count`. + +To configure access using `for_each`, you can use the `access_entry_map` input. +This is the preferred approach, as it keeps any entry from changing +unnecessarily, but it requires that all IAM principal ARNs, Kubernetes group +memberships, and EKS access policy ARNs are known at plan time, and that +none of them are designated as "sensitive". + +If you cannot use `access_entry_map` for some entries, you can use it for +the ones that are known at plan time and use the pair of inputs `access_entries` +and `access_policy_associations` for the ones that are not. These inputs +take lists, and resources are created via `count`. There is a separate +list-based input for self-managed nodes, `access_entries_for_nodes`, because +nodes are managed differently from other access entries. + +These list-based inputs only require you know the number of entries at plan +time, not the specific entries themselves. However, this still means you cannot +use functions that can modify the length of the list, such as `compact` or, +[prior to Terraform v1.6.0, `sort`](https://github.com/hashicorp/terraform/issues/31035). +See [Explicit Transformations of Lists](https://docs.cloudposse.com/reference/terraform-in-depth/terraform-unknown-at-plan-time/#explicit-transformations-of-lists) +for more information on limitations on list transformations. + +### Migrating Access for Standard Users + +Access for standard users is now configured using a combination of +Kubernetes RBAC settings and the new [AWS EKS Access Policies](https://docs.aws.amazon.com/eks/latest/userguide/access-policies.html#access-policy-permissions). +As explained above under [Consideration: Information Known and Unknown at Plan Time](#consideration-information-known-and-unknown-at-plan-time), +there are both map-based and list-based inputs for configuring access. + +Whereas previously your only option was to assign IAM Principals to Kubernetes +RBAC Groups, you can now also associate IAM Principals with EKS Access Policies. + +Unfortunately, migration from the old method to the new one is not as +straightforward as we would like. + +#### Restoration of the Path Component in IAM Principal ARNs + +> [!WARNING] +> Previously, when using the `aws-auth` ConfigMap, the path component in any +> IAM Principal ARN had to be removed from the ARN, and the modified ARN was +> used in the ConfigMap. Quoting from the [AWS EKS documentation](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html#aws-auth-users): +> > The role ARN [used in `aws-auth`] can't include a path such as +> >`role/my-team/developers/my-role`. The format of the ARN must be +> >`arn:aws:iam::111122223333:role/my-role`. In this example, +> > `my-team/developers/` needs to be removed. +> +> This was a workaround for a limitation in the AWS Implementation. With +> full AWS API support for access control, the path component is no longer +> removed, and the full ARN is required. +> +> If you had been using the `aws-auth` ConfigMap, you should have been +> removing the path component either manually as part of your static +> configuration, or programmatically. **You will need to undo these +> transformations and provide the full ARN in the new configuration.** + +#### Migrating from Kubernetes RBAC Groups to EKS Access Policies + +##### EKS Access Policy ARNs, Names, and Abbreviations + +Previously, the only way to specify access to the EKS cluster was to assign +IAM Principals to Kubernetes RBAC Groups. Now, you can also associate IAM +Principals with EKS Access Policies. Full EKS Access Policy ARNs can be +listed via the AWS CLI with the command `aws eks list-access-policies` and +look like `arn:aws:eks::aws:cluster-access-policy/AmazonEKSAdminPolicy`. In +AWS documentation and some other contexts, these policies are referred by +name, for example `AmazonEKSAdminPolicy`. The name is the last component of +the ARN, and always matches the regex `^AmazonEKS(.*)Policy$`. + +In this module, wherever an EKS Access Policy ARN is required, you can use +the full ARN, the full name (e.g. "AmazonEKSAdminPolicy"), or the +abbreviated name (e.g. "Admin"). The abbreviated name is the `$1` part of the +regex `^AmazonEKS(.*)Policy$`. This document will usually use the abbreviated +name. + +##### Changes to Kubernetes RBAC Groups + +Previously, we created cluster administrators by assigning them to +the `system:masters` group. With the new AWS API, we can no longer assign any +users to any of the `system:*` groups. We have to create Cluster Administrators +by associating the ClusterAdmin policy with them, with type `cluster`. + +> [!TIP] +> As a special case, the `system:masters` Kubernetes group is still supported by +> this module, but only when using `access_entry_map` and `type = "STANDARD"`. In +> this case, the `system:masters` group is automatically replaced with an +> association with the `ClusterAdmin` policy. + +> [!NOTE] +> Note that this substitution is not done for `access_entries` because the +> use case for `access_entries` is when values are not known at plan time, +> and the substitution requires knowing the value at plan time. + +Any other `system:*` groups, such as `system:bootstrappers` or `system:nodes` +must be removed. (Those specific groups are assigned automatically by AWS +when using `type` other than `STANDARD`.) + +If you had been assigning users to any other Kubernetes RBAC groups, you can +continue to do so, and we recommend it. +At Cloud Posse, we have found that the pre-defined `view` and `edit` groups +are unsatisfactory, because they do not allow access to Custom Resources, +and we expect the same limitations will make the View and Edit EKS Access +Policies unsatisfactory. We bypass these limitations by creating our own +groups and roles, and by enhancing the `view` role using the label: + +``` +rbac.authorization.k8s.io/aggregate-to-view: "true" +``` + +It is not clear whether changes to the `view` role affect the View EKS Access +Policy, but we expect that they do not, which is why we recommend continuing +to use Kubernetes RBAC groups for roles other than ClusterAdmin and Admin. + +### Migrating Access for Self-Managed Nodes + +There is almost nothing to configure to grant access to the EKS cluster for +nodes, as AWS handles everything fully automatically for EKS-managed nodes +and Fargate nodes. + +For self-managed nodes (which we no longer recommend using), you can use the +`access_entries_for_nodes` input, which is a pair of lists, one for Linux worker +nodes and one for Windows worker nodes. AWS manages all the access for these +nodes, so you only need to provide the IAM roles that the nodes will assume; +there is nothing else to configure. + +The `access_entries_for_nodes` input roughly corresponds to the removed +`workers_role_arns` input, but requires separating Linux workers from +Windows workers. There is no longer a need to configure Fargate nodes at all, +as that is fully automatic in the same way that EKS managed nodes are. + +### Example Access Entry Migration + +Here is an example of how you might migrate access configuration from version +3 to version 4. If you previously had a configuration like this: + +```hcl + map_additional_iam_roles = [ + { + rolearn = replace(data.aws_iam_role.administrator_access.arn, "${data.aws_iam_role.administrator_access.path}/", "") + username = "devops" + groups = ["system:masters", "devops"] + }, + { + rolearn = data.aws_iam_role.gitlab_ci.arn + username = "gitlab-ci" + groups = ["system:masters", "ci"] + }, + { + rolearn = aws_iam_role.karpenter_node.arn + username = "system:node:{{EC2PrivateDNSName}}" + groups = ["system:bootstrappers", "system:nodes"] + }, + { + rolearn = aws_iam_role.fargate.arn + username = "system:node:{{SessionName}}" + groups = ["system:bootstrappers", "system:nodes", "system:node-proxier"] + }, +] +``` + +You can migrate it as follows. Remember, you have the option of keeping +`systems:masters` as a Kubernetes group when using `access_entry_map`, but we +do not recommend that, as it is only provided for backwards compatibility, +and is otherwise a confusing wart that may eventually be removed. + +Also note that we have removed the username for `devops` as a [best practice +when using roles](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html#creating-access-entries), +and we recommend you only use usernames for users. We kept the username for +`gitlab-ci` only so you would have an example. + +The new map-based configuration, using defaults, and showing how to set up +ClusterAdmin with and without `systems:masters`: + +```hcl + access_entry_map = { + # Note that we no longer remove the path! + (data.aws_iam_role.administrator_access.arn) = { + kubernetes_groups = ["devops"] + access_policy_associations = { + ClusterAdmin = {} + } + } + (data.aws_iam_role.gitlab_ci.arn) = { + kubernetes_groups = ["systems:masters", "ci"] + user_name = "gitlab-ci" + } + } + # Use access_entries_for_nodes for self-managed node groups + access_entries_for_nodes = { + EC2_LINUX = [aws_iam_role.karpenter_node.arn] + } + # No need to configure Fargate nodes +``` + +## Cluster Migration Steps + +### Pt. 1: Prepare Your Configuration + +#### Ensure your cluster satisfies the prerequisites + +Verify that your cluster satisfies [the AWS prerequisites](https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html#access-entries-prerequisites) for using the new access control API. + +Verify that you are not using the `kubernetes` or `helm` provider in your root +module, or managing any Kubernetes resources (including Helm charts). Run: + +```shell +terraform state list | grep -E 'helm_|kubernetes_' +``` + +> [!NOTE] +> If you are using `atmos`, you can use the following commands to +> set up your environment to run Terraform commands: +> +> ```shell +> cd $(atmos describe component -s -f json \ +> | jq -r '.component_info.terraform_config.path') +> atmos terraform shell -s +> ``` + +There should only be one resource output from this command, either `aws_auth[0]` +or `aws_auth_ignore_changes[0]`, which is created by earlier versions +of this module. If there are more resources listed, you need to investigate +further to find and remove the source of the resource. Any other +`kubernetes_*` resources (and any `helm_*` resources) are coming from other +places and need to be moved or removed before upgrading. You should not +attempt an upgrade to version 4 until you have moved or removed management +of these resources. See the "Caution" under [Usage notes](#usage-notes) +above for details. + +#### Migrate your access control configuration + +There is not exactly a rote transformation from the old access control +configuration to the new one, and there are some new wrinkles to consider. +Follow the guidance provided above under [Configuration Migration Steps](#configuration-migration-steps). + +#### Migrate management of additional security group (if applicable) + +For historical reasons, this module previously supported creating an +additional Security Group, with the idea that it would be used for worker +nodes. You can find some more information about this in the [Migration From v1 to v2](migration-v1-v2.md#background) document. + +If you had **not** set `create_security_group = true` in version 2 (you +either set it to `false` or left it at its default value), you +can skip this step. + +If you **had** set `create_security_group = true` and you do nothing about it +before updating to version 4, Terraform will try to remove the Security +Group and most likely fail with a timeout error because the Security Group +is still associated with some resources. + +You have several options for how to proceed: + +1. Manually delete the Security Group and remove any usage of it. It may be + that it was not being used, or it was being used in a redundant fashion + and thus was not needed. It may also be that it was being used to provide + this module with access to the EKS control plane, so that it could manage + the `aws-auth` ConfigMap. Since that access is no longer needed, you + might be able to safely delete the Security Group without any replacement. + +1. Manually delete the Security Group and migrate any usage and + configuration of it to the EKS-managed Security Group. This is discussed + in the next section. + +1. Manually delete the Security Group and create a new one in your root + module or a separate component, using our [security-group module](https://github.com/cloudposse/terraform-aws-security-group). + + +Because this is a complex operation with several options and potential +impacts, and because this feature had been deprecated for a long time, we are +not providing further instructions here. If you need assistance with this, +please contact [Cloud Posse Professional Services](https://cloudposse.com/professional-services/) +for options and pricing. + +#### Migrate management of EKS-managed security group (if applicable) + +EKS creates a Security Group for the cluster, and all managed nodes are +automatically associated with that Security Group. The primary purpose of that +security group is to enable communication between the nodes and the Kubernetes +control plane. + +When you create a node group for the cluster, even an EKS managed node group, +you can associate the nodes with additional Security Groups as well. +As a best practice, you would modify a node group Security Group to allow +communication between the nodes and other resources, such as a database, or +even the public internet via a NAT Gateway, while leaving the EKS managed +Security Group alone, to protect the control plane. You would manage the +rules for the node group's Security Group along with managing the node group. + +However, people often instead modify the EKS-managed Security Group to allow +the necessary communication rather than create a separate Security group. +This was previously necessary in order to allow the v2 version of this +module to be able to manage the `aws-auth` ConfigMap via the Kubernetes +control plane. + +Depending on your use cases and security posture, you may want to migrate +existing access rules to a new security group, or you may want to modify the +rules in the EKS-managed Security Group to allow the necessary communication. + +This module retains some of the v2 features that allow you to add ingress +rules to the EKS-managed Security Group, but it no longer allows you to +create and manage a separate Security Group for worker nodes, as explained +above. + +To make changes to the EKS-managed Security Group, we recommend that +you either directly use the `aws_vpc_security_group_ingress_rule` and +`aws_vpc_security_group_egress_rule` resources in your root module, or use a +specialized module such as Cloud Posse's [security-group module] +(https://github.com/cloudposse/terraform-aws-security-group) (once v3 is +released) to manage the rules. This will give you much more control and +flexibility over the rules than this module provides. + +For backward compatibility, this module still supports adding ingress +rules to the EKS-managed Security Group, which may be sufficient for the +simple case of allowing ingress from anything in your VPC. To use this +feature: + +1. Set `managed_security_group_rules_enabled = true` in your configuration. + Without this, any other settings affecting the security group will be + ignored. +2. Allow all ingress from designated security groups by adding their IDs to + `allowed_security_group_ids`. +3. Allow all ingress from designated CIDR blocks by adding them to + `allowed_cidr_blocks`. +4. You can add more fine-grained ingress rules via the + `custom_ingress_rules` input, but this input requires that the source + security group ID be known at plan time and that there is no more than + one single rule per source security group. + + +### Pt. 2: No Going Back + +> [!WARNING] +> Once you proceed with the following steps, there is no going back. +> AWS will not allow you to disable the new access control API once it is +> enabled, and restoring this modules access to the `aws-auth` ConfigMap +> will be difficult if not impossible, and we do not support it. + +#### Update your module reference to v4 + +Update your module reference to version 4.0.0 or later in your root module or +component. Ensure that you have updated all the inputs to the module to match +the new inputs. + +Run `terraform plan` and fix any errors you get, such as "Unsupported +argument", until the only error you are left with is something like: + +```plaintext +Error: Provider configuration not present +β”‚ +β”‚ To work with module.eks_cluster.kubernetes_config_map.aws_auth[0] (orphan) +| its original provider configuration at ... is required, but it has been removed. +``` + +or + +```plaintext +β”‚ Error: Get β€œhttp://localhost/api/v1/namespaces/kube-system/configmaps/aws-auth”: dial tcp [::1]:80: connect: connection refused +``` + +#### Remove the `auth-map` from the Terraform state + +If you got the error message about the `auth-map` being an orphan, then +take the "resource address" of the `auth-map` from the error message (the +part before "`(orphan)`") and remove it from the terraform state. Using the +address from the error message above, you would run: + +```shell +terraform state rm 'module.eks_cluster.kubernetes_config_map.aws_auth[0]' +``` + +It is important to include the single quotes around the address, because +otherwise `[0]` would be interpreted as a shell glob. + +If you got the "connection refused" error message, then you need to find the +resource(s) to remove from the state. You can do this by running: + +```shell +terraform state list | grep kubernetes_ +``` + +There should only be one resource output from this command. If there are +more, then review the "Caution" under [Usage notes](#usage-notes) and the +[Prerequisites](#ensure-your-cluster-satisfies-the-prerequisites) above. + +Use the address output from the above command to remove the resource from +the Terraform state, as shown above. + +Run `terraform plan` again, at which point you should see no errors. + +#### Review the changes + +You should review the changes that Terraform is planning to make to your +cluster. Calmly. Expect some changes. + +- `...null_resource.wait_for_cluster[0]` will be **destroyed**. This is + expected, because it was part of the old method of managing the `aws-auth` ConfigMap. +- Various `aws_security_group_rule` resources will be **destroyed**. They + should be replaced with corresponding + `aws_vpc_security_group_ingress_rule` resources. Note that if you had + specified multiple ingress CIDRs in `allowed_cidr_blocks`, the used to be + managed by a single `aws_security_group_rule` resource, but now each CIDR + is managed by a separate `aws_vpc_security_group_ingress_rule` resource, + so you may see more rule resources being created than destroyed. +- `...aws_eks_cluster.default[0]` will be **updated**. This is expected, + because the `authentication_mode` is changing from "CONFIG_MAP" to + "API_AND_CONFIG_MAP". This is the main point of this upgrade. +- Expect to see resources of `aws_eks_access_entry` and + `aws_eks_access_policy_association` being **created**. These are the new + resources that manage access to the EKS cluster, replacing the entries in + the old `aws-auth` ConfigMap. +- You will likely see changes to `...aws_iam_openid_connect_provider.default[0]`. + This is because it depends on the `aws_eks_cluster` resource, specifically + its TLS certificate, and the `aws_eks_cluster` resource is being updated, + so Terraform cannot be sure that the OIDC provider will not need to be + updated as well. This is expected and harmless. +- You will likely see changes to IRSA (service account role) resources. This + is because they depend on the OIDC provider, and the OIDC provider may + need to be updated. This is expected and harmless. + +#### Apply the changes + +Apply the changes with `terraform apply` and verify you still have access to +the cluster and that everything is working as expected. + +##### Error: creating EKS Access Entry + +You may get an error message like this: + +```plaintext +Error: creating EKS Access Entry +(eg-test-eks-cluster:arn:aws:iam::123456789012:role/eg-test-terraform): + operation error EKS: CreateAccessEntry, + https response error StatusCode: 409, RequestID: ..., ResourceInUseException: + The specified access entry resource is already in use on this cluster. +``` + +This is because, during the conversion from "CONFIG_MAP" to +"API_AND_CONFIG_MAP", EKS automatically adds an access entry for the EKS +cluster creator. + +If you have been following Cloud Posse's recommendations, you will have +configured ClusterAdmin access for the IAM principal that you used to create +the EKS cluster. This configuration duplicates the automatically created access +entry, resulting in the above error. + +We have not found a way to avoid this situation, so our best recommendation is, +if you encounter it, import the automatically created access entry into your +Terraform state. The `access entry ID` to import is given in the error +message in parentheses. In the example above, the ID is +`eg-test-eks-cluster:arn:aws:iam::123456789012:role/eg-test-terraform`. + +The Terraform `resource address` for the resource will depend on your usage. +Probably the easiest way to find it is to run `terraform plan` and look for the +corresponding access entry resource that Terraform will want to create. It +will be something like + +```plaintext +...aws_eks_access_entry.map["arn:aws:iam::123456789012:role/eg-test-terraform"] +``` + +although it may be `standard` instead of `map`. + +To import the resource using `atmos`, use the same component and stack name +as you were using to deploy the cluster, and run a command like + +```shell +atmos terraform import \ + \ + -s= +``` + +To import the resource using Terraform, again, you need to supply the same +configuration that you used to deploy the cluster, and run a command like + +```shell +terraform import -var-file +``` + +After successfully importing the resource, run `terraform apply` again to +add tags to the entry and verify that no other changes are outstanding. + +#### Verify access to the cluster + +Verify that you still have the access to the cluster that you expect. + +- Assume an IAM role (or set your `AWS_PROFILE` environment variable) so that + you are using credentials that should have Cluster Admin access to the + cluster +- Set your `AWS_DEFAULT_REGION` to the region where the cluster is located +- Run `aws eks update-kubeconfig --name ` to configure `kubectl` + to reference the cluster +- Run `kubectl get nodes` to verify that you can see the nodes in the cluster + +You might further explore your access using other tools. The simplest, if +you are a Cluster Admin, is to run: + +```shell +kubectl auth can-i '*' '*' +``` + +which will return `yes` if you have full access to the cluster. + +For a more detailed report, you can use [rakkess](https://github.com/corneliusweig/rakkess), +which is available via many avenues, including Cloud Posse's package repository, +and is installed by default on some versions of Geodesic. + +#### Clean up + +At this point you have both the old and new access control methods enabled, +but nothing is managing the `aws-auth` ConfigMap. You can now proceed to +migrate the cluster to be managed solely by the new access control API, and +manually remove the `aws-auth` ConfigMap. + +- Update the `authentication_mode` to "API" in your configuration, and run + `terraform apply` again. This will cause EKS to ignore the `aws-auth` + ConfigMap, but will not remove it. +- Manually remove the `aws-auth` ConfigMap. You can do this with `kubectl + delete configmap aws-auth --namespace kube-system`. This will not affect + the cluster, because it is now being managed by the new access control API, + but it will reduce the possibility of confusion in the future. + + diff --git a/docs/terraform.md b/docs/terraform.md index c68f8a28..d70b365a 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -4,18 +4,14 @@ | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.3.0 | -| [aws](#requirement\_aws) | >= 5.0.0 | -| [kubernetes](#requirement\_kubernetes) | >= 2.7.1 | -| [null](#requirement\_null) | >= 2.0 | +| [aws](#requirement\_aws) | >= 5.34.0 | | [tls](#requirement\_tls) | >= 3.1.0, != 4.0.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 5.0.0 | -| [kubernetes](#provider\_kubernetes) | >= 2.7.1 | -| [null](#provider\_null) | >= 2.0 | +| [aws](#provider\_aws) | >= 5.34.0 | | [tls](#provider\_tls) | >= 3.1.0, != 4.0.0 | ## Modules @@ -30,6 +26,12 @@ | Name | Type | |------|------| | [aws_cloudwatch_log_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | +| [aws_eks_access_entry.linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_entry.map](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_entry.standard](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_entry.windows](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_entry) | resource | +| [aws_eks_access_policy_association.list](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_policy_association) | resource | +| [aws_eks_access_policy_association.map](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_access_policy_association) | resource | | [aws_eks_addon.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) | resource | | [aws_eks_cluster.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_cluster) | resource | | [aws_iam_openid_connect_provider.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider) | resource | @@ -40,18 +42,9 @@ | [aws_iam_role_policy_attachment.cluster_elb_service_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_kms_alias.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | | [aws_kms_key.cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | -| [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource | -| [aws_security_group_rule.custom_ingress_rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.ingress_workers](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.managed_ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [aws_security_group_rule.managed_ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource | -| [kubernetes_config_map.aws_auth](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource | -| [kubernetes_config_map.aws_auth_ignore_changes](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | resource | -| [null_resource.wait_for_cluster](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | -| [aws_eks_cluster_auth.eks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/eks_cluster_auth) | data source | +| [aws_vpc_security_group_ingress_rule.custom_ingress_rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.managed_ingress_cidr_blocks](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | +| [aws_vpc_security_group_ingress_rule.managed_ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource | | [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_iam_policy_document.cluster_elb_service_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | | [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | @@ -61,16 +54,18 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [access\_config](#input\_access\_config) | Access configuration for the EKS cluster. |
object({
authentication_mode = optional(string, "API")
bootstrap_cluster_creator_admin_permissions = optional(bool, false)
})
| `{}` | no | +| [access\_entries](#input\_access\_entries) | List of IAM principles to allow to access the EKS cluster.
It is recommended to use the default `user_name` because the default includes
the IAM role or user name and the session name for assumed roles.
Use when Principal ARN is not known at plan time. |
list(object({
principal_arn = string
user_name = optional(string, null)
kubernetes_groups = optional(list(string), null)
}))
| `[]` | no | +| [access\_entries\_for\_nodes](#input\_access\_entries\_for\_nodes) | Map of list of IAM roles for the EKS non-managed worker nodes.
The map key is the node type, either `EC2_LINUX` or `EC2_WINDOWS`,
and the list contains the IAM roles of the nodes of that type.
There is no need for or utility in creating Fargate access entries, as those
are always created automatically by AWS, just as with managed nodes.
Use when Principal ARN is not known at plan time. | `map(list(string))` | `{}` | no | +| [access\_entry\_map](#input\_access\_entry\_map) | Map of IAM Principal ARNs to access configuration.
Preferred over other inputs as this configuration remains stable
when elements are added or removed, but it requires that the Principal ARNs
and Policy ARNs are known at plan time.
Can be used along with other `access_*` inputs, but do not duplicate entries.
Map `access_policy_associations` keys are policy ARNs, policy
full name (AmazonEKSViewPolicy), or short name (View).
It is recommended to use the default `user_name` because the default includes
IAM role or user name and the session name for assumed roles.
As a special case in support of backwards compatibility, membership in the
`system:masters` group is is translated to an association with the ClusterAdmin policy.
In all other cases, including any `system:*` group in `kubernetes_groups` is prohibited. |
map(object({
# key is principal_arn
user_name = optional(string)
# Cannot assign "system:*" groups to IAM users, use ClusterAdmin and Admin instead
kubernetes_groups = optional(list(string), [])
type = optional(string, "STANDARD")
access_policy_associations = optional(map(object({
# key is policy_arn or policy_name
access_scope = optional(object({
type = optional(string, "cluster")
namespaces = optional(list(string))
}), {}) # access_scope
})), {}) # access_policy_associations
}))
| `{}` | no | +| [access\_policy\_associations](#input\_access\_policy\_associations) | List of AWS managed EKS access policies to associate with IAM principles.
Use when Principal ARN or Policy ARN is not known at plan time.
`policy_arn` can be the full ARN, the full name (AmazonEKSViewPolicy) or short name (View). |
list(object({
principal_arn = string
policy_arn = string
access_scope = object({
type = optional(string, "cluster")
namespaces = optional(list(string))
})
}))
| `[]` | no | | [additional\_tag\_map](#input\_additional\_tag\_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no | -| [addons](#input\_addons) | Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources |
list(object({
addon_name = string
addon_version = optional(string, null)
configuration_values = optional(string, null)
resolve_conflicts_on_create = optional(string, null)
resolve_conflicts_on_update = optional(string, null)
service_account_role_arn = optional(string, null)
create_timeout = optional(string, null)
update_timeout = optional(string, null)
delete_timeout = optional(string, null)
}))
| `[]` | no | +| [addons](#input\_addons) | Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources.
Note: `resolve_conflicts` is deprecated. If `resolve_conflicts` is set and
`resolve_conflicts_on_create` or `resolve_conflicts_on_update` is not set,
`resolve_conflicts` will be used instead. If `resolve_conflicts_on_create` is
not set and `resolve_conflicts` is `PRESERVE`, `resolve_conflicts_on_create`
will be set to `NONE`. |
list(object({
addon_name = string
addon_version = optional(string, null)
configuration_values = optional(string, null)
# resolve_conflicts is deprecated, but we keep it for backwards compatibility
# and because if not declared, Terraform will silently ignore it.
resolve_conflicts = optional(string, null)
resolve_conflicts_on_create = optional(string, null)
resolve_conflicts_on_update = optional(string, null)
service_account_role_arn = optional(string, null)
create_timeout = optional(string, null)
update_timeout = optional(string, null)
delete_timeout = optional(string, null)
}))
| `[]` | no | | [addons\_depends\_on](#input\_addons\_depends\_on) | If provided, all addons will depend on this object, and therefore not be installed until this object is finalized.
This is useful if you want to ensure that addons are not applied before some other condition is met, e.g. node groups are created.
See [issue #170](https://github.com/cloudposse/terraform-aws-eks-cluster/issues/170) for more details. | `any` | `null` | no | | [allowed\_cidr\_blocks](#input\_allowed\_cidr\_blocks) | A list of IPv4 CIDRs to allow access to the cluster.
The length of this list must be known at "plan" time. | `list(string)` | `[]` | no | | [allowed\_security\_group\_ids](#input\_allowed\_security\_group\_ids) | A list of IDs of Security Groups to allow access to the cluster. | `list(string)` | `[]` | no | -| [allowed\_security\_groups](#input\_allowed\_security\_groups) | DEPRECATED: Use `allowed_security_group_ids` instead.
Historical description: List of Security Group IDs to be allowed to connect to the EKS cluster.
Historical default: `[]` | `list(string)` | `[]` | no | -| [apply\_config\_map\_aws\_auth](#input\_apply\_config\_map\_aws\_auth) | Whether to apply the ConfigMap to allow worker nodes to join the EKS cluster and allow additional users, accounts and roles to acces the cluster | `bool` | `true` | no | | [associated\_security\_group\_ids](#input\_associated\_security\_group\_ids) | A list of IDs of Security Groups to associate the cluster with.
These security groups will not be modified. | `list(string)` | `[]` | no | | [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no | -| [aws\_auth\_yaml\_strip\_quotes](#input\_aws\_auth\_yaml\_strip\_quotes) | If true, remove double quotes from the generated aws-auth ConfigMap YAML to reduce spurious diffs in plans | `bool` | `true` | no | | [cloudwatch\_log\_group\_kms\_key\_id](#input\_cloudwatch\_log\_group\_kms\_key\_id) | If provided, the KMS Key ID to use to encrypt AWS CloudWatch logs | `string` | `null` | no | | [cluster\_attributes](#input\_cluster\_attributes) | Override label module default cluster attributes | `list(string)` |
[
"cluster"
]
| no | | [cluster\_depends\_on](#input\_cluster\_depends\_on) | If provided, the EKS will depend on this object, and therefore not be created until this object is finalized.
This is useful if you want to ensure that the cluster is not created before some other condition is met, e.g. VPNs into the subnet are created. | `any` | `null` | no | @@ -83,11 +78,9 @@ | [cluster\_log\_retention\_period](#input\_cluster\_log\_retention\_period) | 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. | `number` | `0` | no | | [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` |
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no | | [create\_eks\_service\_role](#input\_create\_eks\_service\_role) | Set `false` to use existing `eks_cluster_service_role_arn` instead of creating one | `bool` | `true` | no | -| [create\_security\_group](#input\_create\_security\_group) | Set to `true` to create and configure an additional Security Group for the cluster.
Only for backwards compatibility, if you are updating this module to the latest version on existing clusters, not recommended for new clusters.
EKS creates a managed Security Group for the cluster automatically, places the control plane and managed nodes into the Security Group,
and you can also allow unmanaged nodes to communicate with the cluster by using the `allowed_security_group_ids` variable.
The additional Security Group is kept in the module for backwards compatibility and will be removed in future releases along with this variable.
See https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html for more details. | `bool` | `false` | no | | [custom\_ingress\_rules](#input\_custom\_ingress\_rules) | A List of Objects, which are custom security group rules that |
list(object({
description = string
from_port = number
to_port = number
protocol = string
source_security_group_id = string
}))
| `[]` | no | | [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | [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 | -| [dummy\_kubeapi\_server](#input\_dummy\_kubeapi\_server) | URL of a dummy API server for the Kubernetes server to use when the real one is unknown.
This is a workaround to ignore connection failures that break Terraform even though the results do not matter.
You can disable it by setting it to `null`; however, as of Kubernetes provider v2.3.2, doing so \_will\_
cause Terraform to fail in several situations unless you provide a valid `kubeconfig` file
via `kubeconfig_path` and set `kubeconfig_path_enabled` to `true`. | `string` | `"https://jsonplaceholder.typicode.com"` | no | | [eks\_cluster\_service\_role\_arn](#input\_eks\_cluster\_service\_role\_arn) | The ARN of an IAM role for the EKS cluster to use that provides permissions
for the Kubernetes control plane to perform needed AWS API operations.
Required if `create_eks_service_role` is `false`, ignored otherwise. | `string` | `null` | no | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [enabled\_cluster\_log\_types](#input\_enabled\_cluster\_log\_types) | 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`] | `list(string)` | `[]` | no | @@ -95,27 +88,13 @@ | [endpoint\_public\_access](#input\_endpoint\_public\_access) | Indicates whether or not the Amazon EKS public API server endpoint is enabled. Default to AWS EKS resource and it is true | `bool` | `true` | 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 | | [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 | -| [kube\_data\_auth\_enabled](#input\_kube\_data\_auth\_enabled) | If `true`, use an `aws_eks_cluster_auth` data source to authenticate to the EKS cluster.
Disabled by `kubeconfig_path_enabled` or `kube_exec_auth_enabled`. | `bool` | `true` | no | -| [kube\_exec\_auth\_aws\_profile](#input\_kube\_exec\_auth\_aws\_profile) | The AWS config profile for `aws eks get-token` to use | `string` | `""` | no | -| [kube\_exec\_auth\_aws\_profile\_enabled](#input\_kube\_exec\_auth\_aws\_profile\_enabled) | If `true`, pass `kube_exec_auth_aws_profile` as the `profile` to `aws eks get-token` | `bool` | `false` | no | -| [kube\_exec\_auth\_enabled](#input\_kube\_exec\_auth\_enabled) | If `true`, use the Kubernetes provider `exec` feature to execute `aws eks get-token` to authenticate to the EKS cluster.
Disabled by `kubeconfig_path_enabled`, overrides `kube_data_auth_enabled`. | `bool` | `false` | no | -| [kube\_exec\_auth\_role\_arn](#input\_kube\_exec\_auth\_role\_arn) | The role ARN for `aws eks get-token` to use | `string` | `""` | no | -| [kube\_exec\_auth\_role\_arn\_enabled](#input\_kube\_exec\_auth\_role\_arn\_enabled) | If `true`, pass `kube_exec_auth_role_arn` as the role ARN to `aws eks get-token` | `bool` | `false` | no | -| [kubeconfig\_context](#input\_kubeconfig\_context) | Context to choose from the Kubernetes kube config file | `string` | `""` | no | -| [kubeconfig\_path](#input\_kubeconfig\_path) | The Kubernetes provider `config_path` setting to use when `kubeconfig_path_enabled` is `true` | `string` | `""` | no | -| [kubeconfig\_path\_enabled](#input\_kubeconfig\_path\_enabled) | If `true`, configure the Kubernetes provider with `kubeconfig_path` and use it for authenticating to the EKS cluster | `bool` | `false` | no | -| [kubernetes\_config\_map\_ignore\_role\_changes](#input\_kubernetes\_config\_map\_ignore\_role\_changes) | Set to `true` to ignore IAM role changes in the Kubernetes Auth ConfigMap | `bool` | `true` | no | | [kubernetes\_network\_ipv6\_enabled](#input\_kubernetes\_network\_ipv6\_enabled) | Set true to use IPv6 addresses for Kubernetes pods and services | `bool` | `false` | no | | [kubernetes\_version](#input\_kubernetes\_version) | Desired Kubernetes master version. If you do not specify a value, the latest available version is used | `string` | `"1.21"` | no | | [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | | [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no | | [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no | | [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 | -| [local\_exec\_interpreter](#input\_local\_exec\_interpreter) | shell to use for local\_exec | `list(string)` |
[
"/bin/sh",
"-c"
]
| no | | [managed\_security\_group\_rules\_enabled](#input\_managed\_security\_group\_rules\_enabled) | Flag to enable/disable the ingress and egress rules for the EKS managed Security Group | `bool` | `true` | no | -| [map\_additional\_aws\_accounts](#input\_map\_additional\_aws\_accounts) | Additional AWS account numbers to add to `config-map-aws-auth` ConfigMap | `list(string)` | `[]` | no | -| [map\_additional\_iam\_roles](#input\_map\_additional\_iam\_roles) | Additional IAM roles to add to `config-map-aws-auth` ConfigMap |
list(object({
rolearn = string
username = string
groups = list(string)
}))
| `[]` | no | -| [map\_additional\_iam\_users](#input\_map\_additional\_iam\_users) | Additional IAM users to add to `config-map-aws-auth` ConfigMap |
list(object({
userarn = string
username = string
groups = list(string)
}))
| `[]` | 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 | | [oidc\_provider\_enabled](#input\_oidc\_provider\_enabled) | 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 [EKS User Guide](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html). | `bool` | `false` | no | @@ -128,10 +107,6 @@ | [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch the cluster in | `list(string)` | n/a | yes | | [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no | | [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no | -| [vpc\_id](#input\_vpc\_id) | VPC ID for the EKS cluster | `string` | n/a | yes | -| [wait\_for\_cluster\_command](#input\_wait\_for\_cluster\_command) | `local-exec` command to execute to determine if the EKS cluster is healthy. Cluster endpoint URL is available as environment variable `ENDPOINT` | `string` | `"if test -n \"$ENDPOINT\"; then curl --silent --fail --retry 30 --retry-delay 10 --retry-connrefused --max-time 11 --insecure --output /dev/null $ENDPOINT/healthz; fi"` | no | -| [workers\_role\_arns](#input\_workers\_role\_arns) | List of Role ARNs of the worker nodes | `list(string)` | `[]` | no | -| [workers\_security\_group\_ids](#input\_workers\_security\_group\_ids) | DEPRECATED: Use `allowed_security_group_ids` instead.
Historical description: Security Group IDs of the worker nodes.
Historical default: `[]` | `list(string)` | `[]` | no | ## Outputs @@ -149,11 +124,8 @@ | [eks\_cluster\_id](#output\_eks\_cluster\_id) | The name of the cluster | | [eks\_cluster\_identity\_oidc\_issuer](#output\_eks\_cluster\_identity\_oidc\_issuer) | The OIDC Identity issuer for the cluster | | [eks\_cluster\_identity\_oidc\_issuer\_arn](#output\_eks\_cluster\_identity\_oidc\_issuer\_arn) | The OIDC Identity issuer ARN for the cluster that can be used to associate IAM roles with a service account | +| [eks\_cluster\_ipv6\_service\_cidr](#output\_eks\_cluster\_ipv6\_service\_cidr) | The IPv6 CIDR block that Kubernetes pod and service IP addresses are assigned from
if `kubernetes_network_ipv6_enabled` is set to true. If set to false this output will be null. | | [eks\_cluster\_managed\_security\_group\_id](#output\_eks\_cluster\_managed\_security\_group\_id) | Security Group ID that was created by EKS for the cluster.
EKS creates a Security Group and applies it to the ENI that are attached to EKS Control Plane master nodes and to any managed workloads. | | [eks\_cluster\_role\_arn](#output\_eks\_cluster\_role\_arn) | ARN of the EKS cluster IAM role | | [eks\_cluster\_version](#output\_eks\_cluster\_version) | The Kubernetes server version of the cluster | -| [kubernetes\_config\_map\_id](#output\_kubernetes\_config\_map\_id) | ID of `aws-auth` Kubernetes ConfigMap | -| [security\_group\_arn](#output\_security\_group\_arn) | (Deprecated) ARN of the optionally created additional Security Group for the EKS cluster | -| [security\_group\_id](#output\_security\_group\_id) | (Deprecated) ID of the optionally created additional Security Group for the EKS cluster | -| [security\_group\_name](#output\_security\_group\_name) | Name of the optionally created additional Security Group for the EKS cluster | diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars index 7f893339..66d93e65 100644 --- a/examples/complete/fixtures.us-east-2.tfvars +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -28,31 +28,24 @@ kubernetes_labels = {} cluster_encryption_config_enabled = true # When updating the Kubernetes version, also update the API and client-go version in test/src/go.mod -kubernetes_version = "1.26" +kubernetes_version = "1.29" + +private_ipv6_enabled = false addons = [ - // https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html#vpc-cni-latest-available-version - { - addon_name = "vpc-cni" - addon_version = null - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" - service_account_role_arn = null - }, - // https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html + # https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html { addon_name = "kube-proxy" addon_version = null - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "PRESERVE" service_account_role_arn = null }, - // https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html + # https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html { - addon_name = "coredns" - addon_version = null - resolve_conflicts_on_create = "NONE" - resolve_conflicts_on_update = "NONE" - service_account_role_arn = null + addon_name = "coredns" + addon_version = null + resolve_conflicts = "NONE" + service_account_role_arn = null }, ] diff --git a/examples/complete/main.tf b/examples/complete/main.tf index c1e977b5..6cdc05ed 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -11,7 +11,17 @@ module "label" { context = module.this.context } +data "aws_caller_identity" "current" {} + +data "aws_iam_session_context" "current" { + arn = data.aws_caller_identity.current.arn +} + locals { + enabled = module.this.enabled + + private_ipv6_enabled = var.private_ipv6_enabled + # The usage of the specific kubernetes.io/cluster/* resource tags below are required # for EKS and Kubernetes to discover and manage networking resources # https://aws.amazon.com/premiumsupport/knowledge-center/eks-vpc-subnet-discovery/ @@ -25,11 +35,37 @@ locals { private_subnets_additional_tags = { "kubernetes.io/role/internal-elb" : 1 } + + # Enable the IAM user creating the cluster to administer it, + # without using the bootstrap_cluster_creator_admin_permissions option, + # as a way to test the access_entry_map feature. + # In general, this is not recommended. Instead, you should + # create the access_entry_map statically, with the ARNs you want to + # have access to the cluster. We do it dynamically here just for testing purposes. + access_entry_map = { + (data.aws_iam_session_context.current.issuer_arn) = { + access_policy_associations = { + ClusterAdmin = {} + } + } + } + + # https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html#vpc-cni-latest-available-version + vpc_cni_addon = { + addon_name = "vpc-cni" + addon_version = null + resolve_conflicts = "OVERWRITE" + service_account_role_arn = one(module.vpc_cni_eks_iam_role[*].service_account_role_arn) + } + + addons = concat([ + local.vpc_cni_addon + ], var.addons) } module "vpc" { source = "cloudposse/vpc/aws" - version = "2.1.0" + version = "2.1.1" ipv4_primary_cidr_block = "172.16.0.0/16" tags = local.tags @@ -39,17 +75,20 @@ module "vpc" { module "subnets" { source = "cloudposse/dynamic-subnets/aws" - version = "2.3.0" + version = "2.4.1" availability_zones = var.availability_zones vpc_id = module.vpc.vpc_id igw_id = [module.vpc.igw_id] ipv4_cidr_block = [module.vpc.vpc_cidr_block] + ipv6_cidr_block = [module.vpc.vpc_ipv6_cidr_block] + ipv6_enabled = true max_nats = 1 nat_gateway_enabled = true nat_instance_enabled = false tags = local.tags public_subnets_additional_tags = local.public_subnets_additional_tags + private_subnets_enabled = true private_subnets_additional_tags = local.private_subnets_additional_tags context = module.this.context @@ -58,10 +97,8 @@ module "subnets" { module "eks_cluster" { source = "../../" - vpc_id = module.vpc.vpc_id subnet_ids = concat(module.subnets.private_subnet_ids, module.subnets.public_subnet_ids) kubernetes_version = var.kubernetes_version - local_exec_interpreter = var.local_exec_interpreter oidc_provider_enabled = var.oidc_provider_enabled enabled_cluster_log_types = var.enabled_cluster_log_types cluster_log_retention_period = var.cluster_log_retention_period @@ -73,27 +110,21 @@ module "eks_cluster" { cluster_encryption_config_kms_key_policy = var.cluster_encryption_config_kms_key_policy cluster_encryption_config_resources = var.cluster_encryption_config_resources - addons = var.addons + addons = local.addons addons_depends_on = [module.eks_node_group] - # We need to create a new Security Group only if the EKS cluster is used with unmanaged worker nodes. - # EKS creates a managed Security Group for the cluster automatically, places the control plane and managed nodes into the security group, - # and allows all communications between the control plane and the managed worker nodes - # (EKS applies it to ENIs that are attached to EKS Control Plane master nodes and to any managed workloads). - # If only Managed Node Groups are used, we don't need to create a separate Security Group; - # otherwise we place the cluster in two SGs - one that is created by EKS, the other one that the module creates. - # See https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html for more details. - create_security_group = false + access_entry_map = local.access_entry_map + access_config = { + authentication_mode = "API" + bootstrap_cluster_creator_admin_permissions = false + } # This is to test `allowed_security_group_ids` and `allowed_cidr_blocks` # In a real cluster, these should be some other (existing) Security Groups and CIDR blocks to allow access to the cluster allowed_security_group_ids = [module.vpc.vpc_default_security_group_id] allowed_cidr_blocks = [module.vpc.vpc_cidr_block] - # For manual testing. In particular, set `false` if local configuration/state - # has a cluster but the cluster was deleted by nightly cleanup, in order for - # `terraform destroy` to succeed. - apply_config_map_aws_auth = var.apply_config_map_aws_auth + kubernetes_network_ipv6_enabled = local.private_ipv6_enabled context = module.this.context @@ -102,7 +133,7 @@ module "eks_cluster" { module "eks_node_group" { source = "cloudposse/eks-node-group/aws" - version = "2.4.0" + version = "2.12.0" subnet_ids = module.subnets.private_subnet_ids cluster_name = module.eks_cluster.eks_cluster_id @@ -112,8 +143,5 @@ module "eks_node_group" { max_size = var.max_size kubernetes_labels = var.kubernetes_labels - # Prevent the node groups from being created before the Kubernetes aws-auth ConfigMap - module_depends_on = module.eks_cluster.kubernetes_config_map_id - context = module.this.context } diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 4ba62161..aeb6572e 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -43,6 +43,14 @@ output "eks_cluster_managed_security_group_id" { value = module.eks_cluster.eks_cluster_managed_security_group_id } +output "eks_cluster_ipv6_service_cidr" { + description = <<-EOT + The IPv6 CIDR block that Kubernetes pod and service IP addresses are assigned from + if `kubernetes_network_ipv6_enabled` is set to true. If set to false this output will be null. + EOT + value = module.eks_cluster.eks_cluster_ipv6_service_cidr +} + output "eks_node_group_role_arn" { description = "ARN of the worker nodes IAM role" value = module.eks_node_group.eks_node_group_role_arn diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 9132b724..c1b338b8 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -10,7 +10,7 @@ variable "availability_zones" { variable "kubernetes_version" { type = string - default = "1.21" + default = "1.29" description = "Desired Kubernetes master version. If you do not specify a value, the latest available version is used" } @@ -26,48 +26,12 @@ variable "cluster_log_retention_period" { 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 "map_additional_aws_accounts" { - description = "Additional AWS account numbers to add to `config-map-aws-auth` ConfigMap" - type = list(string) - default = [] -} - -variable "map_additional_iam_roles" { - description = "Additional IAM roles to add to `config-map-aws-auth` ConfigMap" - - type = list(object({ - rolearn = string - username = string - groups = list(string) - })) - - default = [] -} - -variable "map_additional_iam_users" { - description = "Additional IAM users to add to `config-map-aws-auth` ConfigMap" - - type = list(object({ - userarn = string - username = string - groups = list(string) - })) - - default = [] -} - variable "oidc_provider_enabled" { type = bool default = true 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" } -variable "local_exec_interpreter" { - type = list(string) - default = ["/bin/sh", "-c"] - description = "shell to use for local_exec" -} - variable "instance_types" { type = list(string) description = "Set of instance types associated with the EKS Node Group. Defaults to [\"t3.medium\"]. Terraform will only perform drift detection if a configuration value is provided" @@ -132,18 +96,21 @@ variable "cluster_encryption_config_resources" { variable "addons" { type = list(object({ - addon_name = string - addon_version = string - resolve_conflicts_on_create = string - resolve_conflicts_on_update = string + addon_name = string + addon_version = string + # resolve_conflicts is deprecated, but we keep it for backwards compatibility + # and because if not declared, Terraform will silently ignore it. + resolve_conflicts = optional(string, null) + resolve_conflicts_on_create = optional(string, null) + resolve_conflicts_on_update = optional(string, null) service_account_role_arn = string })) default = [] description = "Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources." } -variable "apply_config_map_aws_auth" { +variable "private_ipv6_enabled" { type = bool - default = true - description = "Whether to apply the ConfigMap to allow worker nodes to join the EKS cluster and allow additional users, accounts and roles to acces the cluster" + default = false + description = "Whether to use IPv6 addresses for the pods in the node group" } diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index 61b9ab7b..99d0a4a2 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 3.38" + version = ">= 5.34" } kubernetes = { source = "hashicorp/kubernetes" diff --git a/examples/complete/vpc-cni.tf b/examples/complete/vpc-cni.tf new file mode 100644 index 00000000..ef67b5e0 --- /dev/null +++ b/examples/complete/vpc-cni.tf @@ -0,0 +1,62 @@ +# `vpc-cni` EKS addon +# https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html +# https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html +# https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html#cni-iam-role-create-role +# https://aws.github.io/aws-eks-best-practices/networking/vpc-cni/#deploy-vpc-cni-managed-add-on + +locals { + vpc_cni_sa_needed = local.enabled +} + +# It is important to enable IPv6 support for the VPC CNI plugin +# even if IPv6 is not in use, because the addon may need to +# manage IPv6 addresses during a transition from IPv6 to IPv4 +# or vice versa, or while destroying the cluster. +data "aws_iam_policy_document" "vpc_cni_ipv6" { + count = local.vpc_cni_sa_needed ? 1 : 0 + + # See https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html#cni-iam-role-create-ipv6-policy + statement { + sid = "" + effect = "Allow" + resources = ["*"] + + actions = [ + "ec2:AssignIpv6Addresses", + "ec2:DescribeInstances", + "ec2:DescribeTags", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeInstanceTypes" + ] + } + + statement { + sid = "" + effect = "Allow" + resources = ["arn:aws:ec2:*:*:network-interface/*"] + actions = ["ec2:CreateTags"] + } +} + +resource "aws_iam_role_policy_attachment" "vpc_cni" { + count = local.vpc_cni_sa_needed ? 1 : 0 + + role = module.vpc_cni_eks_iam_role.service_account_role_name + policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" +} + +module "vpc_cni_eks_iam_role" { + source = "cloudposse/eks-iam-role/aws" + version = "2.1.1" + + enabled = local.vpc_cni_sa_needed + + eks_cluster_oidc_issuer_url = module.eks_cluster.eks_cluster_identity_oidc_issuer + + service_account_name = "aws-node" + service_account_namespace = "kube-system" + + aws_iam_policy_document = try([data.aws_iam_policy_document.vpc_cni_ipv6[0].json], []) + + context = module.this.context +} diff --git a/examples/obsolete-version2/context.tf b/examples/obsolete-version2/context.tf new file mode 100644 index 00000000..5e0ef885 --- /dev/null +++ b/examples/obsolete-version2/context.tf @@ -0,0 +1,279 @@ +# +# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label +# All other instances of this file should be a copy of that one +# +# +# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf +# and then place it in your Terraform module to automatically get +# Cloud Posse's standard configuration inputs suitable for passing +# to Cloud Posse modules. +# +# curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf +# +# Modules should access the whole context as `module.this.context` +# to get the input variables with nulls for defaults, +# for example `context = module.this.context`, +# and access individual variables as `module.this.`, +# with final values filled in. +# +# For example, when using defaults, `module.this.context.delimiter` +# will be null, and `module.this.delimiter` will be `-` (hyphen). +# + +module "this" { + source = "cloudposse/label/null" + version = "0.25.0" # requires Terraform >= 0.13.0 + + enabled = var.enabled + namespace = var.namespace + tenant = var.tenant + environment = var.environment + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + tags = var.tags + additional_tag_map = var.additional_tag_map + label_order = var.label_order + regex_replace_chars = var.regex_replace_chars + id_length_limit = var.id_length_limit + label_key_case = var.label_key_case + label_value_case = var.label_value_case + descriptor_formats = var.descriptor_formats + labels_as_tags = var.labels_as_tags + + context = var.context +} + +# Copy contents of cloudposse/terraform-null-label/variables.tf here + +variable "context" { + type = any + default = { + enabled = true + namespace = null + tenant = null + environment = null + stage = null + name = null + delimiter = null + attributes = [] + tags = {} + additional_tag_map = {} + regex_replace_chars = null + label_order = [] + id_length_limit = null + label_key_case = null + label_value_case = null + descriptor_formats = {} + # Note: we have to use [] instead of null for unset lists due to + # https://github.com/hashicorp/terraform/issues/28137 + # which was not fixed until Terraform 1.0.0, + # but we want the default to be all the labels in `label_order` + # and we want users to be able to prevent all tag generation + # by setting `labels_as_tags` to `[]`, so we need + # a different sentinel to indicate "default" + labels_as_tags = ["unset"] + } + description = <<-EOT + Single object for setting entire context at once. + See description of individual variables for details. + Leave string and numeric variables as `null` to use default value. + Individual variable settings (non-null) override settings in context object, + except for attributes, tags, and additional_tag_map, which are merged. + EOT + + validation { + condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"]) + error_message = "Allowed values: `lower`, `title`, `upper`." + } + + validation { + condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"]) + error_message = "Allowed values: `lower`, `title`, `upper`, `none`." + } +} + +variable "enabled" { + type = bool + default = null + description = "Set to false to prevent the module from creating any resources" +} + +variable "namespace" { + type = string + default = null + description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique" +} + +variable "tenant" { + type = string + default = null + description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for" +} + +variable "environment" { + type = string + default = null + description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'" +} + +variable "stage" { + type = string + default = null + description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'" +} + +variable "name" { + type = string + default = null + description = <<-EOT + 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. + EOT +} + +variable "delimiter" { + type = string + default = null + description = <<-EOT + Delimiter to be used between ID elements. + Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. + EOT +} + +variable "attributes" { + type = list(string) + default = [] + description = <<-EOT + ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`, + in the order they appear in the list. New attributes are appended to the + end of the list. The elements of the list are joined by the `delimiter` + and treated as a single ID element. + EOT +} + +variable "labels_as_tags" { + type = set(string) + default = ["default"] + description = <<-EOT + 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. + EOT +} + +variable "tags" { + type = map(string) + default = {} + description = <<-EOT + Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`). + Neither the tag keys nor the tag values will be modified by this module. + EOT +} + +variable "additional_tag_map" { + type = map(string) + default = {} + description = <<-EOT + Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`. + This is for some rare cases where resources want additional configuration of tags + and therefore take a list of maps with tag key, value, and additional configuration. + EOT +} + +variable "label_order" { + type = list(string) + default = null + description = <<-EOT + The order in which the labels (ID elements) appear in the `id`. + Defaults to ["namespace", "environment", "stage", "name", "attributes"]. + You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. + EOT +} + +variable "regex_replace_chars" { + type = string + default = null + description = <<-EOT + 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. + EOT +} + +variable "id_length_limit" { + type = number + default = null + description = <<-EOT + 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`. + EOT + validation { + condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0 + error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length." + } +} + +variable "label_key_case" { + type = string + default = null + description = <<-EOT + Controls the letter case of the `tags` keys (label names) for tags generated by this module. + Does not affect keys of tags passed in via the `tags` input. + Possible values: `lower`, `title`, `upper`. + Default value: `title`. + EOT + + validation { + condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case) + error_message = "Allowed values: `lower`, `title`, `upper`." + } +} + +variable "label_value_case" { + type = string + default = null + description = <<-EOT + Controls the letter case of ID elements (labels) as included in `id`, + set as tag values, and output by this module individually. + Does not affect values of tags passed in via the `tags` input. + Possible values: `lower`, `title`, `upper` and `none` (no transformation). + Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs. + Default value: `lower`. + EOT + + validation { + condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case) + error_message = "Allowed values: `lower`, `title`, `upper`, `none`." + } +} + +variable "descriptor_formats" { + type = any + default = {} + description = <<-EOT + 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). + EOT +} + +#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/examples/obsolete-version2/fixtures.us-east-2.tfvars b/examples/obsolete-version2/fixtures.us-east-2.tfvars new file mode 100644 index 00000000..d72d4ab5 --- /dev/null +++ b/examples/obsolete-version2/fixtures.us-east-2.tfvars @@ -0,0 +1,55 @@ +region = "us-east-2" + +availability_zones = ["us-east-2a", "us-east-2b"] + +namespace = "eg" + +stage = "test" + +name = "eks" + +# oidc_provider_enabled is required to be true for VPC CNI addon +oidc_provider_enabled = true + +enabled_cluster_log_types = ["audit"] + +cluster_log_retention_period = 7 + +instance_types = ["t3.small"] + +desired_size = 2 + +max_size = 3 + +min_size = 2 + +kubernetes_labels = {} + +cluster_encryption_config_enabled = true + +# When updating the Kubernetes version, also update the API and client-go version in test/src/go.mod +kubernetes_version = "1.26" + +addons = [ + // https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html#vpc-cni-latest-available-version + { + addon_name = "vpc-cni" + addon_version = null + resolve_conflicts = "OVERWRITE" + service_account_role_arn = null + }, + // https://docs.aws.amazon.com/eks/latest/userguide/managing-kube-proxy.html + { + addon_name = "kube-proxy" + addon_version = null + resolve_conflicts = "OVERWRITE" + service_account_role_arn = null + }, + // https://docs.aws.amazon.com/eks/latest/userguide/managing-coredns.html + { + addon_name = "coredns" + addon_version = null + resolve_conflicts = "OVERWRITE" + service_account_role_arn = null + }, +] diff --git a/examples/obsolete-version2/main.tf b/examples/obsolete-version2/main.tf new file mode 100644 index 00000000..f3f3e306 --- /dev/null +++ b/examples/obsolete-version2/main.tf @@ -0,0 +1,127 @@ + +################################################################## +## This example shows how to use version 2.9.0 of this module. ## +## It is provided for reference only. ## +## Use version 4.0.0 or later for new deployments. ## +################################################################## + +provider "aws" { + region = var.region +} + +module "label" { + source = "cloudposse/label/null" + version = "0.25.0" + + attributes = ["cluster"] + + context = module.this.context +} + +locals { + # The usage of the specific kubernetes.io/cluster/* resource tags below are required + # for EKS and Kubernetes to discover and manage networking resources + # https://aws.amazon.com/premiumsupport/knowledge-center/eks-vpc-subnet-discovery/ + # https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/deploy/subnet_discovery.md + tags = { "kubernetes.io/cluster/${module.label.id}" = "shared" } + + # required tags to make ALB ingress work https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html + public_subnets_additional_tags = { + "kubernetes.io/role/elb" : 1 + } + private_subnets_additional_tags = { + "kubernetes.io/role/internal-elb" : 1 + } +} + +module "vpc" { + source = "cloudposse/vpc/aws" + version = "2.1.0" + + ipv4_primary_cidr_block = "172.16.0.0/16" + tags = local.tags + + context = module.this.context +} + +module "subnets" { + source = "cloudposse/dynamic-subnets/aws" + version = "2.3.0" + + availability_zones = var.availability_zones + vpc_id = module.vpc.vpc_id + igw_id = [module.vpc.igw_id] + ipv4_cidr_block = [module.vpc.vpc_cidr_block] + max_nats = 1 + nat_gateway_enabled = true + nat_instance_enabled = false + tags = local.tags + public_subnets_additional_tags = local.public_subnets_additional_tags + private_subnets_additional_tags = local.private_subnets_additional_tags + + context = module.this.context +} + +module "eks_cluster" { + source = "cloudposse/eks-cluster/aws" + version = "2.9.0" + + vpc_id = module.vpc.vpc_id + subnet_ids = concat(module.subnets.private_subnet_ids, module.subnets.public_subnet_ids) + kubernetes_version = var.kubernetes_version + local_exec_interpreter = var.local_exec_interpreter + oidc_provider_enabled = var.oidc_provider_enabled + enabled_cluster_log_types = var.enabled_cluster_log_types + cluster_log_retention_period = var.cluster_log_retention_period + + cluster_encryption_config_enabled = var.cluster_encryption_config_enabled + cluster_encryption_config_kms_key_id = var.cluster_encryption_config_kms_key_id + cluster_encryption_config_kms_key_enable_key_rotation = var.cluster_encryption_config_kms_key_enable_key_rotation + cluster_encryption_config_kms_key_deletion_window_in_days = var.cluster_encryption_config_kms_key_deletion_window_in_days + cluster_encryption_config_kms_key_policy = var.cluster_encryption_config_kms_key_policy + cluster_encryption_config_resources = var.cluster_encryption_config_resources + + addons = var.addons + addons_depends_on = [module.eks_node_group] + + # We need to create a new Security Group only if the EKS cluster is used with unmanaged worker nodes. + # EKS creates a managed Security Group for the cluster automatically, places the control plane and managed nodes into the security group, + # and allows all communications between the control plane and the managed worker nodes + # (EKS applies it to ENIs that are attached to EKS Control Plane master nodes and to any managed workloads). + # If only Managed Node Groups are used, we don't need to create a separate Security Group; + # otherwise we place the cluster in two SGs - one that is created by EKS, the other one that the module creates. + # See https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html for more details. + create_security_group = false + + # This is to test `allowed_security_group_ids` and `allowed_cidr_blocks` + # In a real cluster, these should be some other (existing) Security Groups and CIDR blocks to allow access to the cluster + allowed_security_group_ids = [module.vpc.vpc_default_security_group_id] + allowed_cidr_blocks = [module.vpc.vpc_cidr_block] + + # For manual testing. In particular, set `false` if local configuration/state + # has a cluster but the cluster was deleted by nightly cleanup, in order for + # `terraform destroy` to succeed. + apply_config_map_aws_auth = var.apply_config_map_aws_auth + + context = module.this.context + + cluster_depends_on = [module.subnets] +} + +module "eks_node_group" { + source = "cloudposse/eks-node-group/aws" + version = "2.4.0" + + subnet_ids = module.subnets.private_subnet_ids + cluster_name = module.eks_cluster.eks_cluster_id + instance_types = var.instance_types + desired_size = var.desired_size + min_size = var.min_size + max_size = var.max_size + kubernetes_labels = var.kubernetes_labels + + # Prevent the node groups from being created before the Kubernetes aws-auth ConfigMap + module_depends_on = module.eks_cluster.kubernetes_config_map_id + + context = module.this.context +} diff --git a/examples/obsolete-version2/outputs.tf b/examples/obsolete-version2/outputs.tf new file mode 100644 index 00000000..4ba62161 --- /dev/null +++ b/examples/obsolete-version2/outputs.tf @@ -0,0 +1,74 @@ +output "public_subnet_cidrs" { + value = module.subnets.public_subnet_cidrs + description = "Public subnet CIDRs" +} + +output "private_subnet_cidrs" { + value = module.subnets.private_subnet_cidrs + description = "Private subnet CIDRs" +} + +output "vpc_cidr" { + value = module.vpc.vpc_cidr_block + description = "VPC ID" +} + +output "eks_cluster_id" { + description = "The name of the cluster" + value = module.eks_cluster.eks_cluster_id +} + +output "eks_cluster_arn" { + description = "The Amazon Resource Name (ARN) of the cluster" + value = module.eks_cluster.eks_cluster_arn +} + +output "eks_cluster_endpoint" { + description = "The endpoint for the Kubernetes API server" + value = module.eks_cluster.eks_cluster_endpoint +} + +output "eks_cluster_version" { + description = "The Kubernetes server version of the cluster" + value = module.eks_cluster.eks_cluster_version +} + +output "eks_cluster_identity_oidc_issuer" { + description = "The OIDC Identity issuer for the cluster" + value = module.eks_cluster.eks_cluster_identity_oidc_issuer +} + +output "eks_cluster_managed_security_group_id" { + description = "Security Group ID that was created by EKS for the cluster. EKS creates a Security Group and applies it to ENI that is attached to EKS Control Plane master nodes and to any managed workloads" + value = module.eks_cluster.eks_cluster_managed_security_group_id +} + +output "eks_node_group_role_arn" { + description = "ARN of the worker nodes IAM role" + value = module.eks_node_group.eks_node_group_role_arn +} + +output "eks_node_group_role_name" { + description = "Name of the worker nodes IAM role" + value = module.eks_node_group.eks_node_group_role_name +} + +output "eks_node_group_id" { + description = "EKS Cluster name and EKS Node Group name separated by a colon" + value = module.eks_node_group.eks_node_group_id +} + +output "eks_node_group_arn" { + description = "Amazon Resource Name (ARN) of the EKS Node Group" + value = module.eks_node_group.eks_node_group_arn +} + +output "eks_node_group_resources" { + description = "List of objects containing information about underlying resources of the EKS Node Group" + value = module.eks_node_group.eks_node_group_resources +} + +output "eks_node_group_status" { + description = "Status of the EKS Node Group" + value = module.eks_node_group.eks_node_group_status +} diff --git a/examples/obsolete-version2/variables.tf b/examples/obsolete-version2/variables.tf new file mode 100644 index 00000000..3670c904 --- /dev/null +++ b/examples/obsolete-version2/variables.tf @@ -0,0 +1,148 @@ +variable "region" { + type = string + description = "AWS Region" +} + +variable "availability_zones" { + type = list(string) + description = "List of availability zones" +} + +variable "kubernetes_version" { + type = string + default = "1.21" + description = "Desired Kubernetes master version. If you do not specify a value, the latest available version is used" +} + +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`]" +} + +variable "cluster_log_retention_period" { + type = number + 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 "map_additional_aws_accounts" { + description = "Additional AWS account numbers to add to `config-map-aws-auth` ConfigMap" + type = list(string) + default = [] +} + +variable "map_additional_iam_roles" { + description = "Additional IAM roles to add to `config-map-aws-auth` ConfigMap" + + type = list(object({ + rolearn = string + username = string + groups = list(string) + })) + + default = [] +} + +variable "map_additional_iam_users" { + description = "Additional IAM users to add to `config-map-aws-auth` ConfigMap" + + type = list(object({ + userarn = string + username = string + groups = list(string) + })) + + default = [] +} + +variable "oidc_provider_enabled" { + type = bool + default = true + 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" +} + +variable "local_exec_interpreter" { + type = list(string) + default = ["/bin/sh", "-c"] + description = "shell to use for local_exec" +} + +variable "instance_types" { + type = list(string) + description = "Set of instance types associated with the EKS Node Group. Defaults to [\"t3.medium\"]. Terraform will only perform drift detection if a configuration value is provided" +} + +variable "kubernetes_labels" { + type = map(string) + description = "Key-value mapping of Kubernetes labels. Only labels that are applied with the EKS API are managed by this argument. Other Kubernetes labels applied to the EKS Node Group will not be managed" + default = {} +} + +variable "desired_size" { + type = number + description = "Desired number of worker nodes" +} + +variable "max_size" { + type = number + description = "The maximum size of the AutoScaling Group" +} + +variable "min_size" { + type = number + description = "The minimum size of the AutoScaling Group" +} + +variable "cluster_encryption_config_enabled" { + type = bool + default = true + description = "Set to `true` to enable Cluster Encryption Configuration" +} + +variable "cluster_encryption_config_kms_key_id" { + type = string + default = "" + description = "KMS Key ID to use for cluster encryption config" +} + +variable "cluster_encryption_config_kms_key_enable_key_rotation" { + type = bool + default = true + description = "Cluster Encryption Config KMS Key Resource argument - enable kms key rotation" +} + +variable "cluster_encryption_config_kms_key_deletion_window_in_days" { + type = number + default = 10 + description = "Cluster Encryption Config KMS Key Resource argument - key deletion windows in days post destruction" +} + +variable "cluster_encryption_config_kms_key_policy" { + type = string + default = null + description = "Cluster Encryption Config KMS Key Resource argument - key policy" +} + +variable "cluster_encryption_config_resources" { + type = list(any) + default = ["secrets"] + description = "Cluster Encryption Config Resources to encrypt, e.g. ['secrets']" +} + +variable "addons" { + type = list(object({ + addon_name = string + addon_version = string + resolve_conflicts = string + service_account_role_arn = string + })) + default = [] + description = "Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources." +} + +variable "apply_config_map_aws_auth" { + type = bool + default = true + description = "Whether to apply the ConfigMap to allow worker nodes to join the EKS cluster and allow additional users, accounts and roles to acces the cluster" +} diff --git a/examples/obsolete-version2/versions.tf b/examples/obsolete-version2/versions.tf new file mode 100644 index 00000000..8eeb26dc --- /dev/null +++ b/examples/obsolete-version2/versions.tf @@ -0,0 +1,29 @@ +# Because this module is an historical example, not a living one, +# we are pinning provider versions to historical versions that +# are compatible with the module code. +# We ordinarily do not recommend pinning versions in this way. + +terraform { + required_version = ">= 1.3.0, < 1.6.0" + + required_providers { + aws = { + source = "hashicorp/aws" + # Version 5.0.0 introduced a lot of changes. + version = ">= 3.38, < 5.0.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + # Version 2.25.0 introduced a breaking change. + version = ">= 2.7.1, <= 2.24.0" + } + tls = { + source = "hashicorp/tls" + version = "> 3.1, < 5.0" + } + null = { + source = "hashicorp/null" + version = "> 2.0, < 4.0" + } + } +} diff --git a/main.tf b/main.tf index a29bb89f..e235efca 100644 --- a/main.tf +++ b/main.tf @@ -3,6 +3,8 @@ locals { use_ipv6 = var.kubernetes_network_ipv6_enabled + eks_cluster_id = one(aws_eks_cluster.default[*].id) + cluster_encryption_config = { resources = var.cluster_encryption_config_resources @@ -60,19 +62,31 @@ resource "aws_eks_cluster" "default" { version = var.kubernetes_version enabled_cluster_log_types = var.enabled_cluster_log_types + access_config { + authentication_mode = var.access_config.authentication_mode + bootstrap_cluster_creator_admin_permissions = var.access_config.bootstrap_cluster_creator_admin_permissions + } + + lifecycle { + # bootstrap_cluster_creator_admin_permissions is documented as only applying + # to the initial creation of the cluster, and being unreliable afterward, + # so we want to ignore it except at cluster creation time. + ignore_changes = [access_config[0].bootstrap_cluster_creator_admin_permissions] + } + dynamic "encryption_config" { #bridgecrew:skip=BC_AWS_KUBERNETES_3:Let user decide secrets encryption, mainly because changing this value requires completely destroying the cluster for_each = var.cluster_encryption_config_enabled ? [local.cluster_encryption_config] : [] content { - resources = lookup(encryption_config.value, "resources") + resources = encryption_config.value.resources provider { - key_arn = lookup(encryption_config.value, "provider_key_arn") + key_arn = encryption_config.value.provider_key_arn } } } vpc_config { - security_group_ids = var.create_security_group ? compact(concat(var.associated_security_group_ids, [one(aws_security_group.default[*].id)])) : var.associated_security_group_ids + security_group_ids = var.associated_security_group_ids subnet_ids = var.subnet_ids endpoint_private_access = var.endpoint_private_access #bridgecrew:skip=BC_AWS_KUBERNETES_2:Let user decide on public access @@ -100,11 +114,6 @@ resource "aws_eks_cluster" "default" { aws_iam_role_policy_attachment.amazon_eks_cluster_policy, aws_iam_role_policy_attachment.amazon_eks_service_policy, aws_kms_alias.cluster, - aws_security_group.default, - aws_security_group_rule.egress, - aws_security_group_rule.ingress_cidr_blocks, - aws_security_group_rule.ingress_security_groups, - aws_security_group_rule.ingress_workers, aws_cloudwatch_log_group.default, var.associated_security_group_ids, var.cluster_depends_on, @@ -146,8 +155,8 @@ resource "aws_eks_addon" "cluster" { addon_name = each.key addon_version = lookup(each.value, "addon_version", null) configuration_values = lookup(each.value, "configuration_values", null) - resolve_conflicts_on_create = lookup(each.value, "resolve_conflicts_on_create", null) - resolve_conflicts_on_update = lookup(each.value, "resolve_conflicts_on_update", null) + resolve_conflicts_on_create = lookup(each.value, "resolve_conflicts_on_create", try(replace(each.value.resolve_conflicts, "PRESERVE", "NONE"), null)) + resolve_conflicts_on_update = lookup(each.value, "resolve_conflicts_on_update", lookup(each.value, "resolve_conflicts", null)) service_account_role_arn = lookup(each.value, "service_account_role_arn", null) tags = module.label.tags diff --git a/outputs.tf b/outputs.tf index ed56bf34..c1fb017a 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,18 +1,3 @@ -output "security_group_id" { - description = "(Deprecated) ID of the optionally created additional Security Group for the EKS cluster" - value = one(aws_security_group.default[*].id) -} - -output "security_group_arn" { - description = "(Deprecated) ARN of the optionally created additional Security Group for the EKS cluster" - value = one(aws_security_group.default[*].arn) -} - -output "security_group_name" { - description = "Name of the optionally created additional Security Group for the EKS cluster" - value = one(aws_security_group.default[*].name) -} - output "eks_cluster_id" { description = "The name of the cluster" value = one(aws_eks_cluster.default[*].id) @@ -61,9 +46,12 @@ output "eks_cluster_role_arn" { value = local.eks_service_role_arn } -output "kubernetes_config_map_id" { - description = "ID of `aws-auth` Kubernetes ConfigMap" - value = var.kubernetes_config_map_ignore_role_changes ? one(kubernetes_config_map.aws_auth_ignore_changes[*].id) : one(kubernetes_config_map.aws_auth[*].id) +output "eks_cluster_ipv6_service_cidr" { + description = <<-EOT + The IPv6 CIDR block that Kubernetes pod and service IP addresses are assigned from + if `kubernetes_network_ipv6_enabled` is set to true. If set to false this output will be null. + EOT + value = one(aws_eks_cluster.default[*].kubernetes_network_config[0].service_ipv6_cidr) } output "cluster_encryption_config_enabled" { diff --git a/security-group-variables.tf b/security-group-variables.tf deleted file mode 100644 index bab56c52..00000000 --- a/security-group-variables.tf +++ /dev/null @@ -1,59 +0,0 @@ -# security-group-inputs Version: 2 -# - -locals { - allowed_security_group_ids = concat(var.allowed_security_groups, var.allowed_security_group_ids, var.workers_security_group_ids) -} - -variable "create_security_group" { - type = bool - default = false - description = <<-EOT - Set to `true` to create and configure an additional Security Group for the cluster. - Only for backwards compatibility, if you are updating this module to the latest version on existing clusters, not recommended for new clusters. - EKS creates a managed Security Group for the cluster automatically, places the control plane and managed nodes into the Security Group, - and you can also allow unmanaged nodes to communicate with the cluster by using the `allowed_security_group_ids` variable. - The additional Security Group is kept in the module for backwards compatibility and will be removed in future releases along with this variable. - See https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html for more details. - EOT -} - -variable "associated_security_group_ids" { - type = list(string) - default = [] - description = <<-EOT - A list of IDs of Security Groups to associate the cluster with. - These security groups will not be modified. - EOT -} - -variable "allowed_security_group_ids" { - type = list(string) - default = [] - description = <<-EOT - A list of IDs of Security Groups to allow access to the cluster. - EOT -} - -variable "allowed_cidr_blocks" { - type = list(string) - default = [] - description = <<-EOT - A list of IPv4 CIDRs to allow access to the cluster. - The length of this list must be known at "plan" time. - EOT -} - -variable "custom_ingress_rules" { - type = list(object({ - description = string - from_port = number - to_port = number - protocol = string - source_security_group_id = string - })) - default = [] - description = <<-EOT - A List of Objects, which are custom security group rules that - EOT -} diff --git a/security-group.tf b/security-group.tf index e2808839..af14e008 100644 --- a/security-group.tf +++ b/security-group.tf @@ -7,104 +7,31 @@ locals { managed_security_group_rules_enabled = local.enabled && var.managed_security_group_rules_enabled } -resource "aws_security_group_rule" "managed_ingress_security_groups" { - count = local.managed_security_group_rules_enabled ? length(local.allowed_security_group_ids) : 0 +resource "aws_vpc_security_group_ingress_rule" "managed_ingress_security_groups" { + count = local.managed_security_group_rules_enabled ? length(var.allowed_security_group_ids) : 0 - description = "Allow inbound traffic from existing Security Groups" - from_port = 0 - to_port = 65535 - protocol = "-1" - source_security_group_id = local.allowed_security_group_ids[count.index] - security_group_id = local.cluster_security_group_id - type = "ingress" + description = "Allow inbound traffic from existing Security Groups" + ip_protocol = "-1" + referenced_security_group_id = var.allowed_security_group_ids[count.index] + security_group_id = local.cluster_security_group_id } -resource "aws_security_group_rule" "managed_ingress_cidr_blocks" { - count = local.managed_security_group_rules_enabled && length(var.allowed_cidr_blocks) > 0 ? 1 : 0 +resource "aws_vpc_security_group_ingress_rule" "managed_ingress_cidr_blocks" { + count = local.managed_security_group_rules_enabled ? length(var.allowed_cidr_blocks) : 0 description = "Allow inbound traffic from CIDR blocks" - from_port = 0 - to_port = 65535 - protocol = "-1" - cidr_blocks = var.allowed_cidr_blocks + ip_protocol = "-1" + cidr_ipv4 = var.allowed_cidr_blocks[count.index] security_group_id = local.cluster_security_group_id - type = "ingress" } -resource "aws_security_group_rule" "custom_ingress_rules" { +resource "aws_vpc_security_group_ingress_rule" "custom_ingress_rules" { for_each = { for sg_rule in var.custom_ingress_rules : sg_rule.source_security_group_id => sg_rule } - description = each.value.description - from_port = each.value.from_port - to_port = each.value.to_port - protocol = each.value.protocol - source_security_group_id = each.value.source_security_group_id - security_group_id = local.cluster_security_group_id - type = "ingress" -} - -# ----------------------------------------------------------------------- -# DEPRECATED: Additional Security Group -# ----------------------------------------------------------------------- - -locals { - create_security_group = local.enabled && var.create_security_group - security_group_id = one(aws_security_group.default[*].id) -} - -resource "aws_security_group" "default" { - count = local.create_security_group ? 1 : 0 - - name = module.label.id - description = "Security Group for EKS cluster" - vpc_id = var.vpc_id - tags = module.label.tags -} - -resource "aws_security_group_rule" "egress" { - count = local.create_security_group ? 1 : 0 - - description = "Allow all egress traffic" - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - security_group_id = local.security_group_id - type = "egress" -} - -resource "aws_security_group_rule" "ingress_workers" { - count = local.create_security_group ? length(var.workers_security_group_ids) : 0 - - description = "Allow the cluster to receive communication from the worker nodes" - from_port = 0 - to_port = 65535 - protocol = "-1" - source_security_group_id = var.workers_security_group_ids[count.index] - security_group_id = local.security_group_id - type = "ingress" -} - -resource "aws_security_group_rule" "ingress_security_groups" { - count = local.create_security_group ? length(var.allowed_security_groups) : 0 - - description = "Allow inbound traffic from existing Security Groups" - from_port = 0 - to_port = 65535 - protocol = "-1" - source_security_group_id = var.allowed_security_groups[count.index] - security_group_id = local.security_group_id - type = "ingress" -} - -resource "aws_security_group_rule" "ingress_cidr_blocks" { - count = local.create_security_group && length(var.allowed_cidr_blocks) > 0 ? 1 : 0 - - description = "Allow inbound traffic from CIDR blocks" - from_port = 0 - to_port = 65535 - protocol = "-1" - cidr_blocks = var.allowed_cidr_blocks - security_group_id = local.security_group_id - type = "ingress" + description = each.value.description + from_port = each.value.from_port + to_port = each.value.to_port + ip_protocol = each.value.protocol + referenced_security_group_id = each.value.source_security_group_id + security_group_id = local.cluster_security_group_id } diff --git a/test/src/go.mod b/test/src/go.mod index 81a756b3..f248490a 100644 --- a/test/src/go.mod +++ b/test/src/go.mod @@ -1,60 +1,62 @@ module github.com/cloudposse/terraform-aws-eks-cluster -go 1.20 +go 1.21 require ( - github.com/aws/aws-sdk-go v1.44.213 - github.com/gruntwork-io/terratest v0.42.0 - github.com/stretchr/testify v1.8.3 - k8s.io/api v0.26.6 - k8s.io/apimachinery v0.27.2 - k8s.io/client-go v0.26.6 - sigs.k8s.io/aws-iam-authenticator v0.6.10 + github.com/aws/aws-sdk-go v1.50.30 + github.com/gruntwork-io/terratest v0.46.11 + github.com/stretchr/testify v1.9.0 + k8s.io/api v0.29.2 + k8s.io/apimachinery v0.29.2 + k8s.io/client-go v0.29.2 + sigs.k8s.io/aws-iam-authenticator v0.6.18 ) require ( - cloud.google.com/go v0.105.0 // indirect - cloud.google.com/go/compute v1.12.1 // indirect - cloud.google.com/go/compute/metadata v0.2.1 // indirect - cloud.google.com/go/iam v0.7.0 // indirect - cloud.google.com/go/storage v1.27.0 // indirect + cloud.google.com/go v0.112.1 // indirect + cloud.google.com/go/compute v1.24.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/storage v1.39.0 // indirect github.com/agext/levenshtein v1.2.3 // indirect - github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.9.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.1 // indirect - github.com/go-openapi/swag v0.22.3 // indirect + github.com/emicklei/go-restful/v3 v3.11.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.20.2 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/swag v0.22.9 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.1.0 // indirect - github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.7.0 // indirect - github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/s2a-go v0.1.7 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.2 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.1 // indirect - github.com/hashicorp/go-multierror v1.1.0 // indirect + github.com/hashicorp/go-getter v1.7.3 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.9.1 // indirect - github.com/hashicorp/terraform-json v0.13.0 // indirect - github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect + github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/terraform-json v0.21.0 // indirect + github.com/jinzhu/copier v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.15.11 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect + github.com/mattn/go-zglob v0.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect @@ -62,36 +64,44 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/sirupsen/logrus v1.8.1 // indirect - github.com/tmccombs/hcl2json v0.3.3 // indirect - github.com/ulikunitz/xz v0.5.10 // indirect - github.com/zclconf/go-cty v1.9.1 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.49.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/tmccombs/hcl2json v0.6.1 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect + github.com/zclconf/go-cty v1.14.3 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.8.0 // indirect - golang.org/x/oauth2 v0.1.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect - golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.103.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c // indirect - google.golang.org/grpc v1.51.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + golang.org/x/crypto v0.20.0 // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.18.0 // indirect + google.golang.org/api v0.167.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto v0.0.0-20240228224816-df926f6c8641 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240228224816-df926f6c8641 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 // indirect + google.golang.org/grpc v1.62.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.90.1 // indirect - k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect - k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/utils v0.0.0-20240102154912-e7106e64919e // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/test/src/go.sum b/test/src/go.sum index 5fcea043..a71113a8 100644 --- a/test/src/go.sum +++ b/test/src/go.sum @@ -30,8 +30,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -68,10 +68,10 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= -cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= -cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= -cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= @@ -109,13 +109,12 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs= -cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= @@ -171,8 +170,9 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.39.0 h1:brbjUa4hbDHhpQf48tjqMaXEV+f1OGoaTmQau9tmCsA= +cloud.google.com/go/storage v1.39.0/go.mod h1:OAEj/WZwUYjA3YHQ10/YcN9ttGuEpLwvaoyBXIPikEk= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -188,24 +188,14 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.213 h1:WahquyWs7cQdz0vpDVWyWETEemgSoORx0PbWL9oz2WA= -github.com/aws/aws-sdk-go v1.44.213/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/aws/aws-sdk-go v1.50.30 h1:2OelKH1eayeaH7OuL1Y9Ombfw4HK+/k0fEnJNWjyLts= +github.com/aws/aws-sdk-go v1.50.30/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= @@ -213,8 +203,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -229,13 +219,11 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= -github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.3 h1:yagOQz/38xJmcNeZJtrUcKjkHRltIaIFXKWeG1SkWGE= +github.com/emicklei/go-restful/v3 v3.11.3/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -247,35 +235,29 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= -github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= +github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= +github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= +github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -293,7 +275,6 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -316,8 +297,8 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= +github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -332,17 +313,19 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -359,13 +342,17 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -375,67 +362,57 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/gruntwork-io/terratest v0.42.0 h1:j3HKRzZ7p4f1iweP2stDSYz+am4+JIbraTehiEWc77s= -github.com/gruntwork-io/terratest v0.42.0/go.mod h1:O6gajNBjO1wvc7Wl9WtbO+ORcdnhAV2GQiBE71ycwIk= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/gruntwork-io/terratest v0.46.11 h1:1Z9G18I2FNuH87Ro0YtjW4NH9ky4GDpfzE7+ivkPeB8= +github.com/gruntwork-io/terratest v0.46.11/go.mod h1:DVZG/s7eP1u3KOQJJfE6n7FDriMWpDvnj85XIlZMEM8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= -github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= -github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl/v2 v2.9.1 h1:eOy4gREY0/ZQHNItlfuEZqtcQbXIxzojlP301hDpnac= -github.com/hashicorp/hcl/v2 v2.9.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= -github.com/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY= -github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk= +github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= +github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U= +github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= -github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -443,84 +420,49 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 h1:ofNAzWCcyTALn2Zv40+8XitdzCgXY6e9qvXwN9W0YXg= -github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= -github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM= +github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/common v0.49.0 h1:ToNTdK4zSnPVJmh698mGFkDor9wBI/iGaJy5dbH1EgI= +github.com/prometheus/common v0.49.0/go.mod h1:Kxm+EULxRbUkjGU6WFsQqo3ORzB4tyKvlWFOE9mB2sE= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -529,27 +471,21 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ= -github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w= -github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tmccombs/hcl2json v0.6.1 h1:KYk0h4vqLR2LzecgsgCEhuDbNfdvSu65CEZ7VGDgBl0= +github.com/tmccombs/hcl2json v0.6.1/go.mod h1:Bqe5itpqem41iD5O2vCfiP1MoDednwR4/vHTRDpjM4A= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty v1.8.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty v1.9.1 h1:viqrgQwFl5UpSxc046qblj78wZXVDFnSOufaOTER+cc= -github.com/zclconf/go-cty v1.9.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +github.com/zclconf/go-cty v1.14.3 h1:1JXy1XroaGrzZuG6X9dt7HL6s9AwbY+l4UNL8o5B6ho= +github.com/zclconf/go-cty v1.14.3/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -559,17 +495,27 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= +go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -606,10 +552,10 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -617,7 +563,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -644,7 +589,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -657,8 +601,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -683,8 +627,9 @@ golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7Lm golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -699,24 +644,20 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -729,8 +670,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -738,7 +677,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -747,7 +685,6 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -758,7 +695,6 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -770,16 +706,17 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -789,14 +726,15 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -851,7 +789,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -859,8 +798,9 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -909,16 +849,17 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.167.0 h1:CKHrQD1BLRii6xdkatBDXyKzM0mkawt2QP+H3LtPmSE= +google.golang.org/api v0.167.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -950,7 +891,6 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1021,8 +961,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c h1:S34D59DS2GWOEwWNt4fYmTcFrtlOgukG2k9WsomZ7tg= -google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20240228224816-df926f6c8641 h1:GihpvzHjeZHw+/mzsWpdxwr1LaG6E3ff/gyeZlVHbyc= +google.golang.org/genproto v0.0.0-20240228224816-df926f6c8641/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240228224816-df926f6c8641 h1:SO1wX9btGFrwj9EzH3ocqfwiPVOxfv4ggAJajzlHA5s= +google.golang.org/genproto/googleapis/api v0.0.0-20240228224816-df926f6c8641/go.mod h1:wLupoVsUfYPgOMwjzhYFbaVklw/INms+dqTp0tc1fv8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 h1:DKU1r6Tj5s1vlU/moGhuGz7E3xRfwjdAfDzbsaQJtEY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1058,8 +1002,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= +google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1076,29 +1020,22 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1108,26 +1045,26 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.26.6 h1:RZsJGP5p/qdWuFVqj/JFyt+6ttfgL+8/K8gtyi7riuo= -k8s.io/api v0.26.6/go.mod h1:Z+i6M3de4+LJiXtIiWSz/yLpnG+YjxAkeW6cgZqoxn4= -k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= -k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= -k8s.io/client-go v0.26.6 h1:CtC0wOxkAwjYyG2URGzdEKo0nLILopSDYn5AmzOkdi4= -k8s.io/client-go v0.26.6/go.mod h1:HDjbQGY7XzFYFUWOPAfAsIYhvFXyc9l6Ne0pO0bOQ7o= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= -k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= -k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= +k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= +k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= +k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= +k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/aws-iam-authenticator v0.6.10 h1:ld4g1kQUAG9jgUUc0e4cRPhRXTvzp0/uw5M6iSYskpY= -sigs.k8s.io/aws-iam-authenticator v0.6.10/go.mod h1:uh/d/yhtzJXBdevntKgTKRaabgD2T/JI/YdV+9IaycE= +sigs.k8s.io/aws-iam-authenticator v0.6.18 h1:YyKSgeB4o2hf8Bx9vSkMm4YcWxMsO0xOm2xe001mSmA= +sigs.k8s.io/aws-iam-authenticator v0.6.18/go.mod h1:CnvFyzR/xeLHmUY/BD0qW6q0wp6KIwXmFp4eTfrHdP8= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/variables-deprecated.tf b/variables-deprecated.tf deleted file mode 100644 index c3cb4a96..00000000 --- a/variables-deprecated.tf +++ /dev/null @@ -1,19 +0,0 @@ -variable "allowed_security_groups" { - type = list(string) - default = [] - description = <<-EOT - DEPRECATED: Use `allowed_security_group_ids` instead. - Historical description: List of Security Group IDs to be allowed to connect to the EKS cluster. - Historical default: `[]` - EOT -} - -variable "workers_security_group_ids" { - type = list(string) - default = [] - description = <<-EOT - DEPRECATED: Use `allowed_security_group_ids` instead. - Historical description: Security Group IDs of the worker nodes. - Historical default: `[]` - EOT -} diff --git a/variables.tf b/variables.tf index 57e5fe4e..ae848339 100644 --- a/variables.tf +++ b/variables.tf @@ -1,20 +1,25 @@ # tflint-ignore: terraform_unused_declarations variable "region" { + type = string description = "OBSOLETE (not needed): AWS Region" default = null } -variable "vpc_id" { - type = string - description = "VPC ID for the EKS cluster" -} - variable "subnet_ids" { type = list(string) description = "A list of subnet IDs to launch the cluster in" } +variable "associated_security_group_ids" { + type = list(string) + default = [] + description = <<-EOT + A list of IDs of Security Groups to associate the cluster with. + These security groups will not be modified. + EOT +} + variable "cluster_depends_on" { type = any description = <<-EOT @@ -40,11 +45,6 @@ variable "eks_cluster_service_role_arn" { default = null } -variable "workers_role_arns" { - type = list(string) - description = "List of Role ARNs of the worker nodes" - default = [] -} variable "kubernetes_version" { type = string @@ -107,58 +107,6 @@ variable "cluster_log_retention_period" { default = 0 } -variable "apply_config_map_aws_auth" { - type = bool - description = "Whether to apply the ConfigMap to allow worker nodes to join the EKS cluster and allow additional users, accounts and roles to acces the cluster" - default = true -} - -variable "map_additional_aws_accounts" { - type = list(string) - description = "Additional AWS account numbers to add to `config-map-aws-auth` ConfigMap" - default = [] -} - -variable "map_additional_iam_roles" { - type = list(object({ - rolearn = string - username = string - groups = list(string) - })) - description = "Additional IAM roles to add to `config-map-aws-auth` ConfigMap" - default = [] -} - -variable "map_additional_iam_users" { - type = list(object({ - userarn = string - username = string - groups = list(string) - })) - description = "Additional IAM users to add to `config-map-aws-auth` ConfigMap" - default = [] -} - -variable "local_exec_interpreter" { - type = list(string) - description = "shell to use for local_exec" - default = ["/bin/sh", "-c"] -} - -variable "wait_for_cluster_command" { - type = string - description = "`local-exec` command to execute to determine if the EKS cluster is healthy. Cluster endpoint URL is available as environment variable `ENDPOINT`" - ## --max-time is per attempt, --retry is the number of attempts - ## Approx. total time limit is (max-time + retry-delay) * retry seconds - default = "if test -n \"$ENDPOINT\"; then curl --silent --fail --retry 30 --retry-delay 10 --retry-connrefused --max-time 11 --insecure --output /dev/null $ENDPOINT/healthz; fi" -} - -variable "kubernetes_config_map_ignore_role_changes" { - type = bool - description = "Set to `true` to ignore IAM role changes in the Kubernetes Auth ConfigMap" - default = true -} - variable "cluster_encryption_config_enabled" { type = bool description = "Set to `true` to enable Cluster Encryption Configuration" @@ -209,9 +157,12 @@ variable "cloudwatch_log_group_kms_key_id" { variable "addons" { type = list(object({ - addon_name = string - addon_version = optional(string, null) - configuration_values = optional(string, null) + addon_name = string + addon_version = optional(string, null) + configuration_values = optional(string, null) + # resolve_conflicts is deprecated, but we keep it for backwards compatibility + # and because if not declared, Terraform will silently ignore it. + resolve_conflicts = optional(string, null) resolve_conflicts_on_create = optional(string, null) resolve_conflicts_on_update = optional(string, null) service_account_role_arn = optional(string, null) @@ -219,7 +170,14 @@ variable "addons" { update_timeout = optional(string, null) delete_timeout = optional(string, null) })) - description = "Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources" + description = <<-EOT + Manages [`aws_eks_addon`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon) resources. + Note: `resolve_conflicts` is deprecated. If `resolve_conflicts` is set and + `resolve_conflicts_on_create` or `resolve_conflicts_on_update` is not set, + `resolve_conflicts` will be used instead. If `resolve_conflicts_on_create` is + not set and `resolve_conflicts` is `PRESERVE`, `resolve_conflicts_on_create` + will be set to `NONE`. + EOT default = [] } @@ -233,107 +191,162 @@ variable "addons_depends_on" { default = null } -################## -# All the following variables are just about configuring the Kubernetes provider -# to be able to modify the aws-auth ConfigMap. Once EKS provides a normal -# AWS API for modifying it, we can do away with all of this. -# -# The reason there are so many options is because at various times, each -# one of them has had problems, so we give you a choice. -# -# The reason there are so many "enabled" inputs rather than automatically -# detecting whether or not they are enabled based on the value of the input -# is that any logic based on input values requires the values to be known during -# the "plan" phase of Terraform, and often they are not, which causes problems. -# - -variable "kubeconfig_path_enabled" { - type = bool - description = "If `true`, configure the Kubernetes provider with `kubeconfig_path` and use it for authenticating to the EKS cluster" - default = false -} - -variable "kubeconfig_path" { - type = string - description = "The Kubernetes provider `config_path` setting to use when `kubeconfig_path_enabled` is `true`" - default = "" -} - -variable "kubeconfig_context" { - type = string - description = "Context to choose from the Kubernetes kube config file" - default = "" +variable "cluster_attributes" { + type = list(string) + description = "Override label module default cluster attributes" + default = ["cluster"] } -variable "kube_data_auth_enabled" { - type = bool +variable "access_config" { + type = object({ + authentication_mode = optional(string, "API") + bootstrap_cluster_creator_admin_permissions = optional(bool, false) + }) + description = "Access configuration for the EKS cluster." + default = {} + nullable = false + + validation { + condition = !contains(["CONFIG_MAP"], var.access_config.authentication_mode) + error_message = "The CONFIG_MAP authentication_mode is not supported." + } +} + +variable "access_entry_map" { + type = map(object({ + # key is principal_arn + user_name = optional(string) + # Cannot assign "system:*" groups to IAM users, use ClusterAdmin and Admin instead + kubernetes_groups = optional(list(string), []) + type = optional(string, "STANDARD") + access_policy_associations = optional(map(object({ + # key is policy_arn or policy_name + access_scope = optional(object({ + type = optional(string, "cluster") + namespaces = optional(list(string)) + }), {}) # access_scope + })), {}) # access_policy_associations + })) # access_entry_map description = <<-EOT - If `true`, use an `aws_eks_cluster_auth` data source to authenticate to the EKS cluster. - Disabled by `kubeconfig_path_enabled` or `kube_exec_auth_enabled`. + Map of IAM Principal ARNs to access configuration. + Preferred over other inputs as this configuration remains stable + when elements are added or removed, but it requires that the Principal ARNs + and Policy ARNs are known at plan time. + Can be used along with other `access_*` inputs, but do not duplicate entries. + Map `access_policy_associations` keys are policy ARNs, policy + full name (AmazonEKSViewPolicy), or short name (View). + It is recommended to use the default `user_name` because the default includes + IAM role or user name and the session name for assumed roles. + As a special case in support of backwards compatibility, membership in the + `system:masters` group is is translated to an association with the ClusterAdmin policy. + In all other cases, including any `system:*` group in `kubernetes_groups` is prohibited. EOT - default = true + default = {} + nullable = false } -variable "kube_exec_auth_enabled" { - type = bool +variable "access_entries" { + type = list(object({ + principal_arn = string + user_name = optional(string, null) + kubernetes_groups = optional(list(string), null) + })) description = <<-EOT - If `true`, use the Kubernetes provider `exec` feature to execute `aws eks get-token` to authenticate to the EKS cluster. - Disabled by `kubeconfig_path_enabled`, overrides `kube_data_auth_enabled`. + List of IAM principles to allow to access the EKS cluster. + It is recommended to use the default `user_name` because the default includes + the IAM role or user name and the session name for assumed roles. + Use when Principal ARN is not known at plan time. EOT - default = false -} - - -variable "kube_exec_auth_role_arn" { - type = string - description = "The role ARN for `aws eks get-token` to use" - default = "" -} - -variable "kube_exec_auth_role_arn_enabled" { - type = bool - description = "If `true`, pass `kube_exec_auth_role_arn` as the role ARN to `aws eks get-token`" - default = false + default = [] + nullable = false } -variable "kube_exec_auth_aws_profile" { - type = string - description = "The AWS config profile for `aws eks get-token` to use" - default = "" +variable "access_policy_associations" { + type = list(object({ + principal_arn = string + policy_arn = string + access_scope = object({ + type = optional(string, "cluster") + namespaces = optional(list(string)) + }) + })) + description = <<-EOT + List of AWS managed EKS access policies to associate with IAM principles. + Use when Principal ARN or Policy ARN is not known at plan time. + `policy_arn` can be the full ARN, the full name (AmazonEKSViewPolicy) or short name (View). + EOT + default = [] + nullable = false } -variable "kube_exec_auth_aws_profile_enabled" { - type = bool - description = "If `true`, pass `kube_exec_auth_aws_profile` as the `profile` to `aws eks get-token`" - default = false -} +variable "access_entries_for_nodes" { + # We use a map instead of an object because if a user supplies + # an object with an unexpected key, Terraform simply ignores it, + # leaving us with no way to detect the error. + type = map(list(string)) + description = <<-EOT + Map of list of IAM roles for the EKS non-managed worker nodes. + The map key is the node type, either `EC2_LINUX` or `EC2_WINDOWS`, + and the list contains the IAM roles of the nodes of that type. + There is no need for or utility in creating Fargate access entries, as those + are always created automatically by AWS, just as with managed nodes. + Use when Principal ARN is not known at plan time. + EOT + default = {} + nullable = false + validation { + condition = length([for k in keys(var.access_entries_for_nodes) : k if !contains(["EC2_LINUX", "EC2_WINDOWS"], k)]) == 0 + error_message = format(<<-EOS + The access_entries_for_nodes object can only contain the EC2_LINUX and EC2_WINDOWS attributes: + Keys "%s" not allowed. + EOS + , join("\", \"", [for k in keys(var.access_entries_for_nodes) : k if !contains(["EC2_LINUX", "EC2_WINDOWS"], k)])) + } + validation { + condition = !(contains(keys(var.access_entries_for_nodes), "FARGATE_LINUX")) + error_message = <<-EOM + Access entries of type "FARGATE_LINUX" are not supported because they are + automatically created by AWS EKS and should not be managed by Terraform. + EOM + } +} + +## Limited support for modifying the EKS-managed Security Group +## In the future, even this limited support may be removed -variable "aws_auth_yaml_strip_quotes" { +variable "managed_security_group_rules_enabled" { type = bool - description = "If true, remove double quotes from the generated aws-auth ConfigMap YAML to reduce spurious diffs in plans" + description = "Flag to enable/disable the ingress and egress rules for the EKS managed Security Group" default = true } -variable "dummy_kubeapi_server" { - type = string - default = "https://jsonplaceholder.typicode.com" +variable "allowed_security_group_ids" { + type = list(string) + default = [] description = <<-EOT - URL of a dummy API server for the Kubernetes server to use when the real one is unknown. - This is a workaround to ignore connection failures that break Terraform even though the results do not matter. - You can disable it by setting it to `null`; however, as of Kubernetes provider v2.3.2, doing so _will_ - cause Terraform to fail in several situations unless you provide a valid `kubeconfig` file - via `kubeconfig_path` and set `kubeconfig_path_enabled` to `true`. + A list of IDs of Security Groups to allow access to the cluster. EOT } -variable "cluster_attributes" { +variable "allowed_cidr_blocks" { type = list(string) - description = "Override label module default cluster attributes" - default = ["cluster"] + default = [] + description = <<-EOT + A list of IPv4 CIDRs to allow access to the cluster. + The length of this list must be known at "plan" time. + EOT } -variable "managed_security_group_rules_enabled" { - type = bool - description = "Flag to enable/disable the ingress and egress rules for the EKS managed Security Group" - default = true +variable "custom_ingress_rules" { + type = list(object({ + description = string + from_port = number + to_port = number + protocol = string + source_security_group_id = string + })) + default = [] + description = <<-EOT + A List of Objects, which are custom security group rules that + EOT } diff --git a/versions.tf b/versions.tf index 6a5ad201..4ad9380a 100644 --- a/versions.tf +++ b/versions.tf @@ -4,19 +4,11 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 5.0.0" - } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.7.1" + version = ">= 5.34.0" } tls = { source = "hashicorp/tls" version = ">= 3.1.0, != 4.0.0" } - null = { - source = "hashicorp/null" - version = ">= 2.0" - } } }