This sample demonstrates Elsa Workflows running on Aspire with a distributed Elsa Server, Elsa Studio, PostgreSQL, RabbitMQ, and Keycloak.
The application consists of:
- Elsa Studio
- Elsa Server running with two replicas and distributed runtime support
- PostgreSQL for persistence
- RabbitMQ for server node communication
- Keycloak for OpenID Connect authentication
- .NET SDK
10.0.107, pinned byglobal.json - Aspire
13.2.4 - Elsa
3.6.1 - Elsa Studio
3.6.1 - Aspire Keycloak and Kubernetes hosting integrations
13.2.4-preview.1.26224.4
The dedicated Elsa Studio OpenID Connect packages exist, but they are currently RC/preview packages (Elsa.Studio.Authentication.OpenIdConnect*). This repository stays on the stable Elsa Studio line and uses a small Keycloak module around Elsa Studio Login's OpenID Connect hooks.
- .NET 10 SDK
- Docker
- Aspire CLI, if you want to use
aspire runoraspire publish
Verify the pinned SDK:
dotnet --versionRun the AppHost with the HTTP launch profile:
dotnet run --project ./Elsa.Aspire.AppHost/Elsa.Aspire.AppHost.csproj --launch-profile httpOpen the Aspire dashboard URL printed by the AppHost. From there, open the elsastudio resource. The Studio endpoint is normally:
http://localhost:5051
The local Keycloak endpoint is pinned to a stable port so OpenID Connect issuer values do not drift between AppHost restarts:
http://localhost:18080
Keycloak imports the Elsa realm and ElsaServer public client from Elsa.Aspire.AppHost/Realms/realm-export.json.
There is no seeded application user in the checked-in realm. For local Studio testing:
- Open Elsa Studio.
- Follow the redirect to Keycloak.
- Click
Register. - Create any local test user.
- Use that user for subsequent Studio logins.
Self-registration is enabled and email verification is disabled in the demo realm. The Keycloak admin account is generated by the local Aspire/Keycloak runtime and should not be committed to the repository.
If a browser was signed in before the Keycloak port was pinned, sign out from Studio or clear the localhost cookies once. Old cookies can contain tokens whose issuer points at a previous dynamic Keycloak port.
The ElsaServer Keycloak client issues access tokens with the ElsaServer audience. Elsa Server validates this audience before accepting Studio API calls.
Elsa uses FastEndpoints permissions for authorization. For demo purposes, an IClaimsTransformation adds * permission to authenticated users.
TimerHelloWorldWorkflow is registered by the Elsa Server. It runs every 15 seconds and logs:
Hello World from the Elsa timer workflow.
Database passwords need to be consistent between app launches when using persistent volumes. Set the Postgres password in user secrets:
dotnet user-secrets set "Parameters:postgres-password" "<password>" --project ./Elsa.Aspire.AppHost/Elsa.Aspire.AppHost.csprojSee Persist data using volumes for the underlying Aspire behavior.
Aspire now has first-party publishing support for Kubernetes. The AppHost includes a Kubernetes compute environment named k8s, so deployment artifacts can be generated with:
aspire publish -o k8s-artifactsFor Kubernetes, Aspire generates Helm chart artifacts. It does not currently run aspire deploy for Kubernetes; deploy the generated chart with Helm, kubectl, or your GitOps workflow:
helm install elsa-aspire ./k8s-artifacts