PostgreSQL efcore connection string from multiple environment variables
- Dominant language
- C#
- Stars
- 6.3k
- Forks
- 991
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 196
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Is your feature request related to a problem? Please describe the problem.
### Scope
There have been multiple issues regarding how Aspire should provide connection string components as separate environment variables to consuming applications, but my issue is about **connecting a dotnet application to a PostgreSQL database**, using either `Aspire.Npgsql.EntityFrameworkCore.PostgreSQL` or `Aspire.Npgsql`.
It probably applies to many Aspire client library for other ressources.
### Context
In my specific case, I'm developping a dotnet application that uses a PostgreSQL database for data storage. The application architecture includes an S3 bucket and a RabbitMQ exchange. I'm using Aspire as a convenient way to orchestrate all these technlogies locally for development purposes. But then, I'm supposed to publish my application to a K8S cluster for production.
My company provides a cluster with CNCF CloudNativePG which provisions PostgreSQL clusters and databases as K8S resources. This Kubernetes operator generates random credentials for accessing databases under the form of a Kubernetes secret resources which provide connection information in atomic values (host, port, username, password, etc ...).
The good practice with Kubernetes is to mount secret values into pods as environment variables through `secretKeyRef` in the deployment resource.
### Problem
Unfortunately, that feature is not capable of secrets transformation, so I can't compose the different parts into a connection string. Besides, CloudNativePG does not provide connection string secret (in either dotnet or jdbc format). Also, both `Aspire.Npgsql.EntityFrameworkCore.PostgreSQL` and `Aspire.Npgsql` expect credentials to be provided as connection strings. If the connection string is not present, the libraries will not look after individual environment variables to compose one by themselves.
### Workarounds
One workaround is to create another secret containing the connection string by copying the individual values from the other secrets. The problem with this is, if for whatever reason our ops need to rotate the database credentials, the connection string in the pod will not update. It requires manual intervention to update the connection string secret once the CloudNativePG has rotated.
Another workaround is to write a connection string provider that will build the connection string from atomic environment variables in a DbContextFactory. This basically defeats the benefit of using an Aspire client lib with resources discovery.
### Documentation
[Read environment variables in C#](https://aspire.dev/fr/integrations/databases/postgres/postgres-connect/#read-environment-variables-in-c) explains that you basically read the environment and pass it to the non-Aspire lib, but that is still connection string based. It points towards documentation on how to provide custom environment varaibles to the application, but does not document how to consume standard Aspire environment variables (such as using an `NpgsqlConnectionStringBuilder`), despite extensively documenting how Aspire provides values under `[RESOURCE]_[PROPERTY]` environment variables.
### Describe the solution you'd like
I think fallback to atomic environment variables should be available natively in the client libraries.
Whether that should be *enabled* by default is very different question, though.
### Additional context
_No response_
Contributor guide
Assessment
This issue has not been assessed yet.