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.63k stars 9.01k forks source link

[Bug]: Provider produced inconsistent final plan for resource block that reads from data block #33631

Open marco-luzzara opened 9 months ago

marco-luzzara commented 9 months ago

Terraform Core Version

1.5.7

AWS Provider Version

5.17.0

Affected Resource(s)

Resources

Data sources:

Expected Behavior

It should create the AWS Cognito user with the credentials retrieved from the data.aws_secretsmanager_secret_version block. This data block is getting the secret value from the previously created secret using the resource aws_secretsmanager_secret_version.

Actual Behavior

It shows an error (see Relevant Error/Panic Output Snippet)

Relevant Error/Panic Output Snippet

╷
│ Error: Provider produced inconsistent final plan
│ 
│ When expanding the plan for
│ module.authentication.aws_cognito_user.main_admin_user to include new
│ values learned so far during apply, provider
│ "registry.terraform.io/hashicorp/aws" produced an invalid new value for
│ .attributes: inconsistent values for sensitive attribute.
│ 
│ This is a bug in the provider, which should be reported in the provider's
│ own issue tracker.
╵

Terraform Configuration Files

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.17.0"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "us-east-1"
}

variable "admin_user_credentials" {
  description = "Credentials for the admin user"
  type = object({
    username = string
    password = string
  })
#  sensitive = true
}

resource "aws_cognito_user_pool" "main_pool" {
  name = "main-pool"

  auto_verified_attributes = ["email"]
  username_attributes = ["email"]
  schema {
    attribute_data_type = "Number"
    mutable = false
    name = "dbId"
    required = true
    number_attribute_constraints {
      min_value = 1
    }
  }
  password_policy {
    minimum_length    = 8
    require_lowercase = false
    require_numbers   = false
    require_symbols   = false
    require_uppercase = false
  }
  user_pool_add_ons {
    advanced_security_mode = "OFF"
  }
}

resource "aws_cognito_user_group" "admin_user_group" {
  name         = "admin-user-group"
  user_pool_id = aws_cognito_user_pool.main_pool.id
}

resource "aws_cognito_user_pool_client" "main_pool_client" {
  name            = "main-pool-client"
  user_pool_id    = aws_cognito_user_pool.main_pool.id
  allowed_oauth_flows_user_pool_client = true
  callback_urls = ["https://example.com"]
  allowed_oauth_flows                 = ["implicit"]
  allowed_oauth_scopes                = ["openid", "email", "profile"]

  generate_secret = true
}

resource "aws_secretsmanager_secret" "admin_user_credentials_secret" {
  recovery_window_in_days = 0
}

resource "aws_secretsmanager_secret_version" "admin_user_credentials_secret_value" {
  secret_id     = aws_secretsmanager_secret.admin_user_credentials_secret.id
  secret_string = jsonencode(var.admin_user_credentials)
}

data "aws_secretsmanager_secret_version" "admin_user_credentials_secret_data" {
  depends_on = [aws_secretsmanager_secret_version.admin_user_credentials_secret_value]
  secret_id     = aws_secretsmanager_secret.admin_user_credentials_secret.id
}

resource "aws_cognito_user" "main_admin_user" {
  user_pool_id = aws_cognito_user_pool.main_pool.id
  username    = jsondecode(data.aws_secretsmanager_secret_version.admin_user_credentials_secret_data.secret_string)["username"]
  password    = jsondecode(data.aws_secretsmanager_secret_version.admin_user_credentials_secret_data.secret_string)["password"]
  attributes = {
    email = jsondecode(data.aws_secretsmanager_secret_version.admin_user_credentials_secret_data.secret_string)["username"]
  }
}

Steps to Reproduce

  1. terraform init
  2. terraform apply

Debug Output

https://gist.github.com/marco-luzzara/fbf1e30f066ec480f55fb701005b99ce

Panic Output

No response

Important Factoids

The provider endpoint is a Localstack instance instead of the actual AWS environment. Besides, I am running Terraform on Docker, the image is 1.5.7. I have read that a resource block should not use the data block immediately after it is created, but it works in another case:

resource "aws_secretsmanager_secret" "webapp_db_credentials_secret" {
  description = "Db credentials"
  recovery_window_in_days = 0
}

resource "aws_secretsmanager_secret_version" "webapp_db_credentials_secret_value" {
  secret_id     = aws_secretsmanager_secret.webapp_db_credentials_secret.id
  secret_string = jsonencode(var.webapp_db_credentials)
}

data "aws_secretsmanager_secret_version" "webapp_db_credentials_secret_data" {
  depends_on = [aws_secretsmanager_secret_version.webapp_db_credentials_secret_value]
  secret_id     = aws_secretsmanager_secret.webapp_db_credentials_secret.id
}

resource "aws_db_instance" "webapp_db" {
  allocated_storage    = var.webapp_db_config.allocated_storage
  storage_type         = "gp2"
  engine               = "postgres"
  engine_version       = "15"
  instance_class       = var.webapp_db_config.instance_class
  skip_final_snapshot  = var.webapp_db_config.skip_final_snapshot
  username             = jsondecode(data.aws_secretsmanager_secret_version.webapp_db_credentials_secret_data.secret_string)["username"]
  password             = jsondecode(data.aws_secretsmanager_secret_version.webapp_db_credentials_secret_data.secret_string)["password"]
  db_name              = var.webapp_db_config.db_name
  port                 = var.webapp_db_config.port
}

so I thought that this might be a real issue.

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 9 months ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue