terraform-provider-aws: Cognito User Pool: cannot modify or remove schema items

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave “+1” or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform CLI and Terraform AWS Provider Version

Terraform v1.0.6 AWS provider 3.63.0

Affected Resource(s)

  • aws_cognito_user_pool

Terraform Configuration Files

resource "aws_cognito_user_pool" "pool" {
  name = "${local.project_name}_user_pool"

  mfa_configuration = "OFF" # todo change later to OPTIONAL

  lambda_config {
    post_authentication = aws_lambda_function.post_authentication.arn
  }

  auto_verified_attributes = [
    "email",
    # "phone_number",
  ]

  username_attributes = ["email"]

  password_policy {
    minimum_length    = 8
    require_lowercase = true
    require_numbers   = true
    require_symbols   = true
    require_uppercase = true
  }

  schema {
    name                = "email"
    attribute_data_type = "String"
    mutable             = false
    required            = true
  }
  schema {
    name                = "phone"
    attribute_data_type = "String"
    mutable             = false
    required            = false
  }
}

resource "aws_cognito_user_pool_client" "client" {
  name = "${local.project_name}_user_pool_client"

  user_pool_id = aws_cognito_user_pool.pool.id

  allowed_oauth_flows                  = ["implicit"]
  allowed_oauth_flows_user_pool_client = true
  allowed_oauth_scopes                 = ["email", "openid"]

  logout_urls   = ["https://${local.domain}"]
  callback_urls = ["https://${local.domain}"]

  supported_identity_providers = ["COGNITO"]
}

Expected Behavior

Actual Behavior

  # aws_cognito_user_pool.pool will be updated in-place
  ~ resource "aws_cognito_user_pool" "pool" {
        id                        = "eu-central-1_xxx"
        name                      = "intocourse_user_pool"
        tags                      = {}
        # (9 unchanged attributes hidden)




      ~ password_policy {
          - temporary_password_validity_days = 7 -> null
            # (5 unchanged attributes hidden)
        }

      - schema {
          - attribute_data_type      = "String" -> null
          - developer_only_attribute = false -> null
          - mutable                  = false -> null
          - name                     = "email" -> null
          - required                 = true -> null

          - string_attribute_constraints {
              - max_length = "2048" -> null
              - min_length = "0" -> null
            }
        }
      - schema {
          - attribute_data_type      = "String" -> null
          - developer_only_attribute = false -> null
          - mutable                  = false -> null
          - name                     = "phone" -> null
          - required                 = false -> null

          - string_attribute_constraints {}
        }
      + schema {
          + attribute_data_type = "String"
          + mutable             = false
          + name                = "email"
          + required            = true
        }
      + schema {
          + attribute_data_type = "String"
          + mutable             = false
          + name                = "phone"
          + required            = false
        }
      + schema {
        }

        # (4 unchanged blocks hidden)
    }

...

aws_cognito_user_pool.pool: Modifying... [id=eu-central-1_xxx]
â•·
│ Error: error updating Cognito User Pool (eu-central-1_xxx): cannot modify or remove schema items
│ 
│   with aws_cognito_user_pool.pool,
│   on cognito.tf line 1, in resource "aws_cognito_user_pool" "pool":
│    1: resource "aws_cognito_user_pool" "pool" {
│ 
╵

Steps to Reproduce

  1. terraform apply

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 106
  • Comments: 22 (1 by maintainers)

Most upvoted comments

The solution to this problem is to add a string_attribute_constraints block with min_length and max_length:

resource "aws_cognito_user_pool" "pool" {
  name = "${local.project_name}_user_pool"

  mfa_configuration = "OFF" # todo change later to OPTIONAL

  lambda_config {
    post_authentication = aws_lambda_function.post_authentication.arn
  }

  auto_verified_attributes = [
    "email",
    # "phone_number",
  ]

  username_attributes = ["email"]

  password_policy {
    minimum_length = 8
    require_lowercase = true
    require_numbers = true
    require_symbols = true
    require_uppercase = true
  }

  schema {
    name = "email"
    attribute_data_type = "String"
    mutable = false
    required = true

    string_attribute_constraints {
      min_length = 1
      max_length = 256
    }
  }

  schema {
    name = "phone"
    attribute_data_type = "String"
    mutable = false
    required = false

    string_attribute_constraints {
      min_length = 1
      max_length = 256
    }
  }
}

the same issue with terraform 0.13.6 and aws provider 3.37.0 my case is applying the following change:

      - schema {
          - attribute_data_type      = "String" -> null
          - developer_only_attribute = false -> null
          - mutable                  = true -> null
          - name                     = "group" -> null
          - required                 = false -> null

          - string_attribute_constraints {
              - max_length = "1024" -> null
              - min_length = "1" -> null
            }
        }
      + schema {
          + attribute_data_type      = "String"
          + developer_only_attribute = false
          + mutable                  = true
          + name                     = "group"
          + required                 = false

          + string_attribute_constraints {
              + max_length = "4096"
              + min_length = "1"
            }
        }

the same issue with terraform 0.13.6 and aws provider 3.70.0

@lsacco-nutreense It looks like in the AWS console one can add schema attributes without replacing the pool; but one cannot modify or remove attributes.

So the correct behavior should be to update the aws_cognito_user_pool resource when adding a new schema attribute, and to trigger replacement of the resource when removing or modifying a schema attribute.

This is an Issue with AWS Cognito User Pools itself. You cannot change or modify standard attributes after user-pool creation. See their docs -> long story short -> not possible. Especially with App-Clients being already registered or a SAML App using the User Pool ID for the SAML Entity ID its a “pain” and is STILL not being addressed properly by AWS (My change was to change email to muteable after registering a SAML provider). In an corporate environment where you can’t manage SAML Apps yourself and already using app-clients and changes to a schema can happen from time to time, its honestly a reason to rethink the decision to use AWS Cognito.

For the Terraform Provider it means it’s correct to recreate the user pool rather than suggesting an attribute can be replaced during plan phase (which just adds up to the overall confusion). Anyone aware of an issue regarding the general AWS Cognito Behaviour?

Resources could be created with both min and max null on string_attribute_constraints on custom fields, AWS defaults values to 0 and 256 on their side. The problem is, once they are created that way, the are permanently null in states, even if the AWS interface show 0 min and 256 max. Since they are immutable, they can’t be fixed with new string_attribute_constraints after they are deployed.

That is my current problem, I created with empty string_attribute_constraints so both min and max were blank, and even though AWS used defaults of 0 and 256, terraform state reader still reads them as null, forever causing problems when apply other resources or adding new fields because planning doesn’t like null.

I tried re-importing, still reads as null on both min and max. Is there no way to avoid this problem caused by null string_attribute_constraints arguments?

If you dont care about the changes suggested by terraform like in my case, you can simply ignore them by adding this to your resource block:

lifecycle {

    ignore_changes = [
      password_policy,
      schema
    ]
  }

@jmcvetta that shouldn’t be the correct behavior IMHO. You can go to an existing pool in the console and add attributes without replacing the pool. If you replace the pool, then the ID would change which would cause problems downstream for us, since that’s how we bind to it.

Same issue with Terraform v1.3.1 + AWS Provider v4.24.0.

Correct behavior should be to trigger replacement of aws_cognito_user_pool resource upon modification of its schema attributes.

Please read the community notes and stop commenting with +1:

Please do not leave “+1” or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request