Creating an aws_cognito_user_pool in Terraform with anything in the 'schema' causes the user pool to be recreated every time Terraform runs. We want to use custom attributes so need to set options in schema.
According to the documentation
"When defining an attribute_data_type of String or Number, the respective attribute constraints configuration block (e.g string_attribute_constraints or number_attribute_contraints) is required to prevent recreation of the Terraform resource. This requirement is true for both standard (e.g. name, email) and custom schema attributes."
If I understand this correctly, I need to list out all standard attributes in the schema too, so I can add the string_attribute_contraints.
resource "aws_cognito_user_pool" "pool" {
count = "${var.user_pool_count}"
name = "${lookup(var.user_pool[count.index], "name")}"
username_attributes = ["email"]
auto_verified_attributes = ["email"]
schema = [
{
name = "address"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "birthdate"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "email"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "family_name"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "gender"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "given_name"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "locale"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "middle_name"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "name"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "nickname"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "phone_number"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "picture"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "preferred_username"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "profile"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "zoneinfo"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
{
name = "updated_at"
attribute_data_type = "Number"
number_attribute_constraints = {
min_value = 1
}
},
{
name = "website"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
}
},
]
}
With the above example, even though I have not added any custom attributes yet, it recreates the user pool on every run.
EDIT - Added gist link to Terraform plan as it would put me over the Stackoverflow character limit.
https://gist.github.com/mehstg/6bf22a35254a168c14b98af57f86ed85
The plan output shows that most of your schema attributes are missing the max_length
constraint that is set on the schema attributes in the pool:
schema.1286155211.attribute_data_type: "" => "String" (forces new resource)
schema.1286155211.developer_only_attribute: "" => ""
schema.1286155211.mutable: "" => ""
schema.1286155211.name: "" => "locale" (forces new resource)
schema.1286155211.number_attribute_constraints.#: "" => "0"
schema.1286155211.required: "" => ""
schema.1286155211.string_attribute_constraints.#: "" => "1" (forces new resource)
schema.1286155211.string_attribute_constraints.0.max_length: "" => ""
schema.1286155211.string_attribute_constraints.0.min_length: "" => "1" (forces new resource)
...
schema.3812649078.developer_only_attribute: "false" => "false"
schema.3812649078.mutable: "false" => "false"
schema.3812649078.name: "locale" => "" (forces new resource)
schema.3812649078.number_attribute_constraints.#: "0" => "0"
schema.3812649078.required: "false" => "false"
schema.3812649078.string_attribute_constraints.#: "1" => "0" (forces new resource)
schema.3812649078.string_attribute_constraints.0.max_length: "2048" => "" (forces new resource)
schema.3812649078.string_attribute_constraints.0.min_length: "1" => "" (forces new resource)
Terraform is detecting this drift and trying to change your user pool to match your config. Unfortunately user pool schema attributes are immutable so Terraform is forced to destroy the whole user pool and create a new one.
Adding the missing constraints should fix this.
resource "aws_cognito_user_pool" "pool" {
count = var.user_pool_count
name = var.user_pool[count.index]["name"]
username_attributes = ["email"]
auto_verified_attributes = ["email"]
schema = [
# ...
{
name = "locale"
attribute_data_type = "String"
string_attribute_constraints = {
min_length = 1
max_length = 1
}
},
# ...
]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With