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 Azure PostgreSQL managed identity #5930

Merged
merged 5 commits into from
Oct 1, 2024

Conversation

eerhardt
Copy link
Member

@eerhardt eerhardt commented Sep 25, 2024

Description

  • Add a new API to replace AsAzure and PublishAsAzure. This creates an Azure resource to start, so it can be configured like other azure resources. Since this is a new API, we can use managed identity by default.

  • Add an API to convert managed identity to password based auth, so users can still go that route if they need to.

  • Add RunAsContainer following the RunAsEmulator model. This allows local development against a PostreSQL container and publish to go to a manged Azure PostgreSQL flexible server.

Fix #5793

Checklist

Microsoft Reviewers: Open in CodeFlow

eerhardt added a commit to eerhardt/aspire that referenced this pull request Sep 26, 2024
Similar to dotnet#5930, we add a new API pattern for working with Azure resources that may also be local containers.

- Add a new API to replace AsAzure and PublishAsAzure. This creates an Azure resource to start, so it can be configured like other azure resources. Since this is a new API, we can use managed identity by default.

- Add an API to convert managed identity to password based auth, so users can still go that route if they need to.

- Add RunAsContainer following the RunAsEmulator model. This allows local development against a Redis container and publish to go to a manged Azure Cache for Redis.

Fix dotnet#5794
@eerhardt eerhardt force-pushed the PostgresManagedIdentity branch from 1c73ff2 to 38f0274 Compare September 27, 2024 23:22
eerhardt added a commit that referenced this pull request Sep 27, 2024
* Support Managed Identity in Azure Cache for Redis

Similar to #5930, we add a new API pattern for working with Azure resources that may also be local containers.

- Add a new API to replace AsAzure and PublishAsAzure. This creates an Azure resource to start, so it can be configured like other azure resources. Since this is a new API, we can use managed identity by default.

- Add an API to convert managed identity to password based auth, so users can still go that route if they need to.

- Add RunAsContainer following the RunAsEmulator model. This allows local development against a Redis container and publish to go to a manged Azure Cache for Redis.

Fix #5794
@davidfowl
Copy link
Member

davidfowl commented Sep 28, 2024

@eerhardt Can you do this as well #3299? I think postgres is the only database that we need to fix.

See #3277. It should be a simple change to the bicep.

@mitchdenny
Copy link
Member

@eerhardt is this something you want to get in for 9.0 or 9.x?

@mitchdenny
Copy link
Member

The downside of this approach is composability of resources. Let's say I wanted to have a resource that depended on a Postgres database instance. With this change the implementor of that would need to have extensions for each cloud provider (unless they just allow any IResourceWithConnectionString).

@davidfowl
Copy link
Member

The downside of this approach is composability of resources. Let's say I wanted to have a resource that depended on a Postgres database instance. With this change the implementor of that would need to have extensions for each cloud provider (unless they just allow any IResourceWithConnectionString).

That can be solved with an IPostgresResource interface right?

@eerhardt
Copy link
Member Author

@eerhardt is this something you want to get in for 9.0 or 9.x?

9.0. Azure PostgreSQL should support managed identity (dotnet/aspire#5793) is in the 9.0 milestone.

@eerhardt
Copy link
Member Author

The downside of this approach is composability of resources. Let's say I wanted to have a resource that depended on a Postgres database instance. With this change the implementor of that would need to have extensions for each cloud provider (unless they just allow any IResourceWithConnectionString).

We already have a "composability of resources" problem with the current API. You can't call .ConfigureConstruct on the Azure resource for Postgres. Even worse - there is no Azure resource for Postgres in the model. So if you wanted to add an event to inspect all the resources (and possibly modify them), you won't see the AzurePostgresResource resource in the model.

That can be solved with an IPostgresResource interface right?

Yes, we can add that, if necessary.

@eerhardt eerhardt force-pushed the PostgresManagedIdentity branch from a5d6f5d to c272c30 Compare September 30, 2024 22:56
- Add a new API to replace AsAzure and PublishAsAzure. This creates an Azure resource to start, so it can be configured like other azure resources. Since this is a new API, we can use managed identity by default.

- Add an API to convert managed identity to password based auth, so users can still go that route if they need to.

- Add RunAsContainer following the RunAsEmulator model. This allows local development against a PostreSQL container and publish to go to a manged Azure PostgreSQL flexible server.

Fix dotnet#5793
Add Obsolete to old APIs
Fix up playground apps.
@eerhardt eerhardt force-pushed the PostgresManagedIdentity branch from c272c30 to e3e903a Compare September 30, 2024 23:00
@eerhardt eerhardt marked this pull request as ready for review September 30, 2024 23:01
@eerhardt
Copy link
Member Author

This PR is ready for review. I believe I have everything ready for this to be merged.

@@ -98,7 +99,7 @@ param outputs_azure_container_apps_environment_id string
}
}
""";

output.WriteLine(bicep);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You want this for when the bicep changes and you need to update it. You can copy and paste the new output from the test log

@mitchdenny
Copy link
Member

I believe it would be good to add an IPostgresResource interface (or add a follow-up for this).

var pg = builder.AddPostgres("postgres2", administratorLogin, administratorLoginPassword)
.AsAzurePostgresFlexibleServer()
var pg = builder.AddAzurePostgresFlexibleServer("postgres2")
.WithPasswordAuth(administratorLogin, administratorLoginPassword)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be WithPasswordAuthentication?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I chose these names (WithPasswordAuth here and WithAccessKeyAuth in Reds) is because they match the APIs from Azure.Provisioning (which I assume just match the names in the rest API).

postgres.AuthConfig = new PostgreSqlFlexibleServerAuthConfig()
{
ActiveDirectoryAuth = PostgreSqlFlexibleServerActiveDirectoryAuthEnum.Enabled,
PasswordAuth = PostgreSqlFlexibleServerPasswordAuthEnum.Disabled
};

But looking again at Redis, the name is DisableAccessKeyAuthentication, which is inconsistent with the above Postgres APIs. So it is probably better we just completely follow .NET Design Guidelines with our APIs here and use full words.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI - @tg-msft. I'm assuming this isn't something we can change/fix in Azure.Provisioning since it is just generated from the service APIs / typespec.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do an API review, WithAccessKey is not intuitive. We should take the liberty here to add some opinions to this layer of the stack. We can do this in a follow up PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WithAccessKey is not intuitive

Where is that? For Redis it is:

        var redis = builder.AddAzureRedis("cache")
            .WithAccessKeyAuthentication();

now that I renamed Auth to be Authentication.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philon-msft - is there a reason that the portal / ARM use the term "access key"?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Azure Redis doesn't let you choose your own (like a "password") - instead it generates one for you (more like an "access key").
So in general Redis terminology it's a password, but for Azure Redis it's an access key.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, it's passwordAuth on the wire and we're not looking to deviate from our automated translation of the existing ARM experience. There's no way Azure.Provisioning would scale to all of Azure otherwise.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Azure Redis doesn't let you choose your own (like a "password") - instead it generates one for you (more like an "access key"). So in general Redis terminology it's a password, but for Azure Redis it's an access key.

Does Azure Redis let me add users with their own passwords and ACLs?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not standard Redis users+passwords, but you can add Entra users/apps/ManagedIdentities and assign them to roles for ACL functionality. See doc for the Entra experience

@mitchdenny
Copy link
Member

Overall I think this looks good. I do think that there is another approach we could take here (just putting it out there for sake of completeness.

We could do this:

var builder = DistributedApplication.Create(args);
var db = builder.AddPostgres("pgsql").AsAzure(out var azpgsql).AddDatabase("db");
azpgsql.DoAzureyApiStuff();

Folks have historically avoided out vars but we see them a lot more these days. All that said I think your approach here is fine.

Copy link
Member

@davidfowl davidfowl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@eerhardt eerhardt enabled auto-merge (squash) October 1, 2024 15:19
@eerhardt eerhardt merged commit 00ae9c6 into dotnet:main Oct 1, 2024
9 checks passed
@eerhardt
Copy link
Member Author

eerhardt commented Oct 1, 2024

I believe it would be good to add an IPostgresResource interface (or add a follow-up for this).

Opened Add interfaces to PostgreSQL, Redis, and SqlServer Hosting Resources (dotnet/aspire#6055)

@eerhardt eerhardt deleted the PostgresManagedIdentity branch October 1, 2024 19:18
@github-actions github-actions bot locked and limited conversation to collaborators Nov 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Azure PostgreSQL should support managed identity
5 participants