Skip to content

Add support for Keycloak deployment to ACA #8478

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

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

anderly
Copy link

@anderly anderly commented Apr 1, 2025

Description

Per #6004, deploying a container provisioned via the Keycloak integration won't start in Azure Container Apps (ACA).

ACA will try to activate it, but it continuously fails.

The container reports this in the logs:

Key material not provided to setup HTTPS. Please configure your keys/certificates or start the server in development mode.

This PR includes a basic starting point for changes required to get Keycloak working in Azure Container Apps.

See my comment on #6004 showing what is necessary to get Keycloak working on ACA.

Currently, this only outputs the additional env vars if the passed port is 8443. Otherwise, it behaves as before for local dev scenarios. Open to making additional changes based on review and suggestions, but wanted to show bare minimum to get it working and be able to support ACA and SSL.

To opt-in to this configuration for deployment to ACA, users would simply specify port 8443 in the call to AddKeycloak like so:

var keycloak = builder.AddKeycloak("keycloak", 8443);

OR

var port = builder.Environment.IsDevelopment() ? 8080 : 8443;
var keycloak = builder.AddKeycloak("keycloak", port);

Another option would be an explicit Publish extension method similar to PublishAsAzurePostgresFlexibleServer on IResourceBuilder<KeycloakResource> builder for more fine-grained control over these settings.

The changes in this PR output 3 additional env vars:

    KC_HTTP_ENABLED=true
    KC_PROXY-HEADERS=xforwarded
    KC_HOSTNAME-STRICT=false

Since ACA includes TLS termination at the Envoy proxy, we're setting KC_HTTP_ENABLED=true per https://www.keycloak.org/server/hostname#_using_edge_tls_termination and KC_PROXY-HEADERS=xforwarded per https://www.keycloak.org/server/reverseproxy#_configure_the_reverse_proxy_headers.

Technically, KC_HOSTNAME-STRICT doesn't have to be false and shouldn't be for prod configurations, but if it's not, KC_HOSTNAME env var also has to be provided (see here) and needs to match the ACA container url or a configured custom domain. We could make the inclusion of KC_HOSTNAME conditional with an additional param on the AddKeycloak extension method to, optionally, provide a custom domain which would be used to set the KC_HOSTNAME variable. Or, we'd need to always set KC_HOSTNAME to match the generated container url (https://container-app-name.randomwords-digits.centralus.azurecontainerapps.io) or use a custom domain as KC_HOSTNAME if specified.

Fixes #6004

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

@github-actions github-actions bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Apr 1, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Apr 1, 2025
@anderly
Copy link
Author

anderly commented Apr 1, 2025

@dotnet-policy-service agree

@anderly anderly changed the title Add support for deployment to aca and ssl. Add support for deployment to ACA and SSL. Apr 1, 2025
@anderly anderly changed the title Add support for deployment to ACA and SSL. Add support for Keycloak deployment to ACA Apr 2, 2025
@davidfowl davidfowl requested a review from DamianEdwards April 2, 2025 03:34
@eerhardt eerhardt added area-integrations Issues pertaining to Aspire Integrations packages and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Apr 2, 2025
.WithHttpEndpoint(targetPort: ManagementInterfaceContainerPort, name: ManagementEndpointName)
.WithHttpHealthCheck(endpointName: ManagementEndpointName, path: "/health/ready")
.WithEnvironment(context =>
{
context.EnvironmentVariables[AdminEnvVarName] = resource.AdminReference;
context.EnvironmentVariables[AdminPasswordEnvVarName] = resource.AdminPasswordParameter;
context.EnvironmentVariables[HealthCheckEnvVarName] = "true";
if (port == HttpsContainerPort) {
Copy link
Member

Choose a reason for hiding this comment

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

I'm not following why this is the predicate for setting all the config to setup Keycloak for running behind a reverse proxy. My reading of this is that when the user specifies the port to be 8443, we configure the Keycloak container as if it's running behind a reverse proxy, but also enable non-HTTPS? How is it expected this will be used, i.e. what will the app host code look like?

Copy link
Author

@anderly anderly Apr 23, 2025

Choose a reason for hiding this comment

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

Ok. I've simplified this quite a bit with recent commit for bare minimum for running behind reverse proxy and leveraging existing ACA TLS edge termination.

So, no changes to app host code or usage. This just outputs 3 additional env vars:

    KC_HTTP_ENABLED=true
    KC_PROXY-HEADERS=xforwarded
    KC_HOSTNAME-STRICT=false

Since ACA includes TLS termination at the Envoy proxy, we're setting:

Technically, KC_HOSTNAME-STRICT doesn't have to be false and shouldn't be for prod configurations, but if it's not, KC_HOSTNAME env var also has to be provided (see here) and needs to match the ACA container url or a configured custom domain. We could make the inclusion of KC_HOSTNAME conditional with an additional param on the AddKeycloak extension method to, optionally, provide a custom domain which would be used to set the KC_HOSTNAME variable. Or, we'd need to always set KC_HOSTNAME to match the generated container url (https://container-app-name.randomwords-digits.centralus.azurecontainerapps.io) or use a custom domain as KC_HOSTNAME if specified.

Copy link
Member

Choose a reason for hiding this comment

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

I think configuring Keycloak for operation behind a reverse proxy needs to be behind a method call, rather than having these items always set. Setting KC_HOSTNAME to the URL associated with the endpoint as part of deployment should be doable via an EndpointReference. Deployment takes care of ensuring the required value is populated.

Copy link
Author

@anderly anderly Apr 23, 2025

Choose a reason for hiding this comment

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

That makes sense as I did mention in my initial PR description that I thought a dedicated Publish method similar to PublishAsAzurePostgresFlexibleServer might be preferred.

So, maybe we wrap this additional config in PublishAsAzureContainerApp or WithReverseProxy extension method which could set the KC_HTTP_ENABLED and KC_PROXY-HEADERS env vars and the KC_HOSTNAME could be derived from the EndpointReference and or a custom domain, if provided, via param on the new method.

Let me know if that jives with the direction you're thinking.

Copy link
Member

Choose a reason for hiding this comment

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

Something like WithReverseProxy I think is the basic building block. Folks can then put that behind an if check for publish mode. We can consider introducing something like PublishWithReverseProxy if we want to make that a wider pattern (it isn't today, but I for one think we should consider it).

@anderly anderly force-pushed the feature/add-keycloak-aca-support branch from 681774b to 3f24659 Compare April 23, 2025 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-integrations Issues pertaining to Aspire Integrations packages community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Keycloak container fails to start in Azure Container Apps
3 participants