Open rayterrill opened 6 years ago
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 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. :(
Which step are you seeking to manage? The registration of the application or the connectors or both?
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 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.
๐๐ป
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!
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.
Is the Azure AD Graph API what is blocking enterprise applications?
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.
Just "WindowsAzureActiveDirectoryIntegratedApp". I found that out by manually having created a resource and then importing it in Terraform.
Forget mining for bitcoins, its golden nuggets like this that deliver real value, thx to the community for sharing.
@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
@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.
Potential docs reference: https://learn.microsoft.com/en-us/graph/application-proxy-configure-api?tabs=http
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?
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
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
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.
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.
{ "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 ?
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/
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 }
}
`
Just posted my official workaround here for anyone still looking for a work around.
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.
Community Note
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)
References