Skip to content

Commit e83bf5f

Browse files
djeebusdjeebotgithub-actions[bot]
authored
feat: support per-route timeout overrides for ingress path rules (#2250)
Co-authored-by: djeebot <djeebot@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 5e0936d commit e83bf5f

18 files changed

Lines changed: 165 additions & 77 deletions

File tree

.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ ij_yaml_spaces_within_brackets = false
77
[*.hcl]
88
indent_size = 2
99
indent_style = space
10+
11+
[*.toml]
12+
indent_size = 2
13+
indent_style = space

iac/modules/job-ingress/jobs/ingress.hcl

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,41 +81,31 @@ job "ingress" {
8181
image = "traefik:v3.5"
8282
ports = ["control", "ingress"]
8383
args = [
84-
# Entry-points that are set internally by Traefik
85-
"--entrypoints.web.address=:${ingress_port}",
86-
"--entrypoints.traefik.address=:${control_port}",
87-
88-
# Traefik internals (logging, metrics, ...)
89-
"--api.dashboard=true",
90-
"--api.insecure=false",
91-
92-
"--accesslog=true",
93-
"--ping=true",
94-
"--ping.entryPoint=web",
95-
"--metrics=true",
96-
"--metrics.otlp=true",
97-
"--metrics.otlp.grpc=true",
98-
"--metrics.otlp.grpc.endpoint=${otel_collector_grpc_endpoint}",
99-
"--metrics.otlp.grpc.insecure=true",
100-
101-
%{ for arg in additional_args }
102-
"${ arg }",
103-
%{ endfor }
104-
105-
# Traefik Nomad provider
106-
"--providers.nomad=true",
107-
"--providers.nomad.exposedByDefault=false",
108-
"--providers.nomad.endpoint.address=${nomad_endpoint}",
109-
"--providers.nomad.endpoint.token=${nomad_token}",
110-
111-
# Traefik Consul provider
112-
"--providers.consulcatalog=true",
113-
"--providers.consulcatalog.exposedByDefault=false",
114-
"--providers.consulcatalog.endpoint.address=${consul_endpoint}",
115-
"--providers.consulcatalog.endpoint.token=${consul_token}",
84+
"--configFile=/local/traefik.toml",
11685
]
11786
}
11887

88+
template {
89+
data = <<EOF
90+
${traefik_config}
91+
EOF
92+
destination = "local/traefik.toml"
93+
}
94+
95+
template {
96+
data = "# content ignored, ensures the directory exists"
97+
destination = "local/config/.keep"
98+
}
99+
100+
%{ for filename, content in config_files }
101+
template {
102+
data = <<EOF
103+
${content}
104+
EOF
105+
destination = "local/config/${filename}"
106+
}
107+
%{ endfor }
108+
119109
resources {
120110
memory_max = ${memory_mb * 1.5}
121111
memory = ${memory_mb}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[accessLog]
2+
3+
[api]
4+
dashboard = true
5+
insecure = false
6+
7+
[entryPoints]
8+
[entryPoints.web]
9+
address = ":${ingress_port}"
10+
[entryPoints.traefik]
11+
address = ":${control_port}"
12+
13+
[metrics]
14+
[metrics.otlp]
15+
[metrics.otlp.grpc]
16+
endpoint = "${otel_collector_grpc_endpoint}"
17+
insecure = true
18+
19+
[ping]
20+
entryPoint = "web"
21+
22+
[providers]
23+
[providers.consulCatalog]
24+
exposedByDefault = false
25+
[providers.consulCatalog.endpoint]
26+
address = "${consul_endpoint}"
27+
token = "${consul_token}"
28+
[providers.file]
29+
directory = "/local/config"
30+
watch = false
31+
[providers.nomad]
32+
exposedByDefault = false
33+
[providers.nomad.endpoint]
34+
address = "${nomad_endpoint}"
35+
token = "${nomad_token}"

iac/modules/job-ingress/main.tf

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
locals {
2+
traefik_config = templatefile("${path.module}/jobs/traefik.toml", {
3+
ingress_port = var.ingress_proxy_port
4+
control_port = var.ingress_control_port
5+
6+
nomad_endpoint = var.nomad_endpoint
7+
nomad_token = var.nomad_token
8+
9+
consul_endpoint = var.consul_endpoint
10+
consul_token = var.consul_token
11+
12+
otel_collector_grpc_endpoint = var.otel_collector_grpc_endpoint
13+
})
14+
}
15+
116
resource "nomad_job" "ingress" {
217
jobspec = templatefile("${path.module}/jobs/ingress.hcl", {
318
count = var.ingress_count
@@ -6,16 +21,10 @@ resource "nomad_job" "ingress" {
621
cpu_count = var.ingress_cpu_count
722
memory_mb = var.ingress_memory_mb
823

9-
ingress_port = var.ingress_proxy_port
10-
control_port = var.ingress_control_port
11-
additional_args = var.additional_traefik_arguments
12-
13-
nomad_endpoint = var.nomad_endpoint
14-
nomad_token = var.nomad_token
24+
ingress_port = var.ingress_proxy_port
25+
control_port = var.ingress_control_port
1526

16-
consul_token = var.consul_token
17-
consul_endpoint = var.consul_endpoint
18-
19-
otel_collector_grpc_endpoint = var.otel_collector_grpc_endpoint
27+
traefik_config = local.traefik_config
28+
config_files = var.traefik_config_files
2029
})
2130
}

iac/modules/job-ingress/variables.tf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ variable "otel_collector_grpc_endpoint" {
5454
description = "OpenTelemetry collector gRPC endpoint (e.g., localhost:4317)"
5555
}
5656

57-
variable "additional_traefik_arguments" {
58-
type = list(string)
57+
variable "traefik_config_files" {
58+
type = map(string)
59+
description = "Map of filename => content for additional Traefik dynamic configuration files"
5960
}

iac/provider-aws/main.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ module "nomad" {
193193
admin_token = module.init.admin_token
194194
sandbox_access_token_hash_seed = module.init.sandbox_access_token_hash_seed
195195

196-
ingress_port = local.ingress_port
197-
ingress_count = var.ingress_count
198-
additional_traefik_arguments = var.additional_traefik_arguments
196+
ingress_port = local.ingress_port
197+
ingress_count = var.ingress_count
198+
traefik_config_files = var.traefik_config_files
199199

200200
client_proxy_count = var.client_proxy_count
201201
client_proxy_repository_name = module.init.client_proxy_repository_name

iac/provider-aws/nomad/main.tf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ module "redis" {
7373
module "ingress" {
7474
source = "../../modules/job-ingress"
7575

76-
ingress_count = var.ingress_count
77-
ingress_proxy_port = var.ingress_port
78-
additional_traefik_arguments = var.additional_traefik_arguments
76+
ingress_count = var.ingress_count
77+
ingress_proxy_port = var.ingress_port
78+
traefik_config_files = var.traefik_config_files
7979

8080
node_pool = var.api_node_pool
8181
update_stanza = var.api_cluster_size > 1

iac/provider-aws/nomad/variables.tf

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,8 @@ variable "launch_darkly_api_key" {
309309
sensitive = true
310310
}
311311

312-
variable "additional_traefik_arguments" {
313-
type = list(string)
314-
default = []
312+
variable "traefik_config_files" {
313+
type = map(string)
315314
}
316315

317316
variable "db_max_open_connections" {

iac/provider-aws/variables.tf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,10 @@ variable "control_server_cluster_size" {
156156
default = 3
157157
}
158158

159-
variable "additional_traefik_arguments" {
160-
type = list(string)
161-
default = []
159+
variable "traefik_config_files" {
160+
type = map(string)
161+
description = "Map of filename => content for additional Traefik dynamic configuration files"
162+
default = {}
162163
}
163164

164165
variable "db_max_open_connections" {

iac/provider-gcp/main.tf

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ data "google_secret_manager_secret_version" "routing_domains" {
5252
locals {
5353
additional_domains = nonsensitive(jsondecode(data.google_secret_manager_secret_version.routing_domains.secret_data))
5454

55+
# Normalize additional_api_paths_handled_by_ingress to support both legacy (list of strings)
56+
# and new (list of objects) formats. Strings are converted to objects with paths = [string].
57+
normalized_api_paths_handled_by_ingress = [
58+
for item in var.additional_api_paths_handled_by_ingress : {
59+
paths = try(item.paths, [item])
60+
timeout_sec = try(item.timeout_sec, null)
61+
}
62+
]
63+
5564
// Check if all clusters has size greater than 1
5665
template_manages_clusters_size_gt_1 = alltrue([for c in var.build_clusters_config : (c.cluster_size > 1)])
5766

@@ -150,9 +159,10 @@ module "cluster" {
150159
nomad_port = var.nomad_port
151160
google_service_account_email = module.init.service_account_email
152161
domain_name = var.domain_name
162+
ingress_timeout_seconds = var.ingress_timeout_seconds
153163

154164
additional_domains = local.additional_domains
155-
additional_api_paths_handled_by_ingress = var.additional_api_paths_handled_by_ingress
165+
additional_api_paths_handled_by_ingress = local.normalized_api_paths_handled_by_ingress
156166

157167
docker_contexts_bucket_name = module.init.envs_docker_context_bucket_name
158168
cluster_setup_bucket_name = module.init.cluster_setup_bucket_name
@@ -208,9 +218,9 @@ module "nomad" {
208218
clickhouse_node_pool = var.clickhouse_node_pool
209219

210220
# Ingress
211-
ingress_port = var.ingress_port
212-
ingress_count = var.ingress_count
213-
additional_traefik_arguments = var.additional_traefik_arguments
221+
ingress_port = var.ingress_port
222+
ingress_count = var.ingress_count
223+
traefik_config_files = var.traefik_config_files
214224

215225
# API
216226
api_server_count = var.api_server_count

0 commit comments

Comments
 (0)