lgallard / terraform-aws-cognito-user-pool

Terraform module to create Amazon Cognito User Pools, configure its attributes and resources such as app clients, domain, resource servers. Amazon Cognito User Pools provide a secure user directory that scales to hundreds of millions of users.
Apache License 2.0
93 stars 99 forks source link

device_configuration block not respected #158

Open adamwshero opened 2 weeks ago

adamwshero commented 2 weeks ago

Description

When using the device_configuration code block, the values are not respected. Additionally, Terraform believes the current values have not been set and believes they are changes. But when applying Terraform, the existing values get reversed.

Versions

Reproduction Code

locals {
  external_deps  = read_terragrunt_config(find_in_parent_folders("external-deps.hcl"))
  common_vars    = read_terragrunt_config(find_in_parent_folders("common.hcl"))
  account_vars   = read_terragrunt_config(find_in_parent_folders("account.hcl"))
  region_vars    = read_terragrunt_config(find_in_parent_folders("region.hcl"))
  product_vars   = read_terragrunt_config(find_in_parent_folders("product.hcl"))
  env_vars       = read_terragrunt_config(find_in_parent_folders("env.hcl"))
  namespace_vars = read_terragrunt_config(find_in_parent_folders("namespace.hcl"))
  namespace      = local.namespace_vars.locals.namespace
  product        = local.product_vars.locals.product_name
  prefix         = local.product_vars.locals.prefix
  env            = local.env_vars.locals.env
  idp_provider   = "Company"
  tags = merge(
    local.env_vars.locals.tags,
    local.additional_tags
  )
  additional_tags = {
  }
}

include {
  path = find_in_parent_folders()
}

dependency "kms" {
  config_path = "../../../../kms/devops"
}

terraform {
  source = "git::git@github.com:lgallard/terraform-aws-cognito-user-pool.git//.?ref=0.30.0" // Do not go higher than 0.30.0 as it currently breaks device configuration
}

inputs = {
  user_pool_name             = "${local.product}-private-auth-${local.namespace}"
  username_attributes        = ["email"]
  auto_verified_attributes   = ["email"]
  sms_authentication_message = "Your username is {username} and temporary password is {####}."
  sms_verification_message   = "This is the verification message {####}."
  deletion_protection        = "INACTIVE" // Must be inactive before deleting the pool

  mfa_configuration = "OPTIONAL"
  software_token_mfa_configuration = {
    enabled = true
  }

  admin_create_user_config = {
    email_message = "Dear {username}, your verification code is {####}."
    email_subject = "Your verification code."
    sms_message   = "Your username is {username} and temporary password is {####}."
  }

  device_configuration = {
    challenge_required_on_new_device      = false
    device_only_remembered_on_user_prompt = false
  }

  email_configuration = {
    email_sending_account = "COGNITO_DEFAULT"
  }

  password_policy = {
    minimum_length                   = 8
    require_lowercase                = true
    require_numbers                  = true
    require_symbols                  = true
    require_uppercase                = false
    temporary_password_validity_days = 7
  }

  user_pool_add_ons = {
    advanced_security_mode = "ENFORCED"
  }

  verification_message_template = {
    default_email_option = "CONFIRM_WITH_CODE"
  }

  string_schemas = [
    {
      attribute_data_type      = "String"
      developer_only_attribute = false
      mutable                  = true
      name                     = "email"
      required                 = true

      string_attribute_constraints = {
        min_length = 0
        max_length = 2048
      }
    }
  ]

  verification_message_template = {
    default_email_option = "CONFIRM_WITH_CODE"
    email_message        = "Your verification code is {####}. "
    email_subject        = "Your verification code"
    sms_message          = "Your verification code is {####}. "
  }

  // COGNITO  DOMAIN
  domain = "${local.product}-private-auth-${local.namespace}"

  // COGNITO CLIENTS
  clients = [
    {
      name                                 = "company-employee"
      allowed_oauth_flows                  = ["code", "implicit"]
      allowed_oauth_flows_user_pool_client = true
      allowed_oauth_scopes                 = ["aws.cognito.signin.user.admin", "email", "openid", "phone", "profile"]
      callback_urls = [
        "https://portal.company.com",
        "https://portal.company.com/auth/sso",
        "https://company.com/_auth/login",
        "https://company.com/oauth2/authorize/validation",
        "https://company.com/oauth2/authorize/callback",
        "https://www.company.com/oauth2/authorize/login",
        "https://www.company.com//oauth2/authorize/validation",
        "https://www.company.com//oauth2/authorize/callback"
      ]
      default_redirect_uri = "https://portal.company.com"
      explicit_auth_flows = [
        "ALLOW_CUSTOM_AUTH",
        "ALLOW_REFRESH_TOKEN_AUTH",
        "ALLOW_USER_SRP_AUTH",
        "ALLOW_ADMIN_USER_PASSWORD_AUTH"
      ]
      generate_secret = true
      logout_urls = [
        "https://portal.company.com/logout",
        "https://www.company.com/oauth2/authorize/login"
      ]
      read_attributes = ["email"]
      supported_identity_providers = [
        local.idp_provider,
        "COGNITO"
      ]
      write_attributes       = ["email"]
      access_token_validity  = 8
      id_token_validity      = 8
      refresh_token_validity = 30
      token_validity_units = {
        access_token  = "hours"
        id_token      = "hours"
        refresh_token = "days"
      }
    }
  ]

  // USER GROUP
  user_groups = [
    {
      name        = "Internal"
      description = "User group for internal users."
    }
  ]
}

Steps to reproduce the behavior:

Are you using workspaces?

No

Have you cleared the local cache?

Yes

List steps in order that led up to the issue you encountered

Update module release version from 0.22.0 to 0.32.0

Expected behavior

Terraform plan is clean, no changes except to additional outputs.

Actual behavior

Terraform believes the cognito pool has changed. Specifically the device_configuration code block indicates that challenge_required_on_new_device = false and device_only_remembered_on_user_prompt = false have not already been set and indicates they are new additions to the state.

Terminal Output Screenshot(s)

19:23:45.156 INFO   Downloading Terraform configurations from git::ssh://git@github.com/lgallard/terraform-aws-cognito-user-pool.git?ref=0.32.0 into ./.terragrunt-cache/tGkGequ8IAuRcK6PJi1bfX7QuOI/WG_s9iL0qo433IkacVEDiaWEY3w
19:23:47.970 STDOUT terraform: Initializing the backend...
19:23:48.508 STDOUT terraform: 
19:23:48.508 STDOUT terraform: Successfully configured the backend "s3"! Terraform will automatically
19:23:48.508 STDOUT terraform: use this backend unless the backend configuration changes.
19:23:48.947 STDOUT terraform: Initializing provider plugins...
19:23:48.947 STDOUT terraform: - Finding hashicorp/aws versions matching ">= 5.5.0, < 6.0.0"...
19:23:49.827 STDOUT terraform: - Installing hashicorp/aws v5.76.0...
19:23:56.365 STDOUT terraform: - Installed hashicorp/aws v5.76.0 (signed by HashiCorp)
19:23:56.368 STDOUT terraform: Terraform has created a lock file .terraform.lock.hcl to record the provider
19:23:56.368 STDOUT terraform: selections it made above. Include this file in your version control repository
19:23:56.368 STDOUT terraform: so that Terraform can guarantee to make the same selections by default when
19:23:56.368 STDOUT terraform: you run "terraform init" in the future.
19:23:56.368 STDOUT terraform: Terraform has been successfully initialized!
19:23:56.368 STDOUT terraform: 
19:23:56.368 STDOUT terraform: You may now begin working with Terraform. Try running "terraform plan" to see
19:23:56.368 STDOUT terraform: any changes that are required for your infrastructure. All Terraform commands
19:23:56.368 STDOUT terraform: should now work.
19:23:56.368 STDOUT terraform: If you ever set or change modules or backend configuration for Terraform,
19:23:56.368 STDOUT terraform: rerun this command to reinitialize your working directory. If you forget, other
19:23:56.368 STDOUT terraform: commands will detect it and remind you to do so if necessary.
19:24:05.524 STDOUT terraform: aws_cognito_user_pool.pool[0]: Refreshing state... [id=us-east-1_0RdemNajx]
19:24:06.040 STDOUT terraform: aws_cognito_user_pool_domain.domain[0]: Refreshing state... [id=company-private-auth-prod]
19:24:06.040 STDOUT terraform: aws_cognito_user_group.main[0]: Refreshing state... [id=us-east-1_0RdemNajx/Company-Internal]
19:24:06.040 STDOUT terraform: aws_cognito_identity_provider.identity_provider[0]: Refreshing state... [id=us-east-1_0RdemNajx:Company]
19:24:06.179 STDOUT terraform: aws_cognito_user_pool_client.client[0]: Refreshing state... [id=1h2lpep2qhsrom7nlf09ji0mgk]
19:24:06.405 STDOUT terraform: Terraform used the selected providers to generate the following execution
19:24:06.405 STDOUT terraform: plan. Resource actions are indicated with the following symbols:
19:24:06.405 STDOUT terraform:   ~ update in-place
19:24:06.405 STDOUT terraform: Terraform will perform the following actions:
19:24:06.405 STDOUT terraform:   # aws_cognito_identity_provider.identity_provider[0] will be updated in-place
19:24:06.405 STDOUT terraform:   ~ resource "aws_cognito_identity_provider" "identity_provider" {
19:24:06.405 STDOUT terraform:         id                = "us-east-1_0RdemAaaa:Company"
19:24:06.405 STDOUT terraform:       ~ provider_details  = (sensitive value)
19:24:06.405 STDOUT terraform:         # (5 unchanged attributes hidden)
19:24:06.405 STDOUT terraform:     }
19:24:06.405 STDOUT terraform:   # aws_cognito_user_pool.pool[0] will be updated in-place
19:24:06.405 STDOUT terraform:   ~ resource "aws_cognito_user_pool" "pool" {
19:24:06.405 STDOUT terraform:         id                         = "us-east-1_0RdemAaaa"
19:24:06.405 STDOUT terraform:         name                       = "company-private-auth-prod"
19:24:06.405 STDOUT terraform:         tags                       = {}
19:24:06.405 STDOUT terraform:         # (16 unchanged attributes hidden)
19:24:06.406 STDOUT terraform:       + device_configuration {
19:24:06.406 STDOUT terraform:           + challenge_required_on_new_device      = false
19:24:06.406 STDOUT terraform:           + device_only_remembered_on_user_prompt = false
19:24:06.406 STDOUT terraform:         }
19:24:06.406 STDOUT terraform:         # (9 unchanged blocks hidden)
19:24:06.406 STDOUT terraform:     }
19:24:06.406 STDOUT terraform: Plan: 0 to add, 2 to change, 0 to destroy.
19:24:06.406 STDOUT terraform: 
19:24:06.406 STDOUT terraform: Changes to Outputs:
19:24:06.406 STDOUT terraform:   + domain_cloudfront_distribution         = "d1oia1etbbaaa1.cloudfront.net"
19:24:06.406 STDOUT terraform:   + domain_cloudfront_distribution_zone_id = "A1FDTNDABCDEFG2"
19:24:06.406 STDOUT terraform:   ~ last_modified_date                     = "2024-11-14T23:53:51Z" -> "2024-11-15T01:54:32Z"
19:24:06.406 STDOUT terraform:   + name                                   = "company-private-auth-prod"
19:24:06.406 STDOUT terraform: 
19:24:06.406 STDOUT terraform: ─────────────────────────────────────────────────────────────────────────────

Additional context

Downgrading the module release tag to 0.30.0 results in Terraform deleting the device_configuration changes and effectively reverting the values back to their original state of false