-
Notifications
You must be signed in to change notification settings - Fork 147
Add Keycloak with Postgres integration #811
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
Conversation
- Introduced a new project `CommunityToolkit.Aspire.Keycloak.Postgress` for configuring Keycloak with PostgreSQL. - Added an extension method to simplify Keycloak and Postgres database resource integration. - Updated solution and package references for Aspire dependencies.
|
Did you test this? |
- Enhanced parameter descriptions in XML documentation. - Updated method to support asynchronous operations. - Introduced additional environment variables for finer-grained database configuration. - Added cancellation token support for improved task management.
|
I have some problems, i can't access host, can you help me? |
- Simplified XML documentation and parameter descriptions. - Removed exceptions for parent resource validation. - Replaced manual environment variable setup with connection string parsing using `NpgsqlConnectionStringBuilder`. - Introduced optional port parameter for database configuration.
|
Now it working |
|
Its worth reading this https://github.com/dotnet/aspire/blob/main/docs/specs/appmodel.md#values-and-references |
Directory.Packages.props
Outdated
| <ItemGroup Label="Aspire Packages"> | ||
| <!-- Aspire packages --> | ||
| <PackageVersion Include="Aspire.Hosting" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Aspire.Hosting" Version="9.4.1" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is just done when you were testing, but ensure you roll that back and use the MSBuild variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had error
0>CommunityToolkit.Aspire.Keycloak.Postgres.csproj: Error NU1605 : Warning As Error: Detected package downgrade: Aspire.Hosting from 9.4.1 to 9.4.0. Reference the package directly from the project to select a different version.
CommunityToolkit.Aspire.Keycloak.Postgres -> Aspire.Hosting.Keycloak 9.4.1-preview.1.25408.4 -> Aspire.Hosting (>= 9.4.1)
CommunityToolkit.Aspire.Keycloak.Postgres -> Aspire.Hosting (>= 9.4.0)
0>------- Finished building project: CommunityToolkit.Aspire.Keycloak.Postgres. Succeeded: False. Errors: 1. Warnings: 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main branch is now updated to 9.4.1 Aspire.
|
Once there are tests and samples, we can get started on a review of the work. |
|
This implemenaton needs work:
See dotnet/aspire#8034 for more details. |
Alirexaa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package name should be CommunityToolkit.Aspire.Keycloak.Extensions, like other extension packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package name should be CommunityToolkit.Aspire.Keycloak.Extensions, like other extension packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can i name it like CommunityToolkit.Aspire.Keycloak.Extensions.Postgres?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there may be other providers here.
src/CommunityToolkit.Aspire.Keycloak.Postgress/KeycloakPostgresExtension.cs
Outdated
Show resolved
Hide resolved
…sExtension.cs Co-authored-by: Alireza Baloochi <alireza.baloochi1380@gmail.com>
- Renamed `CommunityToolkit.Aspire.Keycloak.Postgress` to `CommunityToolkit.Aspire.Keycloak.Extensions.Postgres`. - Refactored methods to improve flexibility, including support for different configurations (e.g., development, credentials). - Introduced a dedicated test project `CommunityToolkit.Aspire.Keycloak.Extensions.Postgres.Tests`. - Updated solution, dependencies, and project references accordingly.
|
I updated, add event as dev and add parameters for production |
| /// <returns> | ||
| /// The updated resource builder for the Keycloak resource. | ||
| /// </returns> | ||
| private static void WithPostgres(this IResourceBuilder<KeycloakResource> builder, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will work with dev and production.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean void? After that, you can't add other methods, so I returned IResourceBuilder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I mean that this approach using expressions works in both cases and you don’t need 2 implementations for run and publish
| /// <returns> | ||
| /// The updated resource builder for the Keycloak resource. | ||
| /// </returns> | ||
| public static IResourceBuilder<KeycloakResource> WithPostgresDev(this IResourceBuilder<KeycloakResource> builder, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need this overload at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You said that event will not work in prod, so I thought that this i will leave for the development environment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right so you don’t need this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There can be conditional logic to check for the different modes rather than having to call different methods.
| $"jdbc:postgresql://{ep.Property(EndpointProperty.Host)}:" + | ||
| $"{ep.Property(EndpointProperty.Port)}/{dbName}"); | ||
|
|
||
| builder.WithEnvironment("KC_DB", "postgres") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? Why is this hard coded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if postgres is password protected (which is the default).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
builder.WithEnvironment("KC_DB", "postgres")
You about this? Yeah, it's correct. There are other database vendors, but I'm writing for postgres
All environment variables: https://www.keycloak.org/server/all-config
I wanna make for other vendors such as dev-file (default), dev-mem, mariadb, mssql, mysql, oracle, postgres (all vendors that support)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if postgres is password protected (which is the default).
public static IResourceBuilder<KeycloakResource> WithPostgres(this IResourceBuilder<KeycloakResource> builder,
IResourceBuilder<PostgresDatabaseResource> database, ParameterResource username, ParameterResource password)
{
ArgumentNullException.ThrowIfNull(username);
ArgumentNullException.ThrowIfNull(password);
WithPostgres(builder, database);
builder.WithEnvironment("KC_DB_USERNAME", username)
.WithEnvironment("KC_DB_PASSWORD", password);
return builder;
}Here I'm setting by parameter that will set up from user, or what you mean?
aaronpowell
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a hosting integration by the looks of it, so the project should reflect that.
Also, let's just make it Keycloak.Extensions so it's not PG specific, as that'll allow for other extensions on Keycloack to be included in here rather than going through a bunch of micro packages.
...ire.Keycloak.Extensions.Postgres/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres.csproj
Outdated
Show resolved
Hide resolved
| /// <returns> | ||
| /// The updated resource builder for the Keycloak resource. | ||
| /// </returns> | ||
| public static IResourceBuilder<KeycloakResource> WithPostgresDev(this IResourceBuilder<KeycloakResource> builder, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There can be conditional logic to check for the different modes rather than having to call different methods.
| <PropertyGroup> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| <IsPackable>false</IsPackable> | ||
| </PropertyGroup> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These aren't needed as they are inherited. Check the other test projects and follow their patterns
| <PackageReference Include="coverlet.collector" Version="6.0.2"/> | ||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/> | ||
| <PackageReference Include="xunit" Version="2.9.2"/> | ||
| <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2"/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These will fail the build as CPM dictates versions
Directory.Packages.props
Outdated
| <ItemGroup Label="Aspire Packages"> | ||
| <!-- Aspire packages --> | ||
| <PackageVersion Include="Aspire.Hosting" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Aspire.Hosting" Version="9.4.1" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main branch is now updated to 9.4.1 Aspire.
Directory.Packages.props
Outdated
| <PackageVersion Include="Aspire.Hosting.Dapr" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Aspire.Hosting.Azure.AppContainers" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Aspire.Hosting.Azure.Redis" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Aspire.Hosting.Keycloak" Version="9.4.1-preview.1.25408.4" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to introduce a MSBuild variable for the preview version of Aspire packages.
Directory.Packages.props
Outdated
| <PackageVersion Include="Aspire.Hosting.MongoDB" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Aspire.Hosting.MySql" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Aspire.Hosting.SqlServer" Version="$(AspireVersion)" /> | ||
| <PackageVersion Include="Moq" Version="4.20.72" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be under the Testing item group
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a new Keycloak-PostgreSQL integration that enables configuring Keycloak resources to use PostgreSQL databases within Aspire applications. The integration provides extension methods to set up the necessary JDBC connection strings and environment variables required by Keycloak to connect to PostgreSQL databases.
- Extension methods for integrating Keycloak with PostgreSQL databases
- Support for both development and production scenarios with different credential handling approaches
- Package reference updates to align with Aspire 9.4.1 dependencies
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/KeycloakPostgresExtension.cs | Core extension methods for Keycloak-PostgreSQL integration |
| src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres.csproj | Project file with necessary Aspire package references |
| tests/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres.Tests/KeycloakExtensionPostgressTests.cs | Empty test class placeholder |
| tests/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres.Tests/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres.Tests.csproj | Test project configuration |
| Directory.Packages.props | Updated Aspire package versions and added new dependencies |
| CommunityToolkit.Aspire.slnx | Solution file updated with new projects |
src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/KeycloakPostgresExtension.cs
Outdated
Show resolved
Hide resolved
src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/KeycloakPostgresExtension.cs
Outdated
Show resolved
Hide resolved
src/CommunityToolkit.Aspire.Keycloak.Extensions.Postgres/KeycloakPostgresExtension.cs
Outdated
Show resolved
Hide resolved
| builder.WithEnvironment("KC_DB", "postgres") | ||
| .WithEnvironment("KC_DB", "postgres") |
Copilot
AI
Aug 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The environment variable 'KC_DB' is being set twice with the same value 'postgres'. Remove the duplicate line 68.
| builder.WithEnvironment("KC_DB", "postgres") | |
| .WithEnvironment("KC_DB", "postgres") |
…oakPostgresExtension.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…oakPostgresExtension.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…oakPostgresExtension.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
public static IResourceBuilder<KeycloakResource> WithPostgres(this IResourceBuilder<KeycloakResource> builder,
IDistributedApplicationBuilder appBuilder, bool xaEnabled = false,
string usernameParameter = "keycloak-username", string databaseName = "keycloak-db",
string postgrsName = "keycloak-postgres")
{
var username = appBuilder.AddParameter(usernameParameter, "keycloak-db-user");
var pwd = ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter(appBuilder, "pg-pass");
var password = appBuilder.CreateResourceBuilder(pwd);
var keycloakPostgres = appBuilder.AddPostgres(postgrsName, username, password);
var db = keycloakPostgres.AddDatabase(databaseName);
builder.WithPostgres(db, username, password, xaEnabled)
.WithReference(db)
.WaitFor(keycloakPostgres);
return builder;
}What you think about this method for easy dev environment? |
aaronpowell
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've gone ahead and fixed the outstanding issues and it's now ready to merge.
This PR introduces a new integration project that makes it easier to configure Keycloak to run with a Postgres database in Aspire-based applications.
Summary of changes
Added new project CommunityToolkit.Aspire.Keycloak.Postgres.
Implemented an extension method AddPostgres for IResourceBuilder to configure Keycloak with Postgres database resources:
Sets required environment variables (KC_DB, KC_DB_URL_*, KC_DB_USERNAME, KC_DB_PASSWORD, KC_TRANSACTION_XA_ENABLED).
Includes validation for missing or invalid Postgres server configuration.
Updated solution and package references to align with Aspire 9.4.1 dependencies.
Other information
Project name normalized to Postgres for correctness and consistency.
Extension method returns IResourceBuilder to allow chaining.
Uses proper IValueExpression instead of ToString() for connection strings.
Ensures JDBC-compatible environment variables for Keycloak.