okta / terraform-provider-okta

A Terraform provider to manage Okta resources, enabling infrastructure-as-code provisioning and management of users, groups, applications, and other Okta objects.
https://registry.terraform.io/providers/okta/okta
Mozilla Public License 2.0
253 stars 204 forks source link

subject_name_id_format & subject_name_id_template keep being applied #653

Closed greenkiwi closed 2 years ago

greenkiwi commented 2 years ago

Community Note

Terraform Version

Terraform v0.14.9
+ provider registry.terraform.io/cyralinc/cyral v1.2.2
+ provider registry.terraform.io/okta/okta v3.13.10

Your version of Terraform is out of date! The latest version
is 1.0.6. You can update by downloading from https://www.terraform.io/downloads.html

Affected Resource(s)

Terraform Configuration Files

resource "okta_app_saml" "terraform_cloud" {
  label                    = "Terraform Cloud"
  response_signed          = false
  honor_force_authn        = false
  subject_name_id_template = "$${user.userName}"
  subject_name_id_format   = local.okta_constants.subject_name_id_format.emailAddress

  attribute_statements {
    type         = "GROUP"
    name         = "MemberOf"
    filter_type  = "STARTS_WITH"
    filter_value = "terraform-cloud-"
  }

  lifecycle { ignore_changes = [groups] }
}

Debug Output

Panic Output

Expected Behavior

Terraform says that changes need to be applied:

Terraform will perform the following actions:

  # okta_app_saml.terraform_cloud will be updated in-place
  ~ resource "okta_app_saml" "terraform_cloud" {
        id                         = "..."
        name                       = "terraformcloud"
      + subject_name_id_format     = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
      + subject_name_id_template   = "${user.userName}"
        # (29 unchanged attributes hidden)

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

I expect that these values will be set and future plans will be "clean".

Actual Behavior

Instead, when I apply, the changes are still there in the next "plan".

If I then remove those from the config:

resource "okta_app_saml" "terraform_cloud" {
  label                    = "Terraform Cloud"
  response_signed          = false
  honor_force_authn        = false
  #subject_name_id_template = "$${user.userName}"
  #subject_name_id_format   = local.okta_constants.subject_name_id_format.emailAddress

  attribute_statements {
    type         = "GROUP"
    name         = "MemberOf"
    filter_type  = "STARTS_WITH"
    filter_value = "terraform-cloud-"
  }

  lifecycle { ignore_changes = [groups] }
}

It says it will remove the values in the plan

Plan: 0 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  ~ app_terraform_cloud = {
      ~ subject_name_id_format           = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" -> ""
      ~ subject_name_id_template         = "${user.userName}" -> ""
        # (56 unchanged elements hidden)
    }

------------------------------------------------------------------------

This suggests that the values are set but something is failing when fetching them during the plan

Steps to Reproduce

I'm not sure how to reproduce out side of our environment.

Important Factoids

References

bogdanprodan-okta commented 2 years ago

Hi @greenkiwi! Thanks for submitting this issue! I'll try to fix it asap.

bogdanprodan-okta commented 2 years ago

I've tried to create a SAML app based on the script you've provided, but it has failed with an error.

resource "okta_app_saml" "terraform_cloud" {
  label                    = "Terraform Cloud"
  response_signed          = false
  honor_force_authn        = false
  subject_name_id_template = "$${user.userName}"
  subject_name_id_format   = local.okta_constants.subject_name_id_format.emailAddress

  attribute_statements {
    type         = "GROUP"
    name         = "MemberOf"
    filter_type  = "STARTS_WITH"
    filter_value = "terraform-cloud-"
  }

  lifecycle { ignore_changes = [groups] }
}

Error:

 Error: failed to create SAML application: missing conditionally required fields, reason: 'Custom SAML applications must contain these fields', missing fields: sso_url, recipient, destination, audience, signature_algorithm, digest_algorithm, authn_context_class_ref

After I've added missing fields

resource "okta_app_saml" "terraform_cloud" {
  label                    = "Terraform Cloud"
  response_signed          = false
  honor_force_authn        = false
  subject_name_id_template = "$${user.userName}"
  subject_name_id_format   = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
  sso_url                  = "http://google.com"
  recipient                = "http://here.com"
  destination              = "http://its-about-the-journey.com"
  audience                 = "http://audience.com"
  signature_algorithm      = "RSA_SHA256"
  digest_algorithm         = "SHA256"
  authn_context_class_ref  = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
  assertion_signed         = true

  attribute_statements {
    type         = "GROUP"
    name         = "MemberOf"
    filter_type  = "STARTS_WITH"
    filter_value = "terraform-cloud-"
  }

  lifecycle { ignore_changes = [groups] }
}

Everything is working fine. Could you also tell me is this a preconfigured app?

greenkiwi commented 2 years ago

It was an app that was added manually in the Okta UI and then imported.

We followed the instructions here: https://www.terraform.io/docs/enterprise/saml/identity-provider-configuration-okta.html

I'll try to pull the full debug logs and then remove anything that appears sensitive.

bogdanprodan-okta commented 2 years ago

Thanks!

greenkiwi commented 2 years ago

@bogdanprodan-okta Do you know which requests from the debug log you would need? The debug output is extremely long and appears to be filled with IDs etc which seem sensitive.

bogdanprodan-okta commented 2 years ago

I just need a response from GET /api/v1/apps/${appID}

greenkiwi commented 2 years ago

@bogdanprodan-okta what is the objectClass that I should be looking for? the responses are interleaved with different requests.

"objectClass": [
  "okta:user_group"
 ],

samle_app?

bogdanprodan-okta commented 2 years ago

If you are using SSWS token you can just make a curl request

curl --location --request GET 'https://example.okta.com/api/v1/apps/0oa11m5v5dqciPK3O0h8' \
--header 'Authorization: SSWS token' 
greenkiwi commented 2 years ago

I found it:

{
 "id": "APP_ID",
 "name": "terraformcloud",
 "label": "Terraform Cloud",
 "status": "ACTIVE",
 "lastUpdated": "2021-09-16T20:10:14.000Z",
 "created": "2021-08-30T22:26:12.000Z",
 "accessibility": {
  "selfService": false,
  "errorRedirectUrl": null,
  "loginRedirectUrl": null
 },
 "visibility": {
  "autoLaunch": false,
  "autoSubmitToolbar": false,
  "hide": {
   "iOS": false,
   "web": false
  },
  "appLinks": {
   "terraformcloud_link": true
  }
 },
 "features": [],
 "signOnMode": "SAML_2_0",
 "credentials": {
  "userNameTemplate": {
   "template": "${source.login}",
   "type": "BUILT_IN"
  },
  "signing": {
   "kid": "kbfm-REDACTED"
  }
 },
 "settings": {
  "app": {},
  "notifications": {
   "vpn": {
    "network": {
     "connection": "DISABLED"
    },
    "message": null,
    "helpUrl": null
   }
  },
  "notes": {
   "admin": null,
   "enduser": null
  },
  "signOn": {
   "defaultRelayState": null,
   "ssoAcsUrlOverride": null,
   "audienceOverride": null,
   "recipientOverride": null,
   "destinationOverride": null,
   "attributeStatements": [
    {
     "type": "GROUP",
     "name": "MemberOf",
     "namespace": "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified",
     "filterType": "STARTS_WITH",
     "filterValue": "terraform-cloud-"
    }
   ]
  }
 },
 "_links": {
  "help": {
   "href": "https://REDACTED-admin.okta.com/app/terraformcloud/APP_ID/setup/help/SAML_2_0/external-doc",
   "type": "text/html"
  },
  "metadata": {
   "href": "https://REDACTED.okta.com/api/v1/apps/APP_ID/sso/saml/metadata",
   "type": "application/xml"
  },
  "uploadLogo": {
   "href": "https://REDACTED.okta.com/api/v1/apps/APP_ID/logo",
   "hints": {
    "allow": [
     "POST"
    ]
   }
  },
  "appLinks": [
   {
    "name": "terraformcloud_link",
    "href": "https://REDACTED.okta.com/home/terraformcloud/APP_ID/REDACTED",
    "type": "text/html"
   }
  ],
  "groups": {
m/api/v1/apps/APP_ID/groups"
  },
  "logo": [
   {
    "name": "medium",
    "href": "https://ok7static.oktacdn.com/fs/bcg/4/REDACTED",
    "type": "image/png"
   }
  ],
  "users": {
   "href": "https://REDACTED.okta.com/api/v1/apps/APP_ID/users"
  },
  "deactivate": {
   "href": "https://REDACTED.okta.com/api/v1/apps/APP_ID/lifecycle/deactivate"
  }
 }
}
bogdanprodan-okta commented 2 years ago

Thanks! I'll try to see what I can do here. BTW, signOn field in my app looks like this:

        "signOn": {
            "defaultRelayState": "",
            "ssoAcsUrl": "http://google.com",
            "idpIssuer": "http://www.okta.com/${org.externalKey}",
            "audience": "http://audience.com",
            "recipient": "http://here.com",
            "destination": "http://its-about-the-journey.com",
            "subjectNameIdTemplate": "${user.userName}",
            "subjectNameIdFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
            "responseSigned": false,
            "assertionSigned": true,
            "signatureAlgorithm": "RSA_SHA256",
            "digestAlgorithm": "SHA256",
            "honorForceAuthn": false,
            "authnContextClassRef": "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
            "spIssuer": null,
            "requestCompressed": false,
            "attributeStatements": [
                {
                    "type": "GROUP",
                    "name": "MemberOf",
                    "namespace": "urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified",
                    "filterType": "STARTS_WITH",
                    "filterValue": "terraform-cloud-"
                }
            ],
            "inlineHooks": [],
            "allowMultipleAcsEndpoints": false,
            "acsEndpoints": [],
            "slo": {
                "enabled": false
            }
        }
greenkiwi commented 2 years ago

@bogdanprodan-okta is there a chance that these values need some other value to be set?

      ~ subject_name_id_format           = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" -> ""
      ~ subject_name_id_template         = "${user.userName}" -> ""

So without the other value set, they always show up in this weird state.

It just seems weird that if I don't specify them, it tells me I am setting them from the specified value to "" but if I specify them, it tells me that it is going to set those values.

My goal is to cleanly import this app so that it can be managed via TF moving forwards.

greenkiwi commented 2 years ago

So I have confirmed that if I remove the values - they are removed and stay removed.

But if the values are set, they continue to need to be set.

Maybe there is some other value that "enables" them? And/or stops them from being set?

bogdanprodan-okta commented 2 years ago

Hi, @greenkiwi! Sorry for such a late response. I'm currently trying to figure out with Terraform Cloud doesn't have these fields, so I pinged the internal team responsible for the app's functionality to help me out. As soon I get a response from them, I'll get back to you with an answer. Cheers!

bogdanprodan-okta commented 2 years ago

@greenkiwi As I understand, these fields might be missing from the pre-configured aka catalog apps, so unfortunately you can not set up them.

bogdanprodan-okta commented 2 years ago

Closing this issue for now as there is nothing that can be done from the provider's side.