Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add in second app_role to existing azuread_application fails #721

Closed
StefanSchoof opened this issue Jan 25, 2022 · 7 comments · Fixed by #750
Closed

Add in second app_role to existing azuread_application fails #721

StefanSchoof opened this issue Jan 25, 2022 · 7 comments · Fixed by #750

Comments

@StefanSchoof
Copy link
Contributor

StefanSchoof commented Jan 25, 2022

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritise this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritise the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform (and AzureAD Provider) Version

Terraform v1.1.4
on windows_amd64

  • provider registry.terraform.io/hashicorp/azuread v2.15.0
  • provider registry.terraform.io/hashicorp/azurerm v2.93.1

Affected Resource(s)

  • azuread_application

Terraform Configuration Files

old:

resource "azuread_application" "backend_ad_application" {
  count = var.ad_application == true ? 1 : 0

  display_name    = local.ad_application_name
  identifier_uris = ["api://apimanagement"]

  group_membership_claims = ["None"]

  owners = data.azuread_group.aop_ad_owner_group.members
  web {
    implicit_grant {
      access_token_issuance_enabled = true
      id_token_issuance_enabled     = true
    }
  }

  optional_claims {
    access_token {
      name = "email"
    }

    id_token {
      name = "email"
    }
  }

  required_resource_access {
    resource_app_id = "00000003-0000-0000-c000-000000000000" // graph api
    resource_access {
      id   = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" // User.Read
      type = "Scope"
    }
    resource_access {
      id   = "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0" // mail
      type = "Scope"
    }
    resource_access {
      id   = "14dad69e-099b-42c9-810b-d002981feec1" // profile
      type = "Scope"
    }
  }

  app_role {
    allowed_member_types = ["User"]
    description          = "Company Admin"
    display_name         = "Company Admin"
    enabled              = true
    value                = "Admin"
    id                   = "683ff300-db10-48af-0482-fda9e35c6688"
  }

  api {
    requested_access_token_version = 2
    oauth2_permission_scope {
      admin_consent_description  = "Administer ${local.ad_application_name} application"
      admin_consent_display_name = "Administer ${local.ad_application_name} application"
      enabled                    = true
      id                         = "8b9190e9-acfe-8be0-87fe-61f9fbb689c1"
      type                       = "Admin"
      user_consent_description   = "administer ${local.ad_application_name} application"
      user_consent_display_name  = "administer ${local.ad_application_name} application"
      value                      = "administer"
    }
    oauth2_permission_scope {
      admin_consent_description  = "User access ${local.ad_application_name} application"
      admin_consent_display_name = "User access ${local.ad_application_name} application"
      enabled                    = true
      id                         = "6e897dbd-c0fe-982c-ff3c-49404326c443"
      type                       = "User"
      user_consent_description   = "Access ${local.ad_application_name} application"
      user_consent_display_name  = "Access ${local.ad_application_name} application"
      value                      = "user"
    }
  }
}

updated with second app_role

resource "azuread_application" "backend_ad_application" {
  count = var.ad_application == true ? 1 : 0

  display_name    = local.ad_application_name
  identifier_uris = ["api://apimanagement"]

  group_membership_claims = ["None"]

  owners = data.azuread_group.aop_ad_owner_group.members
  web {
     redirect_uris = [
      <snip>
    ]
    implicit_grant {
      access_token_issuance_enabled = true
      id_token_issuance_enabled     = true
    }
  }

  optional_claims {
    access_token {
      name = "email"
    }

    id_token {
      name = "email"
    }
  }

  required_resource_access {
    resource_app_id = "00000003-0000-0000-c000-000000000000" // graph api
    resource_access {
      id   = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" // User.Read
      type = "Scope"
    }
    resource_access {
      id   = "64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0" // mail
      type = "Scope"
    }
    resource_access {
      id   = "14dad69e-099b-42c9-810b-d002981feec1" // profile
      type = "Scope"
    }
  }

  app_role {
    allowed_member_types = ["User"]
    description          = "Company Admin"
    display_name         = "Company Admin"
    enabled              = true
    value                = "Admin"
    id                   = "683ff300-db10-48af-0482-fda9e35c6688"
  }

  app_role {
    allowed_member_types = ["User"]
    description          = "User"
    display_name         = "User"
    enabled              = true
    id                   = "eebd0ddb-ff52-4a3f-890b-6f97a6cafd50"
    value                = "User"
  }

  api {
    requested_access_token_version = 2
    oauth2_permission_scope {
      admin_consent_description  = "Administer ${local.ad_application_name} application"
      admin_consent_display_name = "Administer ${local.ad_application_name} application"
      enabled                    = true
      id                         = "8b9190e9-acfe-8be0-87fe-61f9fbb689c1"
      type                       = "Admin"
      user_consent_description   = "administer ${local.ad_application_name} application"
      user_consent_display_name  = "administer ${local.ad_application_name} application"
      value                      = "administer"
    }
    oauth2_permission_scope {
      admin_consent_description  = "User access ${local.ad_application_name} application"
      admin_consent_display_name = "User access ${local.ad_application_name} application"
      enabled                    = true
      id                         = "6e897dbd-c0fe-982c-ff3c-49404326c443"
      type                       = "User"
      user_consent_description   = "Access ${local.ad_application_name} application"
      user_consent_display_name  = "Access ${local.ad_application_name} application"
      value                      = "user"
    }
  }
}

Debug Output

https://gist.github.com/StefanSchoof/6c4a050558ad644b672781375ff2d0aa

Panic Output

n/a

Expected Behavior

Adding a new app_role to an existing app, will update the app and afterwards the app has two app_roles.

Actual Behavior

I get an error on apply:

{"error":{"code":"DuplicateValue","message":"Request contains a property with duplicate values.","details":[{"code":"DuplicateValue","target":"appRoles","message":"Request contains a property with duplicate values."}],"innerError":{"date":"2022-01-25T14:36:54","request-id":"45bc0677-3873-4270-ab2a-1490cb755a20","client-request-id":"45bc0677-3873-4270-ab2a-1490cb755a20"}}}

Steps to Reproduce

  1. Create App
  2. tf apply
  3. Add a second app_role block
  4. tf apply

Important Factoids

A apply that updates the one app_role is successful.

References

@manicminer
Copy link
Contributor

Hi @StefanSchoof, thanks for reporting this issue.

Looking through the debug log, the API is indeed reporting an error for the appRoles field, however as best I can tell, the request to add the second app role is formatted correctly and there should be no problems with this request. To verify, I tried to reproduce this locally with the same setup; an existing application with one app role, and an apply operation to add a second app role with no changes to the first app role. For good measure I also tried where the plan included changes to the existing app role as well as adding a new role.

Unfortunately I could not reproduce this error. Looking at the HTTP traces, my testing performs the same actions as in your failed apply operation - that is, both of them appear to be doing the right thing. At this time I believe this is quite likely to be an API bug. Are you able to consistently reproduce this error or does the same operation now work as expected?

@StefanSchoof
Copy link
Contributor Author

StefanSchoof commented Jan 26, 2022

Thanks @manicminer to look into this.

I figured it out. The problem is that the azure ad does not allow a Value named User and is returning a this not very matching error message.

Having

  app_role {
    allowed_member_types = ["User"]
    description          = "Standard User"
    display_name         = "Standard User"
    enabled              = true
    id                   = "eebd0ddb-ff52-4a3f-890b-6f97a6cafd50"
    value                = "Standard.User"
  }

is working

(and

  app_role {
    allowed_member_types = ["User"]
    description          = "User"
    display_name         = "User"
    enabled              = true
    id                   = "eebd0ddb-ff52-4a3f-890b-6f97a6cafd50"
    value                = "User"
  }

not)

Not sure if it makes sense to add a check in tf to prevent this name or just close this issue.

@StefanSchoof
Copy link
Contributor Author

@manicminer
Copy link
Contributor

@StefanSchoof That's great, thanks for testing and coming back to this. We can validate this in the provider to provide a more meaningful error message to aid other users in future.

@github-actions
Copy link

This functionality has been released in v2.19.0 of the Terraform Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!

@StefanSchoof
Copy link
Contributor Author

I think I found the real cause.

The oauth2_permission_scope seems to have the same namespace. Having a:

app_role {
    allowed_member_types = [
      "User",
      "Application",
    ]
    description  = "User"
    display_name = "User"
    enabled      = true
    id           = "<gui>"
    value        = "User"
  }
api {
    requested_access_token_version = 2
    oauth2_permission_scope {
      admin_consent_description  = "User access ${local.ad_application_name} application"
      admin_consent_display_name = "User access ${local.ad_application_name} application"
      enabled                    = true
      id                         = "<guid>"
      type                       = "User"
      user_consent_description   = "Access ${local.ad_application_name} application"
      user_consent_display_name  = "Access ${local.ad_application_name} application"
      value                      = "user"
    }
  }

result into this error, when creating a role with the same name.

grafik

grafik

@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants