Search code examples
aws-lambdaterraformaws-secrets-manager

lambda error when creating function for secrets rotation using terraform


Please can you help find the solution to my problem I have tried quite a lot of google search ideas, like replaces hyphens with underscores. I have also set the vpc_config to use public subnets, it was using private perviously. I have increased timeouts from 30 to 120 to see if there was an issue there.

This is the error from my Gitlab Pipeline.

aws_lambda_function.rotate: Creating...

Error: error creating Lambda Function (1): ValidationException:

status code: 400, request id: 375b2989-c466-4f54-b951-31546121edda with aws_lambda_function.rotate,

on lambda-rotater.tf line 10, in resource "aws_lambda_function" "rotate":

10: resource "aws_lambda_function" "rotate" {

Here is the lambda terraform code.

data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_vpc" "main_vpc" {}

data "aws_subnet_ids" "public" {
  vpc_id = data.aws_vpc.main_vpc.id
  tags = {
    Name = "*public*"
  }
}

data "aws_subnet" "public_ingress_cidr" {
  for_each = data.aws_subnet_ids.public.ids
  id = each.value
}

data "archive_file" "lambda_archive" {
  type        = "zip"
  source_file = "lambda/lambda_function.py"
  output_path = "lambda/lambda_function.zip"
}

resource "aws_lambda_function" "rotate" {
  filename          = data.archive_file.lambda_archive.output_path
  function_name    = "test"
  role             = aws_iam_role.iam_for_lambda.arn
  handler          = "lambda_function.lambda_handler"
  source_code_hash = data.archive_file.lambda_archive.output_base64sha256
  runtime          = "python3.8"
  vpc_config {
    subnet_ids         = data.aws_subnet_ids.public.*.id
    security_group_ids = [aws_security_group.rotation_lambda_sg.id]
  }
  timeout     = 120
  description = "Conducts an AWS SecretsManager secret rotation for RDS using single user rotation scheme"
  environment {
    variables = {
      SECRETS_MANAGER_ENDPOINT = "s.${data.aws_region.current.name}.amazonaws.com"
    }
  }
}

resource "aws_lambda_permission" "allow_secret_manager_call_lambda" {
  function_name = aws_lambda_function.rotate.function_name
  statement_id  = "AllowExecutionSecretManager"
  action        = "lambda:InvokeFunction"
  principal     = "secretsmanager.amazonaws.com"
}

I have added the IAM's terraform code incase there is an issue there.

resource "aws_iam_role" "iam_for_lambda" {
  name = "iam_for_lambda"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "lambda-secrets" {
  role       = aws_iam_role.iam_for_lambda.name
  policy_arn = "arn:aws:iam::aws:policy/SecretsManagerReadWrite"
}

resource "aws_iam_role_policy_attachment" "lambda" {
  role       = aws_iam_role.iam_for_lambda.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

resource "aws_iam_role_policy_attachment" "lambda-vpc" {
  role       = aws_iam_role.iam_for_lambda.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}

Solution

  • Using the terraform code that you have provided, I was able to recreate the issue. I resolved the issue by doing the following:

    Change the subnet_ids configuration:

      vpc_config {
        subnet_ids         = data.aws_subnet_ids.public.*.id
        security_group_ids = [aws_security_group.rotation_lambda_sg.id]
      }
    

    to

      vpc_config {
        subnet_ids         = data.aws_subnet_ids.public.ids
        security_group_ids = [aws_security_group.rotation_lambda_sg.id]
      }
    

    The incorrect version seems to be providing the VPC ID instead of the list of subnet IDs. AWS gives a Validation Error due to incorrect parameter value.