hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.74k stars 9.09k forks source link

Delay adding the lambda to cognito user pool until after provisioners have run #9358

Open nikvaessen opened 5 years ago

nikvaessen commented 5 years ago

Community Note

Description

I'm struggling with finding a good way to add users to a (newly created) cognito user pool.

The only way right now (as far as I'm aware) is to add a provision block which executes a script using one of the cognito SDK's.

However, if you have added a pre_sign_up lambda which restricts users from signing up, the provisioning script method could fail. If the lambda's would be added after provisioning, this would not be the case.

One solution would be to have the option to explicitly add users to a user pool, as requested in #4542.

Another solution would be to have an aws_cognito_user_pool_lambda resource, similar to aws_cognito_user_group. As this would (implicitly) depend on the aws_cognito_user_pool the provisioning step would execute before the lambda is added.

A third solution would be to have an optional argument to the aws_cognito_user_pool which delays adding the lambda until after provisioning has run. Not sure if this is possible the way terraform works internally.

New or Affected Resource(s)

Potential Terraform Configuration

option 1

resource "aws_cognito_user_pool" "example" {
  name = "userpool"

  lambda_config {
    pre_sign_up = aws_lambda_function.cognito_pre_signup_lambda.arn
  }
}

resource "aws_lambda_function" "cognito_pre_signup_lambda" {
  filename         = "pre-signup.zip"
  function_name    = "cognito-pre-signup"
  role             = aws_iam_role.iam_lambda.arn
  handler          = "index.handler"
  source_code_hash = filebase64sha256("pre-signup.zip")
  runtime          = "nodejs10.x"
}

resource "aws_cognito_user" "user1" {
  pool = aws_cognito_user_pool.main.id

  username = "xxx"
  password = "yyy"
  phone    = "+1 zzzzzzzzzzz"
}

option 2

resource "aws_cognito_user_pool" "example" {
  name = "userpool"
}

resource "aws_lambda_function" "cognito_pre_signup_lambda" {
  filename         = "pre-signup.zip"
  function_name    = "cognito-pre-signup"
  role             = aws_iam_role.iam_lambda.arn
  handler          = "index.handler"
  source_code_hash = filebase64sha256("pre-signup.zip")
  runtime          = "nodejs10.x"
}

resource "aws_cognito_user_pool_lambda" "user1" {
  pool = aws_cognito_user_pool.main.id

  trigger = "pre-signup"
  lambda  = aws_lambda_function.cognito_pre_signup_lambda.arn
}

option 3

resource "aws_cognito_user_pool" "example" {
  name = "userpool"

  lambda_config {
    pre_sign_up = aws_lambda_function.cognito_pre_signup_lambda.arn
    add_after_provisioning = true
  }
}

resource "aws_lambda_function" "cognito_pre_signup_lambda" {
  filename         = "pre-signup.zip"
  function_name    = "cognito-pre-signup"
  role             = aws_iam_role.iam_lambda.arn
  handler          = "index.handler"
  source_code_hash = filebase64sha256("pre-signup.zip")
  runtime          = "nodejs10.x"
}

References

dansimau commented 3 years ago

I have run into a second use case that requires the lambdas to be configured after the pool is initially created:

I can't achieve the above because it creates a dependency cycle (see also: https://github.com/hashicorp/terraform/issues/27188).

This cycle issue would be solved using the option 2 design proposed by @nikvaessen.

dennisameling commented 1 year ago

Option 2 would also fix our use case. We have the following three resources:

  lambda_config {
    pre_token_generation = aws_lambda_function.token_generation_lambda.arn
  }