Skip to content

Commit 897afed

Browse files
authored
Merge pull request #89 from worldcoin/feat/add-gateway-api-support
INFRA-6062: Add Gateway API support
2 parents 10eb1ce + 815f218 commit 897afed

13 files changed

+581
-12
lines changed

datasources.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ data "aws_vpc" "cluster_vpc" {
33
id = var.vpc_config.vpc_id
44
}
55

6+
data "cloudflare_ip_ranges" "cloudflare" {}
7+
68
locals {
9+
effective_external_cert_arn = var.external_cert_arn != null ? var.external_cert_arn : var.traefik_cert_arn
10+
effective_internal_cert_arn = var.internal_cert_arn != "" ? var.internal_cert_arn : (var.internal_nlb_acm_arn != "" ? var.internal_nlb_acm_arn : local.effective_external_cert_arn)
11+
effective_nlb_service_ports = length(var.internal_nlb_service_ports) > 0 ? var.internal_nlb_service_ports : var.traefik_nlb_service_ports
12+
713
al2023_standard_ami = {
814
amd64 = format("/aws/service/eks/optimized-ami/%s/amazon-linux-2023/x86_64/standard/recommended/image_id", var.cluster_version)
915
arm64 = format("/aws/service/eks/optimized-ami/%s/amazon-linux-2023/arm64/standard/recommended/image_id", var.cluster_version)

kubernetes-gw-ext-alb.tf

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
locals {
2+
gateway_api_external_alb_name = "gw-ext-alb"
3+
4+
# Default is [] — the ALB module manages frontend SG ingress internally
5+
# using open_to_all (Cloudflare IPs or 0.0.0.0/0). backend_ingress_rules
6+
# only adds extra rules to the backend SG which has no ingress by default.
7+
gateway_api_external_alb_sg_rules = var.gateway_api_external_alb_sg_rules != null ? var.gateway_api_external_alb_sg_rules : []
8+
}
9+
10+
module "gateway_api_external_alb" {
11+
source = "git@github.com:worldcoin/terraform-aws-alb.git?ref=v1.4.2"
12+
for_each = var.gateway_api_external_enabled ? toset([local.gateway_api_external_alb_name]) : []
13+
14+
name_suffix = each.key
15+
cluster_name = local.gateway_api_lb_name_prefix
16+
tag_prefix = "gateway.k8s.aws.alb"
17+
tag_stack = format("kube-system/%s", each.key)
18+
19+
tls_listener_version = var.external_tls_listener_version
20+
21+
internal = false
22+
application = each.key
23+
namespace = "kube-system"
24+
25+
create_default_listener = false
26+
27+
acm_arn = local.effective_external_cert_arn
28+
vpc_id = var.vpc_config.vpc_id
29+
public_subnets = var.vpc_config.public_subnets
30+
open_to_all = var.open_to_all
31+
32+
s3_logs_bucket_id = var.alb_logs_bucket_id
33+
idle_timeout = var.alb_idle_timeout
34+
35+
additional_open_ports = var.additional_open_ports
36+
drop_invalid_header_fields = var.drop_invalid_header_fields
37+
backend_ingress_rules = local.gateway_api_external_alb_sg_rules
38+
39+
mtls_enabled = var.open_to_all ? false : var.mtls_enabled
40+
mtls_s3_bucket = format("wld-mtls-ca-%s", var.region)
41+
42+
datadog = {
43+
monitoring_notification_channel = var.monitoring_notification_channel
44+
}
45+
}

kubernetes-gw-ext-nlb.tf

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
locals {
2+
gateway_api_external_nlb_name = "gw-ext-nlb"
3+
4+
gateway_api_external_nlb_default_sg_rules = [
5+
{
6+
description = "allow http from Cloudflare"
7+
port = 80
8+
cidr_blocks = data.cloudflare_ip_ranges.cloudflare.ipv4_cidrs
9+
},
10+
{
11+
description = "allow http from Cloudflare (IPv6)"
12+
port = 80
13+
ipv6_cidr_blocks = data.cloudflare_ip_ranges.cloudflare.ipv6_cidrs
14+
},
15+
{
16+
description = "allow https from Cloudflare"
17+
port = 443
18+
cidr_blocks = data.cloudflare_ip_ranges.cloudflare.ipv4_cidrs
19+
},
20+
{
21+
description = "allow https from Cloudflare (IPv6)"
22+
port = 443
23+
ipv6_cidr_blocks = data.cloudflare_ip_ranges.cloudflare.ipv6_cidrs
24+
},
25+
]
26+
}
27+
28+
module "gateway_api_external_nlb" {
29+
source = "git@github.com:worldcoin/terraform-aws-nlb.git?ref=v1.3.0"
30+
31+
for_each = var.gateway_api_external_enabled ? toset([local.gateway_api_external_nlb_name]) : []
32+
33+
name_suffix = each.key
34+
cluster_name = local.gateway_api_lb_name_prefix
35+
tag_prefix = "gateway.k8s.aws.nlb"
36+
tag_stack = format("kube-system/%s", each.key)
37+
38+
tls_listener_version = var.external_tls_listener_version
39+
40+
internal = false
41+
application = each.key
42+
43+
create_default_listeners = false
44+
45+
acm_arn = local.effective_external_cert_arn
46+
vpc_id = var.vpc_config.vpc_id
47+
public_subnets = var.vpc_config.public_subnets
48+
49+
ingress_sg_rules = var.gateway_api_external_nlb_sg_rules != null ? var.gateway_api_external_nlb_sg_rules : local.gateway_api_external_nlb_default_sg_rules
50+
}

kubernetes-gw-int-alb.tf

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
locals {
2+
gateway_api_internal_alb_name = "gw-int-alb"
3+
4+
gateway_api_internal_alb_sg_rules = var.gateway_api_internal_alb_sg_rules != null ? var.gateway_api_internal_alb_sg_rules : concat(
5+
[
6+
{
7+
description = "Allow HTTPS from VPC"
8+
port = 443
9+
cidr_blocks = [data.aws_vpc.cluster_vpc.cidr_block]
10+
},
11+
],
12+
data.aws_vpc.cluster_vpc.ipv6_cidr_block != "" ? [
13+
{
14+
description = "Allow HTTPS from VPC (IPv6)"
15+
port = 443
16+
ipv6_cidr_blocks = [data.aws_vpc.cluster_vpc.ipv6_cidr_block]
17+
},
18+
] : []
19+
)
20+
}
21+
22+
module "gateway_api_internal_alb" {
23+
source = "git@github.com:worldcoin/terraform-aws-alb.git?ref=v1.4.2"
24+
for_each = var.gateway_api_internal_enabled ? toset([local.gateway_api_internal_alb_name]) : []
25+
26+
name_suffix = each.key
27+
cluster_name = local.gateway_api_lb_name_prefix
28+
tag_prefix = "gateway.k8s.aws.alb"
29+
tag_stack = format("kube-system/%s", each.key)
30+
31+
tls_listener_version = var.internal_tls_listener_version
32+
33+
internal = true
34+
application = each.key
35+
namespace = "kube-system"
36+
37+
create_default_listener = false
38+
39+
acm_arn = local.effective_internal_cert_arn
40+
vpc_id = var.vpc_config.vpc_id
41+
public_subnets = var.use_private_subnets_for_internal_nlb ? [] : var.vpc_config.public_subnets
42+
43+
backend_ingress_rules = local.gateway_api_internal_alb_sg_rules
44+
45+
s3_logs_bucket_id = var.alb_logs_bucket_id
46+
idle_timeout = var.alb_idle_timeout
47+
48+
drop_invalid_header_fields = var.drop_invalid_header_fields
49+
50+
# mTLS on the internal ALB should be disabled because we want to allow traffic within the VPC
51+
mtls_enabled = false
52+
53+
datadog = {
54+
monitoring_notification_channel = var.monitoring_notification_channel
55+
}
56+
}

kubernetes-gw-int-nlb.tf

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
locals {
2+
gateway_api_internal_nlb_name = "gw-int-nlb"
3+
4+
gateway_api_internal_nlb_sg_rules = var.gateway_api_internal_nlb_sg_rules != null ? var.gateway_api_internal_nlb_sg_rules : concat(
5+
[
6+
{
7+
description = "allow http from VPC"
8+
port = 80
9+
cidr_blocks = [data.aws_vpc.cluster_vpc.cidr_block]
10+
},
11+
{
12+
description = "allow https from VPC"
13+
port = 443
14+
cidr_blocks = [data.aws_vpc.cluster_vpc.cidr_block]
15+
},
16+
],
17+
data.aws_vpc.cluster_vpc.ipv6_cidr_block != "" ? [
18+
{
19+
description = "allow http from VPC (IPv6)"
20+
port = 80
21+
ipv6_cidr_blocks = [data.aws_vpc.cluster_vpc.ipv6_cidr_block]
22+
},
23+
{
24+
description = "allow https from VPC (IPv6)"
25+
port = 443
26+
ipv6_cidr_blocks = [data.aws_vpc.cluster_vpc.ipv6_cidr_block]
27+
},
28+
] : []
29+
)
30+
}
31+
32+
module "gateway_api_internal_nlb" {
33+
source = "git@github.com:worldcoin/terraform-aws-nlb.git?ref=v1.3.0"
34+
35+
for_each = var.gateway_api_internal_enabled ? toset([local.gateway_api_internal_nlb_name]) : []
36+
37+
name_suffix = each.key
38+
cluster_name = local.gateway_api_lb_name_prefix
39+
tag_prefix = "gateway.k8s.aws.nlb"
40+
tag_stack = format("kube-system/%s", each.key)
41+
42+
tls_listener_version = var.internal_tls_listener_version
43+
44+
internal = true
45+
application = each.key
46+
47+
create_default_listeners = false
48+
49+
acm_arn = local.effective_internal_cert_arn
50+
vpc_id = var.vpc_config.vpc_id
51+
public_subnets = var.use_private_subnets_for_internal_nlb ? [] : var.vpc_config.public_subnets
52+
private_subnets = var.use_private_subnets_for_internal_nlb ? var.vpc_config.private_subnets : []
53+
54+
ingress_sg_rules = local.gateway_api_internal_nlb_sg_rules
55+
}

kubernetes-traefik-external.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ resource "kubernetes_ingress_v1" "treafik_ingress" {
5454

5555
annotations = {
5656
"alb.ingress.kubernetes.io/scheme" = "internet-facing"
57-
"alb.ingress.kubernetes.io/certificate-arn" = length(var.acm_extra_arns) != 0 ? join(",", var.acm_extra_arns, [var.traefik_cert_arn]) : var.traefik_cert_arn
57+
"alb.ingress.kubernetes.io/certificate-arn" = length(var.acm_extra_arns) != 0 ? join(",", var.acm_extra_arns, [local.effective_external_cert_arn]) : local.effective_external_cert_arn
5858
"alb.ingress.kubernetes.io/group.name" = format("%s.%s", each.key, each.key)
5959
"alb.ingress.kubernetes.io/listen-ports" = "[{\"HTTPS\": 443}]"
6060
"alb.ingress.kubernetes.io/security-groups" = join(",", [for type, id in module.alb[each.key].sg_ids : id if id != null])
@@ -93,7 +93,7 @@ resource "kubernetes_ingress_v1" "treafik_ingress" {
9393
}
9494

9595
module "alb" {
96-
source = "git@github.com:worldcoin/terraform-aws-alb.git?ref=v1.4.1"
96+
source = "git@github.com:worldcoin/terraform-aws-alb.git?ref=v1.4.2"
9797
for_each = var.external_alb_enabled ? toset([local.external_alb_name]) : []
9898

9999
# because of lenght limitation of LB name we need to remove prefix treafik from internal NLB
@@ -106,7 +106,7 @@ module "alb" {
106106
application = each.key
107107
namespace = each.key
108108

109-
acm_arn = var.traefik_cert_arn
109+
acm_arn = local.effective_external_cert_arn
110110
vpc_id = var.vpc_config.vpc_id
111111
public_subnets = var.vpc_config.public_subnets
112112
open_to_all = var.open_to_all

kubernetes-traefik-internal.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ resource "kubernetes_service_v1" "traefik_nlb" {
1515
"service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled" = "true"
1616
"service.beta.kubernetes.io/aws-load-balancer-nlb-target-type" = "ip"
1717
"service.beta.kubernetes.io/aws-load-balancer-scheme" = "internal"
18-
"service.beta.kubernetes.io/aws-load-balancer-ssl-cert" = var.internal_nlb_acm_arn != "" ? var.internal_nlb_acm_arn : var.traefik_cert_arn
18+
"service.beta.kubernetes.io/aws-load-balancer-ssl-cert" = local.effective_internal_cert_arn
1919
"service.beta.kubernetes.io/aws-load-balancer-ssl-ports" = "443"
2020
"service.beta.kubernetes.io/aws-load-balancer-type" = "external"
2121
"service.beta.kubernetes.io/aws-load-balancer-ssl-negotiation-policy" = module.nlb[each.key].ssl_policy
@@ -48,7 +48,7 @@ resource "kubernetes_service_v1" "traefik_nlb" {
4848
}
4949

5050
dynamic "port" {
51-
for_each = var.traefik_nlb_service_ports
51+
for_each = local.effective_nlb_service_ports
5252

5353
content {
5454
name = port.value["name"]
@@ -83,7 +83,7 @@ module "nlb" {
8383
internal = true
8484
application = format("%s/%s", each.key, each.key)
8585

86-
acm_arn = var.internal_nlb_acm_arn != "" ? var.internal_nlb_acm_arn : var.traefik_cert_arn
86+
acm_arn = local.effective_internal_cert_arn
8787
vpc_id = var.vpc_config.vpc_id
8888
public_subnets = var.use_private_subnets_for_internal_nlb ? [] : var.vpc_config.public_subnets
8989
private_subnets = var.use_private_subnets_for_internal_nlb ? var.vpc_config.private_subnets : []

kubernetes.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,18 @@ provider "kubernetes" {
3535
data.aws_eks_cluster_auth.default.token
3636
)
3737
}
38+
39+
locals {
40+
gateway_api_lb_name_prefix = coalesce(var.gateway_api_lb_name_prefix, var.cluster_name)
41+
}
42+
43+
resource "terraform_data" "gateway_api_lb_name_validation" {
44+
count = (var.gateway_api_external_enabled || var.gateway_api_internal_enabled) ? 1 : 0
45+
46+
lifecycle {
47+
precondition {
48+
condition = length(local.gateway_api_lb_name_prefix) <= 21
49+
error_message = "Resolved gateway_api_lb_name_prefix '${local.gateway_api_lb_name_prefix}' exceeds 21 characters (32-char LB name limit minus '-gw-ext-alb' suffix). Set gateway_api_lb_name_prefix explicitly when cluster_name is too long."
50+
}
51+
}
52+
}

outputs.tf

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,47 @@ output "alb_arns" {
3838
value = { for k, v in module.alb : k => v.arn }
3939
}
4040

41+
# Gateway API load balancers
42+
output "gateway_api_external_alb_dns_name" {
43+
description = "DNS name of the external Gateway API ALB"
44+
value = join("", [for k, v in module.gateway_api_external_alb : v.dns_name])
45+
}
46+
47+
output "gateway_api_external_alb_arn" {
48+
description = "ARN of the external Gateway API ALB"
49+
value = join("", [for k, v in module.gateway_api_external_alb : v.arn])
50+
}
51+
52+
output "gateway_api_external_nlb_dns_name" {
53+
description = "DNS name of the external Gateway API NLB"
54+
value = join("", [for k, v in module.gateway_api_external_nlb : v.dns_name])
55+
}
56+
57+
output "gateway_api_external_nlb_arn" {
58+
description = "ARN of the external Gateway API NLB"
59+
value = join("", [for k, v in module.gateway_api_external_nlb : v.arn])
60+
}
61+
62+
output "gateway_api_internal_alb_dns_name" {
63+
description = "DNS name of the internal Gateway API ALB"
64+
value = join("", [for k, v in module.gateway_api_internal_alb : v.dns_name])
65+
}
66+
67+
output "gateway_api_internal_alb_arn" {
68+
description = "ARN of the internal Gateway API ALB"
69+
value = join("", [for k, v in module.gateway_api_internal_alb : v.arn])
70+
}
71+
72+
output "gateway_api_internal_nlb_dns_name" {
73+
description = "DNS name of the internal Gateway API NLB"
74+
value = join("", [for k, v in module.gateway_api_internal_nlb : v.dns_name])
75+
}
76+
77+
output "gateway_api_internal_nlb_arn" {
78+
description = "ARN of the internal Gateway API NLB"
79+
value = join("", [for k, v in module.gateway_api_internal_nlb : v.arn])
80+
}
81+
4182
output "cluster_oidc_issuer_url" {
4283
description = "The OIDC issuer URL for the EKS cluster"
4384
value = local.oidc

0 commit comments

Comments
 (0)