Open c-falardeau opened 5 months ago
This looks specific to the azuread provider. Moving to that repo for further triage.
Hi @c-falardeau I think I re-created the issue using just your code for the the Application and ApplicationRedirectUris
:
using Pulumi;
using Pulumi.AzureAD;
return await Pulumi.Deployment.RunAsync(() =>
{
var application = new Application(
"MyAppRegistration",
new ApplicationArgs
{
DisplayName = "MyAppRegistrationDisplayNAme",
SignInAudience = "AzureADMultipleOrgs",
Owners = new InputList<string> { "REPLACE_WITH_OBJECT_ID" },
}
);
_ = new ApplicationRedirectUris(
"MyAppRegistrationRedirectUris",
new ApplicationRedirectUrisArgs
{
ApplicationId = application.Id,
RedirectUris = new InputList<string> { "https://localhost:3000" },
Type = "Web"
}
);
});
Steps:
MyAppRegistrationRedirectUris
has been deletedDoes that accurately summarise your issue above?
The ApplicationRedirectUris
is also a sub-property of the Application
resource. The above code is equivelent to:
return await Pulumi.Deployment.RunAsync(() =>
{
var application = new Application(
"MyAppRegistration",
new ApplicationArgs
{
DisplayName = "MyAppRegistrationDisplayNAme",
SignInAudience = "AzureADMultipleOrgs",
Owners = new InputList<string> { "db8fa9c3-36b4-4474-91b0-aa96bcc706bc" }, // <---- When this change, the API permission are lost, but pulumi doesn't know. So run pulumi up multiple times with different owners
Web = new ApplicationWebArgs
{
RedirectUris = new InputList<string> { "https://localhost:3000" }
}
}
);
});
This is a slightly odd design of the upstream provider to provide both methods of specifying the RedirectUris
and results in unexpected behaviour when updating the original resource having made changes via the secondary resources (such as ApplicationRedirectUris
). When you make any change to the original Application
resource it entirely overwrites the state of the resource, inadvertantly removing the RedirectUris
configuration which manifests as the deletion of MyAppRegistrationRedirectUris
on the next refresh.
You can also see this by:
Application
resource to reflect the change made by the standalone resource.Where there's conflicts betwen a feature being managed as part of the parent and as it's own resource, it's recommended to only manage the feature via the property on the parent and not as an external resource. This will ensure the lifecycle isn't broken
This would need to be fixed in the core provider implementation. You can search for existing issues or open a new issue if one doesn't yet exist here: https://github.com/hashicorp/terraform-provider-azuread
We've had similar issues in the Azure Native provider historically and have been able to resolve this issue by introducing resource parent-child awareness to allow parts of the parent resource to be managed via standalone resources: https://github.com/pulumi/pulumi-azure-native/issues/1112. Unfortunately, given we don't mange the implementation of the resource behaviours directly for this provider, we would be unable to address this problem directly.
Please let me know if I've mis-understood your problem or if you have any follow-up questions.
Hi @c-falardeau I think I re-created the issue using just your code for the the Application and
ApplicationRedirectUris
:using Pulumi; using Pulumi.AzureAD; return await Pulumi.Deployment.RunAsync(() => { var application = new Application( "MyAppRegistration", new ApplicationArgs { DisplayName = "MyAppRegistrationDisplayNAme", SignInAudience = "AzureADMultipleOrgs", Owners = new InputList<string> { "REPLACE_WITH_OBJECT_ID" }, } ); _ = new ApplicationRedirectUris( "MyAppRegistrationRedirectUris", new ApplicationRedirectUrisArgs { ApplicationId = application.Id, RedirectUris = new InputList<string> { "https://localhost:3000" }, Type = "Web" } ); });
Steps:
- Deploy
- Update owner and re-deploy
- Refresh - see that
MyAppRegistrationRedirectUris
has been deletedDoes that accurately summarise your issue above?
Cause
The
ApplicationRedirectUris
is also a sub-property of theApplication
resource. The above code is equivelent to:return await Pulumi.Deployment.RunAsync(() => { var application = new Application( "MyAppRegistration", new ApplicationArgs { DisplayName = "MyAppRegistrationDisplayNAme", SignInAudience = "AzureADMultipleOrgs", Owners = new InputList<string> { "db8fa9c3-36b4-4474-91b0-aa96bcc706bc" }, // <---- When this change, the API permission are lost, but pulumi doesn't know. So run pulumi up multiple times with different owners Web = new ApplicationWebArgs { RedirectUris = new InputList<string> { "https://localhost:3000" } } } ); });
This is a slightly odd design of the upstream provider to provide both methods of specifying the
RedirectUris
and results in unexpected behaviour when updating the original resource having made changes via the secondary resources (such asApplicationRedirectUris
). When you make any change to the originalApplication
resource it entirely overwrites the state of the resource, inadvertantly removing theRedirectUris
configuration which manifests as the deletion ofMyAppRegistrationRedirectUris
on the next refresh.You can also see this by:
- Performing a clean deployment of the original code
- Run a refresh. This will show the property being populated on the
Application
resource to reflect the change made by the standalone resource.Workaround
Where there's conflicts betwen a feature being managed as part of the parent and as it's own resource, it's recommended to only manage the feature via the property on the parent and not as an external resource. This will ensure the lifecycle isn't broken
Addressing the core issue
This would need to be fixed in the core provider implementation. You can search for existing issues or open a new issue if one doesn't yet exist here: https://github.com/hashicorp/terraform-provider-azuread
We've had similar issues in the Azure Native provider historically and have been able to resolve this issue by introducing resource parent-child awareness to allow parts of the parent resource to be managed via standalone resources: pulumi/pulumi-azure-native#1112. Unfortunately, given we don't mange the implementation of the resource behaviours directly for this provider, we would be unable to address this problem directly.
Please let me know if I've mis-understood your problem or if you have any follow-up questions.
Hello danielrbradley, thanks you for you response.
Yes it matches the behavior well, but I can only confirm reproducing the behavior for the Owners fields. Other child resources or fields we did not tested thoroughly
Do I need to do something else at this stage ?
Best regards.
Hi @c-falardeau, there's nothing else to do here at this point except the two points Workaround and Addressing the core issue outlined by Daniel above. Should the workaround not work for you, please report back here.
What happened?
When updating the app registration configuration after resource is already created in Azure (different run and commit), the API permissions are reset, but pulumi still contain them in the stack state file. The result is that pulumi won't put them back in the Azure resource, because it thinks they are already there because of the state file.
It happened when updating the Owners configuration. I don't know if there are other properties that trigger this. So to work around this, we need to run pulumi refresh (the API permissions will be deleted from the state file) and then pulumi up (the API permissions will be recreated)
Example
Output of
pulumi about
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).