Search code examples
amazon-web-servicesterraformterraform-provider-aws

Python AWS Lambda throwing endpoint request timed out when tested via API Gateway


I have created an AWS Lambda function for my Python module using the below Terraform code:

resource "aws_lambda_function" "api_lambda" {
  function_name = local.lambda_name
  timeout       = 300
  image_uri     = "${local.account_id}.dkr.ecr.eu-west-1.amazonaws.com/workload-dbt:latest"
  package_type  = "Image"
  architectures = ["x86_64"]
  memory_size   = 1024
  role          = aws_iam_role.api_lambda_role.arn
    
  vpc_config {
    security_group_ids = [aws_security_group.security_group_for_lambda.id]
        subnet_ids         = var.subnet_ids
  }
    
  environment {
    variables = {
       gitlab_username     = var.gitlab_username
       gitlab_access_token = var.gitlab_access_token
    }
  }
}

data "aws_vpc" "selected_vpc" {
  id = var.vpc_id
}


resource "aws_security_group" "security_group_for_lambda" {
  name        = "Security group for lambda"
  description = "Security group for lambda within the vpc"

  vpc_id = var.vpc_id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [data.aws_vpc.selected_vpc.cidr_block]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = [data.aws_vpc.selected_vpc.cidr_block]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}


# Lambda Permissions
resource "aws_lambda_permission" "api_gateway_call_async_lambda_permission" {
  statement_id  = "AllowAPIGatewayInvokeLambda"
  action        = "lambda:InvokeFunction"
  principal     = "apigateway.amazonaws.com"
  function_name = aws_lambda_function.api_lambda.function_name
  source_arn    = "${aws_api_gateway_rest_api.rest_api.execution_arn}/*/*"
}

When tested via API Gateway I get the below error:

{"message": "Endpoint request timed out"} 

I also tried increasing the timeout and memory as can be seen in the terraform code. I have also checked that it has been tagged to the correct VPC Id and subnets and also the outbound rule for destination of security group is 0.0.0.0/0.

What else am I missing here?


Solution

  • In your earlier comments, you mentioned:

    I have also checked my subnet id, where I can see 4 route tables attached to that ID where one destination is 0.0.0.0/0 and target is IGW (Internet gateway)

    The fact that your Lambda function's subnet's default route is the IGW tells me that you have connected the Lambda function to a public subnet of your VPC. Public subnets are, by definition, those subnets whose default route is an IGW.

    It should, however, be connected to a private subnet. See Why can't an AWS Lambda function in a public subnet connect to the internet? for why that is. You will also need NAT (or NAT Gateway), which I presume you already have or can easily add.

    So, basically, you should connect the Lambda to a private subnet and include a NAT or NAT Gateway in your infrastructure.

    Also note that best practices recommend that you configure at least 2 private subnets, each in a different Availability Zone (AZ), and configure the Lambda function to connect to 2+ private subnets. That will give you some resilience to AZ failures.