From 8107d7303c2b133b1c48e23c3f6b05aca52c192e Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Thu, 27 Aug 2026 18:52:20 -0700 Subject: [PATCH 1/2] docs: explain PostgreSQL secret connections Signed-off-by: willdavsmith --- .../getting-started/add-connection/_index.md | 36 +++++++++++-------- docs/static/samples/demo/app-postgresql.bicep | 18 ++++++++++ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/docs/content/getting-started/add-connection/_index.md b/docs/content/getting-started/add-connection/_index.md index 84005af4a..d2eb8cd85 100644 --- a/docs/content/getting-started/add-connection/_index.md +++ b/docs/content/getting-started/add-connection/_index.md @@ -6,37 +6,43 @@ description: "Add a PostgreSQL database and connect the Radius Demo container to weight: 300 --- -The Radius Demo application runs on its own, but most applications depend on other resources such as databases and caches. In this step you will add a PostgreSQL database to the application and create a *connection* from the container to it. +The Radius Demo application runs on its own, but most applications depend on other resources such as databases and caches. In this step you will add a PostgreSQL database and an authored Secret to the application, then connect the container to both resources. -## Add a PostgreSQL database and connection +## Add a PostgreSQL database and connections -The `app-postgresql.bicep` definition builds on `app.bicep` by adding a `Radius.Data/postgreSqlDatabases` resource, a `@secure()` password parameter, and a `connections` entry on the container. The highlighted lines are the additions: +The `app-postgresql.bicep` definition builds on `app.bicep` by adding a `Radius.Data/postgreSqlDatabases` resource, a `Radius.Security/secrets` resource, a `@secure()` password parameter, and two `connections` entries on the container. The highlighted lines are the additions: -{{< rad file="/static/samples/demo/app-postgresql.bicep" embed=true markdownConfig=` {hl_lines=["6-8","36-40","44-54"]}` >}} +{{< rad file="/static/samples/demo/app-postgresql.bicep" embed=true markdownConfig=` {hl_lines=["6-8","36-43","47-57","59-72"]}` >}} -The `postgresql` resource is provisioned by the PostgreSQL recipe in the default Recipe Pack. The `password` parameter is declared with `@secure()`, which keeps its value out of deployment logs and history and lets you supply the password at deploy time instead of hardcoding it. Because the `password` property is `x-radius-sensitive` on the Resource Type, Radius also encrypts it and redacts it from reads. +The `postgresql` resource is provisioned by the PostgreSQL Recipe in the default Recipe Pack. The `password` parameter is declared with `@secure()`, which keeps its value out of deployment logs and history and lets you supply the password at deploy time instead of hardcoding it. The application passes that value directly to the database's `password` property. Because the property is `x-radius-sensitive`, Radius encrypts it and redacts it from reads. -The `connections` entry tells Radius that the container depends on the database. Radius provisions the database first, then injects its connection details into the container as environment variables named `CONNECTION_POSTGRESQL_`, such as `CONNECTION_POSTGRESQL_HOST` and `CONNECTION_POSTGRESQL_PORT`. +The application also stores the same value under the `password` key of the authored `postgresqlClientCredentials` Secret instead of relying on database Recipe `result.secrets` for a developer-owned credential. The Secret has the same application and environment as the other resources, so it shares their lifecycle. Its resource name is deliberately different from the `postgresql-${environmentName}-credentials` Kubernetes Secret owned by the PostgreSQL Recipe. + +The `postgresql` connection tells Radius that the container depends on the database. Radius provisions the database first, then injects its ordinary connection values as `CONNECTION_POSTGRESQL_HOST`, `CONNECTION_POSTGRESQL_PORT`, `CONNECTION_POSTGRESQL_DATABASE`, and `CONNECTION_POSTGRESQL_USERNAME`. + +The `postgresqlcredentials` connection points directly to the authored Secret. With a compatible Kubernetes Container Recipe, Radius projects its `password` key through a Kubernetes `secretKeyRef` as `CONNECTION_POSTGRESQLCREDENTIALS_PASSWORD`. The secret value remains in the Secret and is not copied into Recipe output or plaintext container configuration. + +> **Compatibility:** Automatic Secret connection projection requires a compatible Radius runtime and Kubernetes Container Recipe. In older or mixed-version environments, keep an explicit container `env.valueFrom.secretKeyRef` binding instead of changing a working model. Azure Container Instances behavior is unchanged. ## Redeploy the application -Deploy the updated definition from its published URL. The `--parameters password=` flag sets the database password, and `$(openssl rand -hex 16)` generates a random value on each deploy. This works in Bash and Zsh; in PowerShell, generate the value separately and pass it in: +Deploy the updated definition from its published URL. The `--parameters` argument sets the database password, and `$(openssl rand -hex 16)` generates a random value on each deploy. This works in Bash and Zsh; in PowerShell, generate the value separately and pass it in: -{{< rad-deploy path="samples/demo/app-postgresql.bicep" args="--parameters password=$(openssl rand -hex 16)" >}} +{{< rad-deploy path="samples/demo/app-postgresql.bicep" args=`--parameters 'password'="$(openssl rand -hex 16)"` >}} -Radius creates the database and updates the container with the connection. Forward a local port to the container and open the application again: +Radius creates the database and authored Secret, then updates the container with both connections. Forward a local port to the container and open the application again: ```bash kubectl port-forward svc/demo-default-web 3000:3000 ``` -Open [http://localhost:3000](http://localhost:3000). The Radius Connections section now lists the `postgresql` connection. +Open [http://localhost:3000](http://localhost:3000). The Radius Connections section now lists the PostgreSQL-backed data used by the demo. {{< image src="todolist.png" alt="The Radius Demo application showing the PostgreSQL connection" width=800px >}} -## View the connection in the Dashboard +## View the connections in the Dashboard Start port forwarding for the Dashboard: @@ -44,16 +50,16 @@ Start port forwarding for the Dashboard: kubectl port-forward svc/dashboard 7007:80 -n radius-system ``` -Open [http://localhost:7007](http://localhost:7007) and select the `demo-default` application. The graph shows the `demo-default` container connected to the `postgresql-default` database. +Open [http://localhost:7007](http://localhost:7007) and select the `demo-default` application. The graph shows the `demo-default` container connected to the `postgresql-default` database and `postgresql-client-credentials-default` Secret. -{{< image src="dashboard.png" alt="The Radius Dashboard showing the container connected to the PostgreSQL database" width=800px >}} +{{< image src="dashboard.png" alt="The Radius Dashboard showing the container connected to the PostgreSQL database and client credentials Secret" width=800px >}}
To learn more about modeling dependencies between resources, see [How to model application dependencies using connections]({{< ref "/applications/connections" >}}). ## Clean up -Delete the Radius Demo application: +Delete the Radius Demo application. Because the database and authored Secret belong to this application, Radius deletes them with the container: ```bash @@ -68,6 +74,6 @@ rad uninstall kubernetes --purge ## Next steps -You have installed Radius, deployed the Radius Demo application, and connected it to a PostgreSQL database. Continue with the hands-on labs for deeper, real-world scenarios. +You have installed Radius, deployed the Radius Demo application, and connected it to a PostgreSQL database and an authored Secret. Continue with the hands-on labs for deeper, real-world scenarios. {{< button text="Next step: Explore the labs" page="getting-started/labs" >}} diff --git a/docs/static/samples/demo/app-postgresql.bicep b/docs/static/samples/demo/app-postgresql.bicep index 98a29c182..b9c6ef09b 100644 --- a/docs/static/samples/demo/app-postgresql.bicep +++ b/docs/static/samples/demo/app-postgresql.bicep @@ -37,6 +37,9 @@ resource demoContainer 'Radius.Compute/containers@2025-08-01-preview' = { postgresql: { source: postgresql.id } + postgresqlcredentials: { + source: postgresqlClientCredentials.id + } } } } @@ -52,3 +55,18 @@ resource postgresql 'Radius.Data/postgreSqlDatabases@2025-08-01-preview' = { password: password } } + +// Keep this distinct from the PostgreSQL Recipe-owned +// `postgresql-${environmentName}-credentials` Kubernetes Secret. +resource postgresqlClientCredentials 'Radius.Security/secrets@2025-08-01-preview' = { + name: 'postgresql-client-credentials-${environmentName}' + properties: { + environment: environment + application: demoApp.id + data: { + password: { + value: password + } + } + } +} From 20a506a3eee0e649602e40a7cfca76bdf69fbedf Mon Sep 17 00:00:00 2001 From: willdavsmith Date: Thu, 27 Aug 2026 18:56:02 -0700 Subject: [PATCH 2/2] docs: align PostgreSQL sample comments Signed-off-by: willdavsmith --- docs/static/samples/demo/app-postgresql.bicep | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/static/samples/demo/app-postgresql.bicep b/docs/static/samples/demo/app-postgresql.bicep index b9c6ef09b..6973e35a3 100644 --- a/docs/static/samples/demo/app-postgresql.bicep +++ b/docs/static/samples/demo/app-postgresql.bicep @@ -56,8 +56,6 @@ resource postgresql 'Radius.Data/postgreSqlDatabases@2025-08-01-preview' = { } } -// Keep this distinct from the PostgreSQL Recipe-owned -// `postgresql-${environmentName}-credentials` Kubernetes Secret. resource postgresqlClientCredentials 'Radius.Security/secrets@2025-08-01-preview' = { name: 'postgresql-client-credentials-${environmentName}' properties: {