Skip to content

Commit ab2207d

Browse files
authored
feat: Improve addon dependency chain and decrease time to provision addons (due to retries) (#3218)
* feat: Improve addon dependency chain and decrease time to provision addons (due to retries) * fix: Run pre-commit to clean up docs
1 parent 97a08c8 commit ab2207d

File tree

8 files changed

+508
-11
lines changed

8 files changed

+508
-11
lines changed

main.tf

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ locals {
208208
resource "aws_eks_access_entry" "this" {
209209
for_each = { for k, v in local.merged_access_entries : k => v if local.create }
210210

211-
cluster_name = aws_eks_cluster.this[0].name
211+
cluster_name = aws_eks_cluster.this[0].id
212212
kubernetes_groups = try(each.value.kubernetes_groups, null)
213213
principal_arn = each.value.principal_arn
214214
type = try(each.value.type, "STANDARD")
@@ -225,7 +225,7 @@ resource "aws_eks_access_policy_association" "this" {
225225
type = each.value.association_access_scope_type
226226
}
227227

228-
cluster_name = aws_eks_cluster.this[0].name
228+
cluster_name = aws_eks_cluster.this[0].id
229229

230230
policy_arn = each.value.association_policy_arn
231231
principal_arn = each.value.principal_arn
@@ -481,19 +481,25 @@ resource "aws_iam_policy" "cluster_encryption" {
481481
# EKS Addons
482482
################################################################################
483483

484+
locals {
485+
# TODO - Set to `NONE` on next breaking change when default addons are disabled
486+
resolve_conflicts_on_create_default = var.bootstrap_self_managed_addons ? "OVERWRITE" : "NONE"
487+
}
488+
484489
data "aws_eks_addon_version" "this" {
485490
for_each = { for k, v in var.cluster_addons : k => v if local.create && !local.create_outposts_local_cluster }
486491

487492
addon_name = try(each.value.name, each.key)
488493
kubernetes_version = coalesce(var.cluster_version, aws_eks_cluster.this[0].version)
489-
most_recent = try(each.value.most_recent, null)
494+
# TODO - Set default fallback to `true` on next breaking change
495+
most_recent = try(each.value.most_recent, null)
490496
}
491497

492498
resource "aws_eks_addon" "this" {
493499
# Not supported on outposts
494500
for_each = { for k, v in var.cluster_addons : k => v if !try(v.before_compute, false) && local.create && !local.create_outposts_local_cluster }
495501

496-
cluster_name = aws_eks_cluster.this[0].name
502+
cluster_name = aws_eks_cluster.this[0].id
497503
addon_name = try(each.value.name, each.key)
498504

499505
addon_version = coalesce(try(each.value.addon_version, null), data.aws_eks_addon_version.this[each.key].version)
@@ -508,8 +514,9 @@ resource "aws_eks_addon" "this" {
508514
}
509515
}
510516

511-
preserve = try(each.value.preserve, true)
512-
resolve_conflicts_on_create = try(each.value.resolve_conflicts_on_create, "OVERWRITE")
517+
preserve = try(each.value.preserve, true)
518+
# TODO - Set to `NONE` on next breaking change when default addons are disabled
519+
resolve_conflicts_on_create = try(each.value.resolve_conflicts_on_create, local.resolve_conflicts_on_create_default)
513520
resolve_conflicts_on_update = try(each.value.resolve_conflicts_on_update, "OVERWRITE")
514521
service_account_role_arn = try(each.value.service_account_role_arn, null)
515522

@@ -532,7 +539,7 @@ resource "aws_eks_addon" "before_compute" {
532539
# Not supported on outposts
533540
for_each = { for k, v in var.cluster_addons : k => v if try(v.before_compute, false) && local.create && !local.create_outposts_local_cluster }
534541

535-
cluster_name = aws_eks_cluster.this[0].name
542+
cluster_name = aws_eks_cluster.this[0].id
536543
addon_name = try(each.value.name, each.key)
537544

538545
addon_version = coalesce(try(each.value.addon_version, null), data.aws_eks_addon_version.this[each.key].version)
@@ -547,8 +554,9 @@ resource "aws_eks_addon" "before_compute" {
547554
}
548555
}
549556

550-
preserve = try(each.value.preserve, true)
551-
resolve_conflicts_on_create = try(each.value.resolve_conflicts_on_create, "OVERWRITE")
557+
preserve = try(each.value.preserve, true)
558+
# TODO - Set to `NONE` on next breaking change when default addons are disabled
559+
resolve_conflicts_on_create = try(each.value.resolve_conflicts_on_create, local.resolve_conflicts_on_create_default)
552560
resolve_conflicts_on_update = try(each.value.resolve_conflicts_on_update, "OVERWRITE")
553561
service_account_role_arn = try(each.value.service_account_role_arn, null)
554562

@@ -570,14 +578,15 @@ locals {
570578
# Maintain current behavior for <= 1.29, remove default for >= 1.30
571579
# `null` will return the latest Kubernetes version from the EKS API, which at time of writing is 1.30
572580
# https://github.com/kubernetes/kubernetes/pull/123561
581+
# TODO - remove on next breaking change in conjunction with issuer URL change below
573582
idpc_backwards_compat_version = contains(["1.21", "1.22", "1.23", "1.24", "1.25", "1.26", "1.27", "1.28", "1.29"], coalesce(var.cluster_version, "1.30"))
574583
idpc_issuer_url = local.idpc_backwards_compat_version ? try(aws_eks_cluster.this[0].identity[0].oidc[0].issuer, null) : null
575584
}
576585

577586
resource "aws_eks_identity_provider_config" "this" {
578587
for_each = { for k, v in var.cluster_identity_providers : k => v if local.create && !local.create_outposts_local_cluster }
579588

580-
cluster_name = aws_eks_cluster.this[0].name
589+
cluster_name = aws_eks_cluster.this[0].id
581590

582591
oidc {
583592
client_id = each.value.client_id

node_groups.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ resource "time_sleep" "this" {
3232
create_duration = var.dataplane_wait_duration
3333

3434
triggers = {
35-
cluster_name = aws_eks_cluster.this[0].name
35+
cluster_name = aws_eks_cluster.this[0].id
3636
cluster_endpoint = aws_eks_cluster.this[0].endpoint
3737
cluster_version = aws_eks_cluster.this[0].version
3838
cluster_service_cidr = var.cluster_ip_family == "ipv6" ? try(local.kubernetes_network_config.service_ipv6_cidr, "") : try(local.kubernetes_network_config.service_ipv4_cidr, "")

tests/fast-addons/README.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Fast Addons
2+
3+
Refer to https://github.com/terraform-aws-modules/terraform-aws-eks/pull/3214 for additional information.
4+
5+
<!-- TODO - remove this at next breaking change since the defaults will be in place -->
6+
7+
## Usage
8+
9+
To provision the provided configurations you need to execute:
10+
11+
```bash
12+
$ terraform init
13+
$ terraform plan
14+
$ terraform apply --auto-approve
15+
```
16+
17+
Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
18+
19+
<!-- BEGIN_TF_DOCS -->
20+
## Requirements
21+
22+
| Name | Version |
23+
|------|---------|
24+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.2 |
25+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.75 |
26+
27+
## Providers
28+
29+
| Name | Version |
30+
|------|---------|
31+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.75 |
32+
33+
## Modules
34+
35+
| Name | Source | Version |
36+
|------|--------|---------|
37+
| <a name="module_eks"></a> [eks](#module\_eks) | ../.. | n/a |
38+
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 |
39+
40+
## Resources
41+
42+
| Name | Type |
43+
|------|------|
44+
| [aws_route_table_association.custom_network](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
45+
| [aws_subnet.custom_network](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
46+
| [aws_vpc_ipv4_cidr_block_association.custom_network](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_ipv4_cidr_block_association) | resource |
47+
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
48+
49+
## Inputs
50+
51+
No inputs.
52+
53+
## Outputs
54+
55+
| Name | Description |
56+
|------|-------------|
57+
| <a name="output_access_entries"></a> [access\_entries](#output\_access\_entries) | Map of access entries created and their attributes |
58+
| <a name="output_cloudwatch_log_group_arn"></a> [cloudwatch\_log\_group\_arn](#output\_cloudwatch\_log\_group\_arn) | Arn of cloudwatch log group created |
59+
| <a name="output_cloudwatch_log_group_name"></a> [cloudwatch\_log\_group\_name](#output\_cloudwatch\_log\_group\_name) | Name of cloudwatch log group created |
60+
| <a name="output_cluster_addons"></a> [cluster\_addons](#output\_cluster\_addons) | Map of attribute maps for all EKS cluster addons enabled |
61+
| <a name="output_cluster_arn"></a> [cluster\_arn](#output\_cluster\_arn) | The Amazon Resource Name (ARN) of the cluster |
62+
| <a name="output_cluster_certificate_authority_data"></a> [cluster\_certificate\_authority\_data](#output\_cluster\_certificate\_authority\_data) | Base64 encoded certificate data required to communicate with the cluster |
63+
| <a name="output_cluster_dualstack_oidc_issuer_url"></a> [cluster\_dualstack\_oidc\_issuer\_url](#output\_cluster\_dualstack\_oidc\_issuer\_url) | Dual-stack compatible URL on the EKS cluster for the OpenID Connect identity provider |
64+
| <a name="output_cluster_endpoint"></a> [cluster\_endpoint](#output\_cluster\_endpoint) | Endpoint for your Kubernetes API server |
65+
| <a name="output_cluster_iam_role_arn"></a> [cluster\_iam\_role\_arn](#output\_cluster\_iam\_role\_arn) | IAM role ARN of the EKS cluster |
66+
| <a name="output_cluster_iam_role_name"></a> [cluster\_iam\_role\_name](#output\_cluster\_iam\_role\_name) | IAM role name of the EKS cluster |
67+
| <a name="output_cluster_iam_role_unique_id"></a> [cluster\_iam\_role\_unique\_id](#output\_cluster\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role |
68+
| <a name="output_cluster_id"></a> [cluster\_id](#output\_cluster\_id) | The ID of the EKS cluster. Note: currently a value is returned only for local EKS clusters created on Outposts |
69+
| <a name="output_cluster_identity_providers"></a> [cluster\_identity\_providers](#output\_cluster\_identity\_providers) | Map of attribute maps for all EKS identity providers enabled |
70+
| <a name="output_cluster_ip_family"></a> [cluster\_ip\_family](#output\_cluster\_ip\_family) | The IP family used by the cluster (e.g. `ipv4` or `ipv6`) |
71+
| <a name="output_cluster_name"></a> [cluster\_name](#output\_cluster\_name) | The name of the EKS cluster |
72+
| <a name="output_cluster_oidc_issuer_url"></a> [cluster\_oidc\_issuer\_url](#output\_cluster\_oidc\_issuer\_url) | The URL on the EKS cluster for the OpenID Connect identity provider |
73+
| <a name="output_cluster_platform_version"></a> [cluster\_platform\_version](#output\_cluster\_platform\_version) | Platform version for the cluster |
74+
| <a name="output_cluster_primary_security_group_id"></a> [cluster\_primary\_security\_group\_id](#output\_cluster\_primary\_security\_group\_id) | Cluster security group that was created by Amazon EKS for the cluster. Managed node groups use this security group for control-plane-to-data-plane communication. Referred to as 'Cluster security group' in the EKS console |
75+
| <a name="output_cluster_security_group_arn"></a> [cluster\_security\_group\_arn](#output\_cluster\_security\_group\_arn) | Amazon Resource Name (ARN) of the cluster security group |
76+
| <a name="output_cluster_security_group_id"></a> [cluster\_security\_group\_id](#output\_cluster\_security\_group\_id) | ID of the cluster security group |
77+
| <a name="output_cluster_service_cidr"></a> [cluster\_service\_cidr](#output\_cluster\_service\_cidr) | The CIDR block where Kubernetes pod and service IP addresses are assigned from |
78+
| <a name="output_cluster_status"></a> [cluster\_status](#output\_cluster\_status) | Status of the EKS cluster. One of `CREATING`, `ACTIVE`, `DELETING`, `FAILED` |
79+
| <a name="output_cluster_tls_certificate_sha1_fingerprint"></a> [cluster\_tls\_certificate\_sha1\_fingerprint](#output\_cluster\_tls\_certificate\_sha1\_fingerprint) | The SHA1 fingerprint of the public key of the cluster's certificate |
80+
| <a name="output_eks_managed_node_groups"></a> [eks\_managed\_node\_groups](#output\_eks\_managed\_node\_groups) | Map of attribute maps for all EKS managed node groups created |
81+
| <a name="output_eks_managed_node_groups_autoscaling_group_names"></a> [eks\_managed\_node\_groups\_autoscaling\_group\_names](#output\_eks\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by EKS managed node groups |
82+
| <a name="output_fargate_profiles"></a> [fargate\_profiles](#output\_fargate\_profiles) | Map of attribute maps for all EKS Fargate Profiles created |
83+
| <a name="output_kms_key_arn"></a> [kms\_key\_arn](#output\_kms\_key\_arn) | The Amazon Resource Name (ARN) of the key |
84+
| <a name="output_kms_key_id"></a> [kms\_key\_id](#output\_kms\_key\_id) | The globally unique identifier for the key |
85+
| <a name="output_kms_key_policy"></a> [kms\_key\_policy](#output\_kms\_key\_policy) | The IAM resource policy set on the key |
86+
| <a name="output_node_security_group_arn"></a> [node\_security\_group\_arn](#output\_node\_security\_group\_arn) | Amazon Resource Name (ARN) of the node shared security group |
87+
| <a name="output_node_security_group_id"></a> [node\_security\_group\_id](#output\_node\_security\_group\_id) | ID of the node shared security group |
88+
| <a name="output_oidc_provider"></a> [oidc\_provider](#output\_oidc\_provider) | The OpenID Connect identity provider (issuer URL without leading `https://`) |
89+
| <a name="output_oidc_provider_arn"></a> [oidc\_provider\_arn](#output\_oidc\_provider\_arn) | The ARN of the OIDC Provider if `enable_irsa = true` |
90+
| <a name="output_self_managed_node_groups"></a> [self\_managed\_node\_groups](#output\_self\_managed\_node\_groups) | Map of attribute maps for all self managed node groups created |
91+
| <a name="output_self_managed_node_groups_autoscaling_group_names"></a> [self\_managed\_node\_groups\_autoscaling\_group\_names](#output\_self\_managed\_node\_groups\_autoscaling\_group\_names) | List of the autoscaling group names created by self-managed node groups |
92+
<!-- END_TF_DOCS -->

tests/fast-addons/main.tf

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
provider "aws" {
2+
region = local.region
3+
}
4+
5+
locals {
6+
name = "ex-${basename(path.cwd)}"
7+
cluster_version = "1.31"
8+
region = "eu-west-1"
9+
10+
tags = {
11+
Test = local.name
12+
GithubRepo = "terraform-aws-eks"
13+
GithubOrg = "terraform-aws-modules"
14+
}
15+
}
16+
17+
################################################################################
18+
# EKS Module
19+
################################################################################
20+
21+
module "eks" {
22+
source = "../.."
23+
24+
cluster_name = local.name
25+
cluster_version = local.cluster_version
26+
cluster_endpoint_public_access = true
27+
28+
enable_cluster_creator_admin_permissions = true
29+
30+
# Disable the default self-managed addons to avoid the penalty of adopting them later
31+
bootstrap_self_managed_addons = false
32+
33+
# Addons will be provisioned net new via the EKS addon API
34+
cluster_addons = {
35+
coredns = {
36+
most_recent = true
37+
}
38+
eks-pod-identity-agent = {
39+
before_compute = true
40+
most_recent = true
41+
}
42+
kube-proxy = {
43+
most_recent = true
44+
}
45+
vpc-cni = {
46+
most_recent = true
47+
before_compute = true
48+
configuration_values = jsonencode({
49+
env = {
50+
# Use subnet tags to avoid the need to inject the ENIConfig
51+
# which requires a live API server endpoint which leads to a dependency of:
52+
# Control plane -> API request to create ENIConfig -> VPC CNI addon -> nodes/compute
53+
# With the subnet discovery feature, we can avoid this dependency:
54+
# Control plane -> VPC CNI addon -> nodes/compute
55+
ENABLE_SUBNET_DISCOVERY = "true"
56+
}
57+
})
58+
}
59+
}
60+
61+
vpc_id = module.vpc.vpc_id
62+
subnet_ids = module.vpc.private_subnets
63+
64+
eks_managed_node_groups = {
65+
example = {
66+
instance_types = ["m6i.large"]
67+
68+
min_size = 2
69+
max_size = 5
70+
desired_size = 2
71+
}
72+
}
73+
74+
tags = local.tags
75+
}
76+
77+
################################################################################
78+
# VPC
79+
################################################################################
80+
81+
data "aws_availability_zones" "available" {
82+
# Exclude local zones
83+
filter {
84+
name = "opt-in-status"
85+
values = ["opt-in-not-required"]
86+
}
87+
}
88+
89+
locals {
90+
vpc_cidr = "10.0.0.0/16"
91+
azs = slice(data.aws_availability_zones.available.names, 0, 3)
92+
}
93+
94+
module "vpc" {
95+
source = "terraform-aws-modules/vpc/aws"
96+
version = "~> 5.0"
97+
98+
name = local.name
99+
cidr = local.vpc_cidr
100+
101+
azs = local.azs
102+
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
103+
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
104+
105+
enable_nat_gateway = true
106+
single_nat_gateway = true
107+
108+
public_subnet_tags = {
109+
"kubernetes.io/role/elb" = 1
110+
}
111+
112+
tags = local.tags
113+
}
114+
115+
################################################################################
116+
# Custom Networking
117+
################################################################################
118+
119+
locals {
120+
custom_network_vpc_cidr = "10.99.0.0/16"
121+
122+
custom_network_subnets = [for k, v in local.azs : cidrsubnet(local.custom_network_vpc_cidr, 4, k)]
123+
}
124+
125+
resource "aws_vpc_ipv4_cidr_block_association" "custom_network" {
126+
vpc_id = module.vpc.vpc_id
127+
cidr_block = local.custom_network_vpc_cidr
128+
}
129+
130+
resource "aws_subnet" "custom_network" {
131+
count = length(local.custom_network_subnets)
132+
133+
vpc_id = module.vpc.vpc_id
134+
cidr_block = element(local.custom_network_subnets, count.index)
135+
136+
tags = merge(
137+
local.tags,
138+
{
139+
# Tag for subnet discovery
140+
"kubernetes.io/role/cni" = 1
141+
"kubernetes.io/role/internal-elb" = 1
142+
}
143+
)
144+
145+
depends_on = [
146+
aws_vpc_ipv4_cidr_block_association.custom_network
147+
]
148+
}
149+
150+
resource "aws_route_table_association" "custom_network" {
151+
count = length(local.custom_network_subnets)
152+
153+
subnet_id = element(aws_subnet.custom_network[*].id, count.index)
154+
route_table_id = element(module.vpc.private_route_table_ids, 0)
155+
156+
depends_on = [
157+
aws_vpc_ipv4_cidr_block_association.custom_network
158+
]
159+
}

0 commit comments

Comments
 (0)