2

I'm able to create Instances, Target Groups, and ALBs just fine with Terraform, but am getting stuck when trying to use Lambda Functions. It looks like the Lambda function gets created OK along with an ALB and a Target Group, but fails on the step when attaching the Lambda function to the target group.

resource "aws_lambda_function" "LAMBDA_FUNCTION" {
  filename         = "../my_function.zip"
  function_name    = "my_function"
  role             = aws_iam_role.LAMBDA_ROLE.arn
  handler          = "my_function.lambda_handler"
  runtime          = "python3.8"
  memory_size      = 128
  description      = "My Lambda Function"
}
resource "aws_lb_target_group" "LB_TG" {
  name                               = "${local.env}-tg"
  target_type                        = "lambda"
  lambda_multi_value_headers_enabled = false
}
resource "aws_lb_target_group_attachment" "TG_ATTACHMENT" {
  target_group_arn        = aws_lb_target_group.LB_TG.arn
  target_id               = aws_lambda_function.LAMBDA_FUNCTION.arn
}

Error message when running terraform apply:

Error: Error registering targets with target group: AccessDenied: elasticloadbalancing principal does not have permission to invoke arn:aws:lambda:us-west-1:694058713236:function:my_function from target group arn:aws:elasticloadbalancing:us-west-1:694058713236:targetgroup/test-tg/9da892faefbe02b7
    status code: 403, request id: d13c36ed-2513-4d4c-97d0-2e449be859a1

From what I can gather, I'm missing a step where I specifically give permission to either the Target Group or the Lambda function to associate with one another.

John Heyer
  • 211
  • 1
  • 3
  • 10

2 Answers2

1

There are two additional resources needed for this to work:

Much thanks to this blog post

John Heyer
  • 211
  • 1
  • 3
  • 10
0

I encountered a similar issue:

This answer might not been the best. I tried a lot of options, but none worked.

I had set up the following modules:

Create Lambda Function

module "lambda_function_infra_lambda_app" {
  source = "../../../../modules/aws/lambda-function"

  function_name          = var.function_name.ila
  function_role          = local.lambda_role_arn
  function_architectures = var.function_architectures
  function_description   = var.function_description.ila
  function_handler       = var.function_handler.index
  function_memory_size   = var.function_memory_size
  function_package_type  = var.function_package_type.zip
  function_s3_bucket     = var.function_s3_bucket
  function_s3_key        = var.function_s3_key.ila
  function_image_uri     = null
  function_timeout       = var.function_timeout
  function_publish       = var.function_publish
  function_runtime       = var.function_runtime.node16
  # environment variables are updated only from the deployment pipeline
  environment_variables         = var.environment_variables
  vpc_config_subnet_ids         = [data.aws_subnets.public.ids[0], data.aws_subnets.public.ids[1], data.aws_subnets.public.ids[2]]
  vpc_config_security_group_ids = [data.aws_security_groups.lambda_functions.ids[0]]
  tag_environment               = local.tag_environment
  tag_terraform                 = local.tag_terraform.true
}

Create Lambda triggers/permissions

module "lambda_permission_infra_lambda_app" {
  source = "../../../../modules/aws/lambda-permission"

  lambda_permission_statement_id = var.lambda_permission_statement_id.lb
  lambda_permission_action       = var.lambda_permission_action.invoke
  function_name                  = var.function_name.ila
  lambda_permission_principal    = var.lambda_permission_principal.lb
  lambda_permission_source_arn   = data.aws_lb.prod_alb_public_1.id
  lambda_permission_qualifier    = null

  depends_on = [
    module.lambda_function_infra_lambda_app
  ]
}

Create Load balancer target groups

module "lb_target_group_infra_lambda_app" {
  source = "../../../../modules/aws/lb-target-group"

  lb_target_group_name     = var.lb_target_group_name.ila
  lb_target_group_port     = var.lb_target_group_port.80
  lb_target_group_protocol = var.lb_target_group_protocol.http
  lb_target_type           = var.lb_target_type.lambda
  vpc_id                   = local.vpc_id
  connection_termination   = var.connection_termination
  deregistration_delay     = var.deregistration_delay
  protocol_version         = var.protocol_version
  proxy_protocol_v2        = var.proxy_protocol_v2
  slow_start               = var.slow_start
  health_check_enabled     = var.health_check_enabled.true
  healthy_threshold        = var.healthy_threshold
  health_check_interval    = var.health_check_interval.300
  health_check_path        = var.health_check_path.root
  health_check_port        = null
  health_check_protocol    = var.health_check_protocol
  health_check_timeout     = var.health_check_timeout.5
  unhealthy_threshold      = var.unhealthy_threshold
  tag_environment          = local.tag_environment
  tag_terraform            = local.tag_terraform.true
  tag_application          = local.tag_application.ecs
}

Create Load balancer target group attachments

module "lb_target_group_attachment_infra_lambda_app" {
  source = "../../../../modules/aws/lb-target-group-attachment"

  target_group_arn                = module.lb_target_group_infra_lambda_app.lb_target_group_arn
  target_id                       = data.aws_lambda_function.infra_lambda_app.arn
  lb_target_group_attachment_port = null
  availability_zone               = null

  depends_on = [module.lb_target_group_infra_lambda_app]
}

But when run this I get the following error below for the Create Load balancer target group attachments:

│ Error: Error registering targets with target group: AccessDenied: elasticloadbalancing principal does not have permission to invoke arn:aws:lambda:eu-west-1:230835587296:function:infra-lambda-app from target group arn:aws:elasticloadbalancing:eu-west-1:230835587296:targetgroup/infra-lambda-app/f35dfb6543a30220 │ status code: 403, request id: fe5cffaf-a58b-46ba-996e-fg15bc4124a1 │ │ with module.lb_target_group_attachment_infra_lambda_app.aws_lb_target_group_attachment.main, │ on ../../../../modules/aws/lb-target-group-attachment/main.tf line 1, in resource "aws_lb_target_group_attachment" "main": │ 1: resource "aws_lb_target_group_attachment" "main" {

Other modules got applied successfully except the last one.

Here's how I solved it:

All I had to do was go register the target manually on the AWS Console:

Go to EC2 > Target Groups > the target group > Register target > Select specific lambda function

Afterwhich, I could register the lambda target using Terraform. I also deregistered the target from the Target group, and tried again with Terraform and it still worked fine for that specific Target group and the specific Lambda function.

Promise Preston
  • 223
  • 3
  • 10