terraform-provider-azuread icon indicating copy to clipboard operation
terraform-provider-azuread copied to clipboard

Support for AzureAD Enterprise Applications & Proxy Resources

Open rayterrill opened this issue 6 years ago • 23 comments

Community Note

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

Description

Create resources to support Enterprise Applications and specifically AzureAD application proxy resources (https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/application-proxy).

We're using this heavily with AzureAD and would love a declarative way to manage them vs creating them with the GUI or the relatively new PowerShell cmdlets.

New or Affected Resource(s)

  • azurerm_application
  • azurerm_application_proxy_configuration

References

  • https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/application-proxy
  • https://docs.microsoft.com/en-us/powershell/module/azuread/?view=azureadps-2.0#application_proxy_application_management

rayterrill avatar Jun 22 '18 02:06 rayterrill

hey @rayterrill

Thanks for opening this issue :)

Taking a quick look into this - I can't see an API available for this functionality here: https://docs.microsoft.com/en-us/rest/api/resources/ - do you know if it happens to go by another name?

Thanks!

tombuildsstuff avatar Jun 22 '18 11:06 tombuildsstuff

@tombuildsstuff Unfortunately I don't. That's what I was afraid of - given that they just added the PowerShell mechanism to do that work I had a feeling there might not be a public API yet. :(

rayterrill avatar Jun 22 '18 16:06 rayterrill

Which step are you seeking to manage? The registration of the application or the connectors or both?

ranieuwe avatar Jun 26 '18 22:06 ranieuwe

Taking a quick look into this - I can't see an API available for this functionality here: https://docs.microsoft.com/en-us/rest/api/resources/ - do you know if it happens to go by another name?

It is not part of AzureRM but part of Graph. According to the Changelog for Graph this was already pushed in September 2016, but I can't really find any clear documentation on it. In the Azure REST API specification you can see some of it pop up as Graph RBAC, which is implemented by the Go SDK.

ranieuwe avatar Jun 26 '18 22:06 ranieuwe

@ranieuwe The registration of "Enterprise Applications" in general would be really useful for us. As far as the App Proxy piece, basically everything in the "On-premises application" section (internal URL, external URL, Preauthentication, connector group, etc). https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/application-proxy-publish-azure-portal. Things like being able to add users/groups to the apps, SSO settings, etc would also be beautiful.

rayterrill avatar Jun 27 '18 01:06 rayterrill

👋🏻

We've just posted a proposal regarding splitting the Azure Active Directory resources out into their own Provider in #2322, which would allow us to ship support for additional AzureAD resources. If you're subscribed to this thread we'd be interested to hear any feedback you may have on the proposal in that thread :)

Thanks!

tombuildsstuff avatar Nov 15 '18 14:11 tombuildsstuff

Hi @rayterrill,

As in 2.0 we are deprecating all Azure AD resources and data sources in the Azure RM provider in favour of this new provider I have moved the issue here.

katbyte avatar Jan 10 '19 06:01 katbyte

Is the Azure AD Graph API what is blocking enterprise applications?

midacts avatar Jul 19 '19 20:07 midacts

I was able to create Enterprise Application with

resource "azuread_service_principal" "this" {
  application_id                = azuread_application.this.application_id
  tags = [
    "AppServiceIntegratedApp",
    "WindowsAzureActiveDirectoryIntegratedApp",
  ]
}

The tags matter. I had no time to try of both tags are required.

See also https://stackoverflow.com/questions/54071385/difference-between-enterprise-application-and-app-registration-in-azure

StefanSchoof avatar Sep 09 '19 18:09 StefanSchoof

Just "WindowsAzureActiveDirectoryIntegratedApp". I found that out by manually having created a resource and then importing it in Terraform.

borancar avatar Feb 02 '20 21:02 borancar

Forget mining for bitcoins, its golden nuggets like this that deliver real value, thx to the community for sharing.

JasonDonnelly avatar May 12 '20 09:05 JasonDonnelly

@borancar hey, how are you? With that code, could I create, through terraform, a specific Enterprise Application? For example, this one: GitHub Enterprise Cloud Organization.

I haven't found any way of creating this and specifying its details (SAML SSO and Provisioning mappings, for example) through terraform.

Best regards, Diogo Teixeira

dgteixeira avatar Apr 28 '22 14:04 dgteixeira

@borancar hey, how are you? With that code, could I create, through terraform, a specific Enterprise Application? For example, this one: GitHub Enterprise Cloud Organization.

Give it a shot - I haven't worked with Azure in a while, so wouldn't know... putting that tag was all that was needed to make the principal into an Enterprise Application.

borancar avatar Apr 28 '22 15:04 borancar

Potential docs reference: https://learn.microsoft.com/en-us/graph/application-proxy-configure-api?tabs=http

manicminer avatar Jan 25 '23 10:01 manicminer

Notes from my attempt:

Yes https://learn.microsoft.com/en-us/graph/application-proxy-configure-api?tabs=http is the correct doc.

First issue:

Error with app roles, I commented out the code disabling them to get past it. (Looks related to https://github.com/hashicorp/terraform-provider-azuread/issues/950)

	//if err := applicationDisableAppRoles(ctx, client, &properties, expandApplicationAppRoles(d.Get("app_role").(*schema.Set).List())); err != nil {
	//	return tf.ErrorDiagPathF(err, "app_role", "Could not disable App Roles for application with object ID %q", d.Id())
	//}

Second issue: Invalid property name being sent, I checked the SDK and the name didn't match the expected value, fixed with https://github.com/manicminer/hamilton/pull/244

Third issue: Properties couldn't be updated on the application created with the recommended template 8adf8e6e-67b2-4cf2-a259-e3dc5476c621 (I didn't investigate this much other than commenting out the code)

{"error":{"code":"BadRequest","message":"The request is currently not supported on the targeted entity set","innerError":{"date":"2023-06-07T15:00:10","request-id":"80b887fd-c2b6-47d5-83bb-cfae8e2b604f","client-request-id":"80b887fd-c2b6-47d5-83bb-cfae8e2b604f"}}}

I commented out the relevant code:

	//if _, err := client.Update(ctx, properties); err != nil {
	//	return tf.ErrorDiagF(err, "Could not update global application with object ID: %q", d.Id())
	//}

To work around the properties update I created a specific PATCH just for these attributes and I still got the error:

{"error":{"code":"BadRequest","message":"The request is currently not supported on the targeted entity set","innerError":{"date":"2023-06-07T15:00:10","request-id":"80b887fd-c2b6-47d5-83bb-cfae8e2b604f","client-request-id":"80b887fd-c2b6-47d5-83bb-cfae8e2b604f"}}}

I added TF_LOG and compared the body that was being sent to one that worked in the graph explorer and I saw that the id for the application is sent in the body by terraform. When I send the request with id in the graph explorer it fails, when I remove the id it works:

broken:

{
  "id": "32860704-96e8-4493-a5fc-9c4d917a24ec",
  "onPremisesPublishing": {
    "externalAuthenticationType": "aadPreAuthentication",
    "externalUrl": "https://contosoiwaapp-contoso.msappproxy.net",
    "internalUrl": "https://contosoiwaapp.com",
    "isHttpOnlyCookieEnabled": true,
    "isOnPremPublishingEnabled": true,
    "isPersistentCookieEnabled": false,
    "isSecureCookieEnabled": false,
    "isTranslateHostHeaderEnabled": true,
    "isTranslateLinksInBodyEnabled": false
  }
}

broken response:

{
    "error": {
        "code": "BadRequest",
        "message": "The request is currently not supported on the targeted entity set",
        "innerError": {
            "date": "2023-06-07T15:49:19",
            "request-id": "7ddc08bd-ea56-44eb-96c0-df53f22398a7",
            "client-request-id": "08ca0054-e0f7-ee3b-d011-95075684da43"
        }
    }
}

working is above without id

Code reference: https://github.com/manicminer/hamilton/blob/9893247866cc3aa95ff00b2dec2f70215e5f3d9b/msgraph/applications.go#L154-L158

Is there anyway to work around this @manicminer? I'm a bit surprised the id is added to the body for no reason, is it required in some cases or just a mistake by virtue of the object having an ID in it and then accidentally serialised, or should the API just be ignoring this value and not complaining?

My changes: https://github.com/hashicorp/terraform-provider-azuread/compare/main...timja:terraform-provider-azuread:app-proxy?expand=1

timja avatar Jun 07 '23 15:06 timja

Hi @timja, just adding a +1 to this. Awesome work glad this has got some traction, it'll be a great resource to have in TF

charliegibb avatar Jun 13 '23 14:06 charliegibb

I've written a blog and a CLI tool using the Graph API to work around this in the meantime:

https://blog.timja.dev/how-to-automate-azure-ad-application-proxy-part-2/

https://github.com/hmcts/azure-app-proxy-manager

It should be do-able to adapt terraform but it will need changes to the SDK used and I would like @manicminer 's input on that

timja avatar Jun 29 '23 13:06 timja

I know the graph API requires you to utilize a Microsoft template for Azure ad App proxy type apps. There is a requirement to instantiate non-gallery apps. see link below. https://learn.microsoft.com/en-us/graph/api/applicationtemplate-instantiate?view=graph-rest-1.0&tabs=http

I had to go this route when calling Graph API via power automate to create Azure AD Applications which utilized Application Proxy.

image image image

there's a static template id for non-gallery azure apps that we may be able to specify via terraform Example:

`resource "azuread_application" "example_app" { display_name = "example azure application app" template_id = "8adf8e6e-67b2-4cf2-a259-e3dc5476c621" }

resource "azuread_service_principal" "example_app" { application_id = azuread_application.template2.application_id use_existing = true feature_tags { enterprise = true gallery = false } }`

hope this helps shed some light on this request.

ctejeda avatar Jul 11 '23 00:07 ctejeda

{ "id": "32860704-96e8-4493-a5fc-9c4d917a24ec", "onPremisesPublishing": { "externalAuthenticationType": "aadPreAuthentication", "externalUrl": "https://contosoiwaapp-contoso.msappproxy.net", "internalUrl": "https://contosoiwaapp.com", "isHttpOnlyCookieEnabled": true, "isOnPremPublishingEnabled": true, "isPersistentCookieEnabled": false, "isSecureCookieEnabled": false, "isTranslateHostHeaderEnabled": true, "isTranslateLinksInBodyEnabled": false } }

May you provide an example of a resource creation with the app proxy settings ?

ctejeda avatar Jul 11 '23 18:07 ctejeda

May you provide an example of a resource creation with the app proxy settings ?

What do you mean? it's not possible with terraform currently.

You need to use the Graph API, or you can take a look at the app I wrote for it: https://blog.timja.dev/how-to-automate-azure-ad-application-proxy-part-2/

timja avatar Jul 11 '23 19:07 timja

I came up with a workaround that works for my use case. you can read more about it here: https://ctejeda.com/documentation/creating-azure-apps-that-utilize-azure-application-proxy-via-terrafrom/

Thanks @timja for shedding some light on this.

using the below worked for me as a work around.

`terraform { required_providers { azuread = { source = "hashicorp/azuread" version = "~> 2.7.0" } } }

provider "azuread" {

client_id = "var.client_id" client_secret = "var.sec" tenant_id = "var.tenant_id" }

data "azuread_application_template" "example" { template_id = "8adf8e6e-67b2-4cf2-a259-e3dc5476c621" }

resource "azuread_application" "example" { display_name = "example" template_id = data.azuread_application_template.example.template_id feature_tags { custom_single_sign_on = true } }

resource "azuread_service_principal" "example" { application_id = azuread_application.example.application_id use_existing = true preferred_single_sign_on_mode = "saml" login_url = "https://test-verifieddoamin.net/" feature_tags { enterprise = true gallery = false custom_single_sign_on = true }

provisioner "local-exec" { command = <<EOF curl --location --request PATCH 'https://graph.microsoft.com/beta/applications/${azuread_application.example.object_id}' --header 'Content-Type: application/json' --header 'Authorization: Bearervar.token' --data '{ "onPremisesPublishing": { "externalAuthenticationType": "aadPreAuthentication", "internalUrl": "https://internalurl.com/", "externalUrl": "https://externalurl.verifieddomain.com/", "isHttpOnlyCookieEnabled": true, "isOnPremPublishingEnabled": true, "isPersistentCookieEnabled": true, "isSecureCookieEnabled": true, "isStateSessionEnabled": true, "isTranslateHostHeaderEnabled": true, "isTranslateLinksInBodyEnabled": true } }' EOF }

}

`

ctejeda avatar Jul 12 '23 17:07 ctejeda

Just posted my official workaround here for anyone still looking for a work around.

https://github.com/ctejeda/azuread_appproxy

ctejeda avatar Jul 14 '23 23:07 ctejeda

Just "WindowsAzureActiveDirectoryIntegratedApp". I found that out by manually having created a resource and then importing it in Terraform.

Not sure when this was added, but you can now specify this using the higher level feature_tags block:

resource "azuread_application" "example" {
  display_name = "example"
}

resource "azuread_service_principal" "example" {
  client_id = azuread_application.example.client_id

  feature_tags {
    enterprise = true
  }
}

The docs linked state that specifying enterprise = true is the same as assigning the WindowsAzureActiveDirectoryIntegratedApp tag.

daviewales avatar Feb 22 '24 04:02 daviewales