4

I have a cyclic dependency problem with terraform. I have a user pool user_pool which invokes a lambda user_signup_lambda as a trigger when a user signs up. This lambda also needs the user pool's Id as an environment variable.

My terraform looks like this

resource "aws_lambda_function" "user_signup_lambda" {
  function_name = "user_signup_lambda"
  filename = var.file_name
  source_code_hash = filebase64sha256(var.file_name)
  handler = var.handler
  runtime = var.runtime
  memory_size = var.memory_size
  timeout = var.timeout
  role = var.iam_role_arn

  environment {
    variables = aws_cognito_user_pool.user_pool.id
  }
}

resource "aws_cognito_user_pool" "user_pool" {
  name = "some-user-pool"

  ....other config

  lambda_config {
     post_confirmation = module.user_signup_lambda.arn
  }

This results in the following error:

Error: Cycle: module.user_signup_lambda.var.environment_variables, module.user_signup_lambda.aws_lambda_function.lambda_function, module.user_signup_lambda.output.arn, aws_cognito_user_pool.user_pool

Is there anyway around this other than hardcoding the user pool id?

Joshua Smart
  • 61
  • 1
  • 3
  • 3
    Why do you need the pass the user pool ID? The event object should already have the `userPoolId` in it that you can read from there instead. https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-post-authentication.html#aws-lambda-triggers-post-authentication-example has an example Lambda function and an example event input. – ydaetskcoR Jun 08 '20 at 12:41
  • You're right...I can do it this way. My bad! thanks! However is there a way around this problem anyway if it wasn't possible to get it from the request? – Joshua Smart Jun 08 '20 at 13:48
  • The issue is that there is a clear dependency both ways on these. If you separated the Lambda function and the Cognito user pool from each other so they were applied separately then you could do it by either hardcoding the ARN/ID of one into the other or looking the other up with data sources. There's not a way of doing it in the same `apply` though. – ydaetskcoR Jun 08 '20 at 13:54
  • I found this: https://www.integralist.co.uk/posts/cognito/ in the terraform example the author addresses the exact same issue we face. – MattBH Jul 27 '22 at 11:49

2 Answers2

4

We had the exact same issue. We ended up passing a variable containing the UserPool Name to Both UserPool and Lambda trigger resources.

The lambda then fetches the Cognito user pool info from it's name.

This way there is no cycle dependency between those 2 resources.

# Module containing Cognito userPool
resource "aws_cognito_user_pool" "default" {

 ...
  # Triggers
  lambda_config {
    post_confirmation = module.cognito_post_confirmation.lambda_post_confirmation.arn
  }
  name = var.cognito_identity_pool_name
} 


module "cognito_post_confirmation" {
  source                     = "./triggers/post-confirmation"
  cognito_identity_pool_name = var.cognito_identity_pool_name
  ...
}
Sebastien H.
  • 6,818
  • 2
  • 28
  • 36
0

Have you considered using the event payload? It looks like this.

{ 
  version: '1',
  userPoolId: 'ap-southeast-BLABLA',
}

The event itself has the userPoolId. If you're using this, there is no need to have an environment variable.