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.88k stars 9.22k forks source link

aws_cognito_identity_provider always shows pending changes in plan #4807

Open esteban-angee opened 6 years ago

esteban-angee commented 6 years ago

Terraform Version

Terraform v0.11.7

Affected Resource(s)

Terraform Configuration Files

resource "aws_cognito_identity_provider" "kaizen_saml" {
  user_pool_id  = "${aws_cognito_user_pool.any_pool.id}"
  provider_name = "PeoplesTrustADFS"
  provider_type = "SAML"

  provider_details {
    MetadataURL = "<a-url>"
  }

  attribute_mapping {
    name        = "<a-mapping>"
    family_name = "<a-mapping>"
    email       = "<a-mapping>"
  }
}

Expected Behavior

Plan isn't expected to show any modifications since the code hasn't been modifiied.

Actual Behavior

  ~ module.dev-cloud.module.cognito_user_pool.aws_cognito_identity_provider.kaizen_saml
      provider_details.%:                     "3" => "1"
      provider_details.SLORedirectBindingURI: "<actual-url>" => ""
      provider_details.SSORedirectBindingURI: "<actual-url>" => ""

Steps to Reproduce

  1. terraform plan
mike-zipit commented 6 years ago

Also present in: 1.23.0

maanenh commented 6 years ago

Also present in: 1.28.0

loa commented 5 years ago

Seems like identity provider is applying fields automatically from metadata file so they are not present in state. We decided to ignore those fields until further.

resource "aws_cognito_identity_provider" "test" {
  lifecycle {
    ignore_changes = [
      "provider_details.%",
      "provider_details.SLORedirectBindingURI",
      "provider_details.SSORedirectBindingURI",
    ]
  }
}
opub commented 4 years ago

This is my version of @loa's workaround that is compatible with Terraform v0.12.23 and AWS provider v2.53.0 that seems to work.

resource "aws_cognito_identity_provider" "idp" {
  ...

  provider_details = {
    MetadataURL           = var.idp_metadata_url
    SLORedirectBindingURI = "ignored"    # see ignore_changes below
    SSORedirectBindingURI = "ignored"    # see ignore_changes below
  }

  # SLORedirectBindingURI and SSORedirectBindingURI are only populated from MetadataURL
  lifecycle {
    ignore_changes = [
      provider_details["SLORedirectBindingURI"],
      provider_details["SSORedirectBindingURI"]
    ]
  }
}

EDIT: It turns out that the S?ORedirectBindingURI values must be set to something for the initial create to work. They can't be empty or the call fails. If they are missing the ignore_changes doesn't work since the attribute count also changes. The value ("ignored" above) can be anything since it gets replaced with the values from the metadata URL.

rbenet-lbo commented 4 years ago

I observe what I believe is the same problem, but with different fields.

Terraform v0.12.26
+ provider.aws v2.63.0

Right after applying my files I always see pending changes as follows:

  ~ resource "aws_cognito_identity_provider" "idp_google" {
        attribute_mapping = {
            "email"          = "email"
            "email_verified" = "email_verified"
            "name"           = "name"
            "username"       = "sub"
        }
        id                = "eu-west-1_XXXXXXX:Google"
        idp_identifiers   = []
      ~ provider_details  = {
          - "attributes_url"                = "https://people.googleapis.com/v1/people/me?personFields=" -> null
          - "attributes_url_add_attributes" = "true" -> null
            "authorize_scopes"              = "email profile openid"
          - "authorize_url"                 = "https://accounts.google.com/o/oauth2/v2/auth" -> null
            "client_id"                     = "----the-id----"
            "client_secret"                 = "---the-secret----"
          - "oidc_issuer"                   = "https://accounts.google.com" -> null
          - "token_request_method"          = "POST" -> null
          - "token_url"                     = "https://www.googleapis.com/oauth2/v4/token" -> null
        }
        provider_name     = "Google"
        provider_type     = "Google"
        user_pool_id      = "eu-west-1_XXXXXXX"
    }

Same behaviour seen for Facebook and Apple providers.

For reference, this is what my .tf looks like for this resource:

resource "aws_cognito_identity_provider" "idp_google" {
  user_pool_id = aws_cognito_user_pool.pool.id
  provider_name = "Google"
  provider_type = "Google"
  provider_details= {
      authorize_scopes = "email profile openid"
      client_id = "----the-id-----"
      client_secret = "----the-secret------"
  }
  attribute_mapping = {
      email = "email"
      username = "sub"
      email_verified = "email_verified"
      name = "name"
  }
}

The workaround proposed by opub also works for me. But, code doesn't look particularly pretty after that...

rvoitenko commented 2 years ago

any updates on this ? it's required to comment lifecycle part every time you want to update the provider details(in my case I'm using exported xml from Azure).

borfig commented 1 year ago

any updates on this ? it's required to comment lifecycle part every time you want to update the provider details(in my case I'm using exported xml from Azure).

Azure AD provides a constant MetadataURL as well. AWS Cognito will update its XML automatically when a new XML is available. Terraform and the AWS provider do not have to do anything.