Skip to content

Commit 8b9af22

Browse files
committed
fix: expose the lighthouse queue redis over PrivateLink
1 parent 47bd86d commit 8b9af22

File tree

11 files changed

+252
-2
lines changed

11 files changed

+252
-2
lines changed

ops/mainnet/staging/backend/config.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ locals {
4747
{ name = "DD_LOGS_ENABLED", value = "true" },
4848
{ name = "DD_API_KEY", value = var.dd_api_key },
4949
{ name = "CARTOGRAPHER_ADMIN_TOKEN", value = var.cartographer_admin_token },
50-
{ name = "REDIS_URL", value = data.terraform_remote_state.core.outputs.lighthouse_queue_redis_url },
50+
{ name = "REDIS_URL", value = "rediss://:${data.terraform_remote_state.core.outputs.lighthouse_queue_redis_auth_token}@${module.lighthouse_queue_privatelink.endpoint_dns_name}:${data.terraform_remote_state.core.outputs.lighthouse_queue_redis_port}?tlsServername=${data.terraform_remote_state.core.outputs.lighthouse_queue_redis_address}" },
5151
]
5252

5353
local_cartographer_config_obj = {

ops/mainnet/staging/backend/main.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,19 @@ module "cartographer-handler" {
264264
domain = var.domain
265265
}
266266

267+
# PrivateLink consumer endpoint — gives cartographer-handler access to the
268+
# lighthouse queue Redis that lives in the core VPC.
269+
module "lighthouse_queue_privatelink" {
270+
source = "../../../modules/privatelink/consumer"
271+
stage = var.stage
272+
environment = var.environment
273+
family = "lh-queue"
274+
vpc_id = module.network.vpc_id
275+
subnet_ids = module.network.public_subnets
276+
endpoint_service_name = data.terraform_remote_state.core.outputs.lighthouse_queue_endpoint_service_name
277+
port = data.terraform_remote_state.core.outputs.lighthouse_queue_redis_port
278+
}
279+
267280
module "network" {
268281
source = "../../../modules/networking"
269282
cidr_block = var.cidr_block

ops/mainnet/staging/core/main.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,19 @@ module "lighthouse_queue_cache" {
544544
auth_token = var.lighthouse_queue_redis_auth_token
545545
}
546546

547+
# Expose the lighthouse queue Redis over PrivateLink so the cartographer-handler
548+
# in the backend VPC can enqueue BullMQ jobs without direct VPC connectivity.
549+
module "lighthouse_queue_privatelink" {
550+
source = "../../../modules/privatelink/provider"
551+
stage = var.stage
552+
environment = var.environment
553+
family = "lh-queue"
554+
vpc_id = module.network.vpc_id
555+
subnet_ids = module.network.public_subnets
556+
target_address = module.lighthouse_queue_cache.redis_instance_address
557+
target_port = module.lighthouse_queue_cache.redis_instance_port
558+
}
559+
547560
module "watchtower_cache" {
548561
source = "../../../modules/redis"
549562
stage = var.stage

ops/mainnet/staging/core/outputs.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,20 @@ output "lighthouse_queue_redis_url" {
1818
value = "rediss://:${var.lighthouse_queue_redis_auth_token}@${module.lighthouse_queue_cache.redis_instance_address}:${module.lighthouse_queue_cache.redis_instance_port}"
1919
sensitive = true
2020
}
21+
22+
output "lighthouse_queue_endpoint_service_name" {
23+
value = module.lighthouse_queue_privatelink.endpoint_service_name
24+
}
25+
26+
output "lighthouse_queue_redis_port" {
27+
value = module.lighthouse_queue_cache.redis_instance_port
28+
}
29+
30+
output "lighthouse_queue_redis_auth_token" {
31+
value = var.lighthouse_queue_redis_auth_token
32+
sensitive = true
33+
}
34+
35+
output "lighthouse_queue_redis_address" {
36+
value = module.lighthouse_queue_cache.redis_instance_address
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# VPC Interface Endpoint in the consumer VPC.
2+
# Connects to a PrivateLink Endpoint Service in another VPC,
3+
# giving local services a DNS name that routes traffic across VPCs.
4+
5+
resource "aws_security_group" "endpoint" {
6+
name = "pl-endpoint-${var.environment}-${var.stage}-${var.family}"
7+
description = "Allow traffic to PrivateLink endpoint for ${var.family}"
8+
vpc_id = var.vpc_id
9+
10+
ingress {
11+
from_port = var.port
12+
to_port = var.port
13+
protocol = "tcp"
14+
cidr_blocks = ["0.0.0.0/0"]
15+
}
16+
17+
egress {
18+
from_port = 0
19+
to_port = 0
20+
protocol = "-1"
21+
cidr_blocks = ["0.0.0.0/0"]
22+
}
23+
24+
tags = {
25+
Environment = var.environment
26+
Stage = var.stage
27+
}
28+
}
29+
30+
resource "aws_vpc_endpoint" "this" {
31+
vpc_id = var.vpc_id
32+
service_name = var.endpoint_service_name
33+
vpc_endpoint_type = "Interface"
34+
subnet_ids = var.subnet_ids
35+
private_dns_enabled = false
36+
37+
security_group_ids = [aws_security_group.endpoint.id]
38+
39+
tags = {
40+
Name = "pl-endpoint-${var.environment}-${var.stage}-${var.family}"
41+
Environment = var.environment
42+
Stage = var.stage
43+
}
44+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "endpoint_dns_name" {
2+
description = "DNS name of the VPC endpoint — use as the host for cross-VPC clients"
3+
value = aws_vpc_endpoint.this.dns_entry[0].dns_name
4+
}
5+
6+
output "endpoint_id" {
7+
description = "ID of the VPC endpoint"
8+
value = aws_vpc_endpoint.this.id
9+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
variable "environment" {
2+
description = "Environment name"
3+
type = string
4+
}
5+
6+
variable "stage" {
7+
description = "Stage of deployment"
8+
type = string
9+
}
10+
11+
variable "family" {
12+
description = "Service family name for resource naming"
13+
type = string
14+
}
15+
16+
variable "vpc_id" {
17+
description = "VPC ID where the consuming service lives"
18+
type = string
19+
}
20+
21+
variable "subnet_ids" {
22+
description = "Subnet IDs for the VPC endpoint"
23+
type = list(string)
24+
}
25+
26+
variable "endpoint_service_name" {
27+
description = "Service name of the VPC Endpoint Service (from the provider module output)"
28+
type = string
29+
}
30+
31+
variable "port" {
32+
description = "Port of the target service"
33+
type = number
34+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# NLB + VPC Endpoint Service in the provider VPC.
2+
# Exposes a TCP service over PrivateLink so consumers in other VPCs can reach it.
3+
4+
# Service endpoints are typically DNS names; resolve to IP for the NLB target group.
5+
data "dns_a_record_set" "target" {
6+
host = var.target_address
7+
}
8+
9+
resource "aws_lb" "this" {
10+
name = "pl-nlb-${var.environment}-${var.stage}-${var.family}"
11+
internal = true
12+
load_balancer_type = "network"
13+
subnets = var.subnet_ids
14+
enable_cross_zone_load_balancing = true
15+
16+
tags = {
17+
Environment = var.environment
18+
Stage = var.stage
19+
}
20+
}
21+
22+
resource "aws_lb_target_group" "this" {
23+
name = "pl-tg-${var.environment}-${var.stage}-${var.family}"
24+
port = var.target_port
25+
protocol = "TCP"
26+
vpc_id = var.vpc_id
27+
target_type = "ip"
28+
29+
health_check {
30+
protocol = "TCP"
31+
port = var.target_port
32+
healthy_threshold = 3
33+
unhealthy_threshold = 3
34+
interval = 30
35+
}
36+
37+
tags = {
38+
Environment = var.environment
39+
Stage = var.stage
40+
}
41+
}
42+
43+
resource "aws_lb_target_group_attachment" "this" {
44+
target_group_arn = aws_lb_target_group.this.arn
45+
target_id = data.dns_a_record_set.target.addrs[0]
46+
port = var.target_port
47+
}
48+
49+
resource "aws_lb_listener" "this" {
50+
load_balancer_arn = aws_lb.this.arn
51+
port = var.target_port
52+
protocol = "TCP"
53+
54+
default_action {
55+
type = "forward"
56+
target_group_arn = aws_lb_target_group.this.arn
57+
}
58+
}
59+
60+
resource "aws_vpc_endpoint_service" "this" {
61+
acceptance_required = false
62+
network_load_balancer_arns = [aws_lb.this.arn]
63+
64+
tags = {
65+
Name = "pl-svc-${var.environment}-${var.stage}-${var.family}"
66+
Environment = var.environment
67+
Stage = var.stage
68+
}
69+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "endpoint_service_name" {
2+
description = "Service name of the VPC Endpoint Service — pass this to the consumer module"
3+
value = aws_vpc_endpoint_service.this.service_name
4+
}
5+
6+
output "nlb_arn" {
7+
description = "ARN of the internal NLB"
8+
value = aws_lb.this.arn
9+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
variable "environment" {
2+
description = "Environment name"
3+
type = string
4+
}
5+
6+
variable "stage" {
7+
description = "Stage of deployment"
8+
type = string
9+
}
10+
11+
variable "family" {
12+
description = "Service family name for resource naming"
13+
type = string
14+
}
15+
16+
variable "vpc_id" {
17+
description = "VPC ID where the target service lives"
18+
type = string
19+
}
20+
21+
variable "subnet_ids" {
22+
description = "Subnet IDs for the NLB"
23+
type = list(string)
24+
}
25+
26+
variable "target_address" {
27+
description = "DNS address of the target service (resolved to IP for the NLB target group)"
28+
type = string
29+
}
30+
31+
variable "target_port" {
32+
description = "Port of the target service"
33+
type = number
34+
}

0 commit comments

Comments
 (0)