pulumi / pulumi-azuread

A Microsoft Azure Active Directory (Azure AD) Pulumi resource package, providing multi-language access to Azure AD
Apache License 2.0
17 stars 8 forks source link

Identifier URI created with ApplicationIdentifierUri is lost on Application update #1036

Open lukaskabrt opened 5 months ago

lukaskabrt commented 5 months ago

What happened?

I am trying to set Identifier URI for Azure AD Application using ApplicationIdentifierUri

        var applicationArgs = new Pulumi.AzureAD.ApplicationArgs
        {
            DisplayName = configuration.Api.Name
        };
        var application = new Pulumi.AzureAD.Application("entraid-app", applicationArgs);

        _ = new Pulumi.AzureAD.ApplicationIdentifierUri("entraid-app-api-identifier", new()
        {
            ApplicationId = application.Id,
            IdentifierUri = application.ClientId.Apply(id => $"api://{id}")
        });

This code works as expected and creates the application with the specified Identifier URI. However, if I make any change to the Application resource e.g.

var applicationArgs = new Pulumi.AzureAD.ApplicationArgs
{
    DisplayName = configuration.Api.Name,
    Web = new ApplicationWebArgs
    {
        ImplicitGrant = new ApplicationWebImplicitGrantArgs { AccessTokenIssuanceEnabled = true },
    }
};

and run pulumi up the change is applied, but the Identifier URI is removed from the application in Azure AD. The ApplicationIdentifierUri still exists in the Pulumi stack, but Identifier URI doesn't exist in the actual Azure AD application.

Example

Please, see description.

Output of pulumi about

CLI Version 3.114.0 Go Version go1.22.2 Go Compiler gc

Plugins KIND NAME VERSION language dotnet unknown

Host OS Microsoft Windows 11 Enterprise Version 10.0.22621 Build 22621 Arch x86_64

This project is written in dotnet: executable='C:\Program Files\dotnet\dotnet.exe' version='8.0.300-preview.24203.14'

Dependencies: NAME VERSION Pulumi 3.62.0 Pulumi.AzureAD 5.48.0 Pulumi.AzureNative 2.38.0 Pulumi.Random 4.16.0

Additional context

No response

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

thomas11 commented 5 months ago

Hi @lukaskabrt, thank you for reporting this. This behavior is expected but unfortunately we failed to document it in this case. The problem is that application identifier URIs can be managed either through the Application resource or as stand-alone resources (as in your case).

You can either manage your ApplicationIdentifierUri entirely inside the Application resource, via the IdentifierUris property, or set new CustomResourceOptions { IgnoreChanges = { "IdentifierUris" } } on the Application resource to tell Pulumi to disregard that property for updates (full docs here).

lukaskabrt commented 5 months ago

Hi @thomas11, thanks you for your suggestion, unfortunately it seems, that the approach with new CustomResourceOptions { IgnoreChanges = { "IdentifierUris" } } doesn't work. The result is the same as in the original report.

I am no expert on Pulumi internals, but from the linked docs it makes sense.

The ignoreChanges resource option specifies a list of properties that Pulumi will ignore when it updates existing resources. Pulumi ignores a property by using the old value from the state instead of the value provided by the Pulumi program when determining whether an update or replace is needed.

My understanding is that IgnoreChanges prevents Pulumi from triggering an update when the property changes, but when some other property changes the resource is updated as a whole. Since Application resource and ApplicationIdentifierUri resource maintain separate states, there is no record of the identifier URIs value in the application state, so it is removed.

At the moment I am using the second approach and manage application identifier URIs in the Application resource, but this prevents us from using the standart URI format api://CLIENT_ID, because the client ID is not known at the time of application creation.

thomas11 commented 5 months ago

Hi @lukaskabrt, it looks like I made a small mistake in my code snippet. It should be { IgnoreChanges = { "identifierUris" } } (camelCase identifier). Could you try again with that?

My understanding is that IgnoreChanges prevents Pulumi from triggering an update when the property changes, but when some other property changes the resource is updated as a whole.

Not quite. When some other property changes and the resource is updated, the property marked with ignoreChanges will be updated with its original value from creation, if any. So if it wasn't specified at all at creation, it should be ignored.