Search code examples
pythonamazon-web-servicesaws-lambdaterraform

Terraform Lambda Invocation


I want to bootstrap a new RDS cluster with a user and password while it's being instantiated by Terraform.

I've created a Lambda and successfully configured a cluster with hardcoded variables. Here's the Python:

import boto3
import psycopg2

user = ""
password = ""
host = ""
database = ""
role_user = ""
role_passwd = ""

def lambda_handler(event, context):
  connection = psycopg2.connect(f"user={user} password={password} host={host} dbname={database} port=5432")
  cursor = connection.cursor()
  cursor.execute(f"CREATE ROLE {role_user} WITH PASSWORD {role_passwd} CREATEDB CREATEROLE LOGIN ;")
  cursor.execute(f"GRANT rds_superuser TO {role_user} ;")
  print('Password applied')

I want to use Terraform's 'aws_lambda_invocation' resource to inject the variables and I thought the code below would do the trick, but I am wrong.

resource "aws_lambda_invocation" "this" {
  function_name = aws_lambda_function.this.function_name
  input         = jsonencode({
    user        = jsondecode(data.aws_secretsmanager_secret_version.rds.secret_string)["username"]
    password    = jsondecode(data.aws_secretsmanager_secret_version.rds.secret_string)["password"]
    host        = data.aws_rds_cluster.this.endpoint
    database    = "postgres"
    role_user   = jsondecode(data.aws_secretsmanager_secret_version.role.secret_string)["username"]
    role_passwd = jsondecode(data.aws_secretsmanager_secret_version.role.secret_string)["password"]   
  })
}

I'm getting this error:

Error: invoking Lambda Function (bootstrap-modeler-hbmy-mct-joc-eu-west-1-dev): {"errorMessage": "name 'user' is not defined", "errorType": "NameError",

I'm new to Lambda and hoping there's something dumb I'm missing that you can help me with.


Solution

  • That's not how AWS Lambda functions work. The input to an AWS Lambda function doesn't directly update variables inside the Lambda function's source code. Any input like that will be made available to the Lambda function invocation as attributes on the event object that is passed into the Lambda hander.

    I suggest printing the event object in your Lambda function, and then examining that in CloudWatch Logs to see exactly how you will need to access those values in your code.