diff --git a/fargate/manifest.yaml b/fargate/manifest.yaml index 26ff7ff..23cd088 100644 --- a/fargate/manifest.yaml +++ b/fargate/manifest.yaml @@ -31,4 +31,7 @@ inputs: security_groups: type: list(string) -outputs: {} +outputs: + http_endpoint: + type: string + description: "HTTP endpoint URL for service-to-service communication" diff --git a/fargate/module/main.tf b/fargate/module/main.tf index dbfcfcb..c974fbb 100644 --- a/fargate/module/main.tf +++ b/fargate/module/main.tf @@ -221,5 +221,17 @@ resource "aws_lb_listener_rule" "service" { } } +resource "aws_security_group_rule" "service_ingress_from_alb" { + count = length(var.suga.services) > 0 && var.alb_security_group != null ? 1 : 0 + + type = "ingress" + from_port = 80 + to_port = 80 + protocol = "tcp" + security_group_id = var.alb_security_group + self = true + description = "Allow service-to-service communication via ALB for ${var.suga.name}" +} + diff --git a/fargate/module/outputs.tf b/fargate/module/outputs.tf index e52a216..10d58cc 100644 --- a/fargate/module/outputs.tf +++ b/fargate/module/outputs.tf @@ -1,7 +1,8 @@ output "suga" { value = { - id = aws_ecs_service.service.id - domain_name = data.aws_lb.alb.dns_name + id = aws_ecs_service.service.id + domain_name = data.aws_lb.alb.dns_name + http_endpoint = "http://${data.aws_lb.alb.dns_name}/${var.suga.name}" exports = { resources = { "aws_lb" = var.alb_arn diff --git a/fargate/module/variables.tf b/fargate/module/variables.tf index 18c71a7..61a21c8 100644 --- a/fargate/module/variables.tf +++ b/fargate/module/variables.tf @@ -5,6 +5,12 @@ variable "suga" { image_id = string env = map(string) identities = map(any) + services = optional(map(object({ + actions = list(string) + identities = map(object({ + exports = map(string) + })) + })), {}) }) } diff --git a/lambda/manifest.yaml b/lambda/manifest.yaml index a66a2ef..97d457e 100644 --- a/lambda/manifest.yaml +++ b/lambda/manifest.yaml @@ -38,4 +38,7 @@ inputs: type: list(string) description: 'Security group IDs controlling network access when Lambda runs in VPC. Must be used with subnet_ids - both provided for VPC deployment or both empty for internet-only Lambda. Configure outbound rules for database, API, or service access (e.g. `["sg-lambda-rds", "sg-lambda-redis"]`)' -outputs: {} +outputs: + http_endpoint: + type: string + description: "HTTP endpoint URL for service-to-service communication" diff --git a/lambda/module/main.tf b/lambda/module/main.tf index f181910..d7418d5 100644 --- a/lambda/module/main.tf +++ b/lambda/module/main.tf @@ -117,6 +117,39 @@ resource "aws_lambda_function_url" "endpoint" { # } } +resource "aws_iam_policy" "service_callers" { + for_each = var.suga.services + + name = "${local.lambda_name}-caller-${each.key}" + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = "lambda:InvokeFunctionUrl" + Resource = aws_lambda_function_url.endpoint.function_arn + } + ] + }) +} + +resource "aws_iam_role_policy_attachment" "service_callers" { + for_each = var.suga.services + + role = each.value.identities["aws:iam:role"].exports["aws_iam_role:name"] + policy_arn = aws_iam_policy.service_callers[each.key].arn +} + +resource "aws_lambda_permission" "service_invokers" { + for_each = var.suga.services + + statement_id = "AllowInvokeFrom${replace(each.key, "-", "")}" + action = "lambda:InvokeFunctionUrl" + function_name = aws_lambda_function.function.function_name + principal = each.value.identities["aws:iam:role"].exports["aws_iam_role:arn"] +} + # Create role and policy to allow schedule to invoke lambda resource "aws_iam_role" "role" { assume_role_policy = jsonencode({ diff --git a/lambda/module/outputs.tf b/lambda/module/outputs.tf index d6f8c4e..159fae9 100644 --- a/lambda/module/outputs.tf +++ b/lambda/module/outputs.tf @@ -1,7 +1,8 @@ output "suga" { value = { - id = aws_lambda_function.function.arn - domain_name = split("/", aws_lambda_function_url.endpoint.function_url)[2] + id = aws_lambda_function.function.arn + domain_name = split("/", aws_lambda_function_url.endpoint.function_url)[2] + http_endpoint = aws_lambda_function_url.endpoint.function_url exports = { resources = { "aws_lambda_function" = aws_lambda_function.function.arn diff --git a/lambda/module/variables.tf b/lambda/module/variables.tf index 105985b..e563f95 100644 --- a/lambda/module/variables.tf +++ b/lambda/module/variables.tf @@ -11,6 +11,12 @@ variable "suga" { identities = map(object({ exports = map(string) })) + services = optional(map(object({ + actions = list(string) + identities = map(object({ + exports = map(string) + })) + })), {}) }) }