Skip to content

Commit 315b095

Browse files
SafouakSafouan OUAKRIM
authored andcommitted
feat: support centralised webhook proxy in multi-account deployments
When deploying runners with a centralised webhook proxy in a separate AWS account (e.g. an Ops account that validates and authorises webhook events before routing them to target accounts), three gaps force consumers to work around the module: 1. The module exclusively owns the SQS queue policy (DenyInsecureTransport only). Adding cross-account sqs:SendMessage requires overriding the whole policy, duplicating DenyInsecureTransport and causing permanent Terraform drift on every plan. 2. aws_sqs_queue_policy requires the queue URL, not the ARN. The queues output only exposed the ARN, forcing consumers to reconstruct the URL by string-splitting. 3. The webhook Lambda and API Gateway are always deployed even when the module's built-in webhook is not used (the external proxy receives GitHub events directly and publishes to SQS, bypassing the module's endpoint). Changes (root module + modules/multi-runner): - sqs_build_queue_extra_policy_json (default: null): optional policy JSON merged into the build queue policy via source_policy_documents. No-op when unset — no behaviour change for existing deployments. - build_queue_url added to the queues output (root); queues output added to modules/multi-runner exposing ARN + URL per runner key. - create_webhook_module (default: true): set to false to skip the webhook Lambda and API Gateway. The webhook output becomes null when disabled.
1 parent 1d57199 commit 315b095

7 files changed

Lines changed: 75 additions & 22 deletions

File tree

main.tf

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,16 @@ data "aws_iam_policy_document" "deny_insecure_transport" {
4848
}
4949
}
5050

51+
data "aws_iam_policy_document" "build_queue_policy" {
52+
source_policy_documents = compact([
53+
data.aws_iam_policy_document.deny_insecure_transport.json,
54+
var.sqs_build_queue_extra_policy_json,
55+
])
56+
}
57+
5158
resource "aws_sqs_queue_policy" "build_queue_policy" {
5259
queue_url = aws_sqs_queue.queued_builds.id
53-
policy = data.aws_iam_policy_document.deny_insecure_transport.json
60+
policy = data.aws_iam_policy_document.build_queue_policy.json
5461
}
5562

5663
resource "aws_sqs_queue" "queued_builds" {
@@ -97,6 +104,7 @@ module "ssm" {
97104

98105
module "webhook" {
99106
source = "./modules/webhook"
107+
count = var.create_webhook_module ? 1 : 0
100108

101109
ssm_paths = {
102110
root = local.ssm_root_path

modules/multi-runner/outputs.tf

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ output "binaries_syncer_map" {
3232
}
3333

3434
output "webhook" {
35-
value = {
36-
gateway = module.webhook.gateway
37-
lambda = module.webhook.lambda
38-
lambda_log_group = module.webhook.lambda_log_group
39-
lambda_role = module.webhook.role
40-
endpoint = "${module.webhook.gateway.api_endpoint}/${module.webhook.endpoint_relative_path}"
41-
webhook = module.webhook.webhook
42-
dispatcher = var.eventbridge.enable ? module.webhook.dispatcher : null
43-
eventbridge = var.eventbridge.enable ? module.webhook.eventbridge : null
44-
}
35+
value = var.create_webhook_module ? {
36+
gateway = module.webhook[0].gateway
37+
lambda = module.webhook[0].lambda
38+
lambda_log_group = module.webhook[0].lambda_log_group
39+
lambda_role = module.webhook[0].role
40+
endpoint = "${module.webhook[0].gateway.api_endpoint}/${module.webhook[0].endpoint_relative_path}"
41+
webhook = module.webhook[0].webhook
42+
dispatcher = var.eventbridge.enable ? module.webhook[0].dispatcher : null
43+
eventbridge = var.eventbridge.enable ? module.webhook[0].eventbridge : null
44+
} : null
4545
}
4646

4747
output "ssm_parameters" {
@@ -67,3 +67,13 @@ output "instance_termination_handler" {
6767
lambda_role = module.instance_termination_watcher[0].spot_termination_handler.lambda_role
6868
} : null
6969
}
70+
71+
output "queues" {
72+
description = "SQS build queues per runner type."
73+
value = {
74+
for key in keys(var.multi_runner_config) : key => {
75+
build_queue_arn = aws_sqs_queue.queued_builds[key].arn
76+
build_queue_url = aws_sqs_queue.queued_builds[key].url
77+
}
78+
}
79+
}

modules/multi-runner/queues.tf

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,19 @@ resource "aws_sqs_queue" "queued_builds" {
4545
tags = var.tags
4646
}
4747

48+
data "aws_iam_policy_document" "build_queue_policy" {
49+
for_each = var.multi_runner_config
50+
51+
source_policy_documents = compact([
52+
data.aws_iam_policy_document.deny_insecure_transport.json,
53+
var.sqs_build_queue_extra_policy_json,
54+
])
55+
}
56+
4857
resource "aws_sqs_queue_policy" "build_queue_policy" {
4958
for_each = var.multi_runner_config
5059
queue_url = aws_sqs_queue.queued_builds[each.key].id
51-
policy = data.aws_iam_policy_document.deny_insecure_transport.json
60+
policy = data.aws_iam_policy_document.build_queue_policy[each.key].json
5261
}
5362

5463
resource "aws_sqs_queue" "queued_builds_dlq" {

modules/multi-runner/variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,3 +770,15 @@ variable "parameter_store_tags" {
770770
type = map(string)
771771
default = {}
772772
}
773+
774+
variable "sqs_build_queue_extra_policy_json" {
775+
description = "Optional additional SQS policy statements (JSON) merged into the build queue policy for all runner types. Useful for cross-account access, e.g. allowing an SNS topic from another account to send messages."
776+
type = string
777+
default = null
778+
}
779+
780+
variable "create_webhook_module" {
781+
description = "Set to false to skip deploying the webhook Lambda and API Gateway. Use when webhook delivery is handled externally (e.g. a centralised proxy in another account)."
782+
type = bool
783+
default = true
784+
}

modules/multi-runner/webhook.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module "webhook" {
22
source = "../webhook"
3+
count = var.create_webhook_module ? 1 : 0
34
prefix = var.prefix
45
tags = local.tags
56
kms_key_arn = var.kms_key_arn

outputs.tf

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ output "binaries_syncer" {
3131
}
3232

3333
output "webhook" {
34-
value = {
35-
gateway = module.webhook.gateway
36-
lambda = module.webhook.lambda
37-
lambda_log_group = module.webhook.lambda_log_group
38-
lambda_role = module.webhook.role
39-
endpoint = "${module.webhook.gateway.api_endpoint}/${module.webhook.endpoint_relative_path}"
40-
webhook = module.webhook.webhook
41-
dispatcher = var.eventbridge.enable ? module.webhook.dispatcher : null
42-
eventbridge = var.eventbridge.enable ? module.webhook.eventbridge : null
43-
}
34+
value = var.create_webhook_module ? {
35+
gateway = module.webhook[0].gateway
36+
lambda = module.webhook[0].lambda
37+
lambda_log_group = module.webhook[0].lambda_log_group
38+
lambda_role = module.webhook[0].role
39+
endpoint = "${module.webhook[0].gateway.api_endpoint}/${module.webhook[0].endpoint_relative_path}"
40+
webhook = module.webhook[0].webhook
41+
dispatcher = var.eventbridge.enable ? module.webhook[0].dispatcher : null
42+
eventbridge = var.eventbridge.enable ? module.webhook[0].eventbridge : null
43+
} : null
4444
}
4545

4646
output "ssm_parameters" {
@@ -56,6 +56,7 @@ output "queues" {
5656
description = "SQS queues."
5757
value = {
5858
build_queue_arn = aws_sqs_queue.queued_builds.arn
59+
build_queue_url = aws_sqs_queue.queued_builds.url
5960
build_queue_dlq_arn = var.redrive_build_queue.enabled ? aws_sqs_queue.queued_builds_dlq[0].arn : null
6061
}
6162
}

variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ variable "aws_region" {
33
type = string
44
}
55

6+
variable "sqs_build_queue_extra_policy_json" {
7+
description = "Optional additional SQS policy statements (JSON) merged into the build queue policy. Useful for cross-account access, e.g. allowing an SNS topic from another account to send messages."
8+
type = string
9+
default = null
10+
}
11+
12+
variable "create_webhook_module" {
13+
description = "Set to false to skip deploying the webhook Lambda and API Gateway. Use when webhook delivery is handled externally (e.g. a centralised proxy in another account)."
14+
type = bool
15+
default = true
16+
}
17+
618
variable "vpc_id" {
719
description = "The VPC for security groups of the action runners."
820
type = string

0 commit comments

Comments
 (0)