diff --git a/samples/demo/app-postgresql.bicep b/samples/demo/app-postgresql.bicep new file mode 100644 index 00000000..24daa087 --- /dev/null +++ b/samples/demo/app-postgresql.bicep @@ -0,0 +1,92 @@ +extension radius + +@description('The Radius Environment ID. Injected automatically by the rad CLI.') +param environment string + +@description('Container image for the demo app. Defaults to the published sample image; overridden in CI to test a locally-built image.') +param image string = 'ghcr.io/radius-project/samples/demo:latest' + +@description('The administrator password for the PostgreSQL database. Pass via the CLI, e.g. -p password=$(openssl rand -hex 16).') +@secure() +param password string + +// Environment name derived from the Environment ID, used to keep resource names +// unique per environment (e.g. dev/test/prod) within the same resource group. +var environmentName = last(split(environment, '/')) + +resource demoApp 'Radius.Core/applications@2025-08-01-preview' = { + name: 'demo-${environmentName}' + properties: { + environment: environment + } +} + +// The demo container needs the same password used to provision the database. +// Store it in a Radius.Security/secrets resource and bind it by reference rather +// than passing it to the container as a plain `env` value: `data.value` is +// x-radius-sensitive, so Radius encrypts it at rest and redacts it on reads, +// whereas a container `env.value` is stored unencrypted on the container +// resource and rendered literally into the pod spec. +resource dbCredentials 'Radius.Security/secrets@2025-08-01-preview' = { + name: 'postgresql-credentials-${environmentName}' + properties: { + environment: environment + application: demoApp.id + data: { + password: { + value: password + } + } + } +} + +resource postgresql 'Radius.Data/postgreSqlDatabases@2025-08-01-preview' = { + name: 'postgresql-${environmentName}' + properties: { + environment: environment + application: demoApp.id + size: 'S' + database: 'appdb' + username: 'myadmin' + password: password + } +} + +resource demoContainer 'Radius.Compute/containers@2025-08-01-preview' = { + name: 'demo-${environmentName}' + properties: { + environment: environment + application: demoApp.id + containers: { + web: { + image: image + // Host, port, username, and database arrive automatically as + // CONNECTION_POSTGRESQL_* env vars from the connection below. The + // connection cannot carry the password (x-radius-sensitive properties + // redact to null on reads and are skipped by the containers recipe), so + // it is bound by reference here under the same naming scheme, filling + // the one gap the connection leaves. + env: { + CONNECTION_POSTGRESQL_PASSWORD: { + valueFrom: { + secretKeyRef: { + secretName: dbCredentials.name + key: 'password' + } + } + } + } + ports: { + web: { + containerPort: 3000 + } + } + } + } + connections: { + postgresql: { + source: postgresql.id + } + } + } +} diff --git a/samples/demo/app-redis.bicep b/samples/demo/app-redis.bicep new file mode 100644 index 00000000..d0d32741 --- /dev/null +++ b/samples/demo/app-redis.bicep @@ -0,0 +1,63 @@ +extension radius + +@description('The Radius Environment ID. Injected automatically by the rad CLI.') +param environment string + +@description('Container image for the demo app. Defaults to the published sample image; overridden in CI to test a locally-built image.') +param image string = 'ghcr.io/radius-project/samples/demo:latest' + +// Environment name derived from the Environment ID, used to keep resource names +// unique per environment (e.g. dev/test/prod) within the same resource group. +var environmentName = last(split(environment, '/')) + +resource demoApp 'Radius.Core/applications@2025-08-01-preview' = { + name: 'demo-${environmentName}' + properties: { + environment: environment + } +} + +resource redis 'Radius.Data/redisCaches@2025-08-01-preview' = { + name: 'redis-${environmentName}' + properties: { + environment: environment + application: demoApp.id + size: 'S' + } +} + +resource demoContainer 'Radius.Compute/containers@2025-08-01-preview' = { + name: 'demo-${environmentName}' + properties: { + environment: environment + application: demoApp.id + containers: { + web: { + image: image + // The recipe's `url` secret is NOT injected through the connection. It is + // materialized into a managed Radius.Security/secrets resource, so bind it + // by reference with secretKeyRef -- the value never lands in the pod spec. + env: { + REDIS_URL: { + valueFrom: { + secretKeyRef: { + secretName: redis.properties.secrets.name + key: 'url' + } + } + } + } + ports: { + web: { + containerPort: 3000 + } + } + } + } + connections: { + redis: { + source: redis.id + } + } + } +} diff --git a/samples/demo/app.bicep b/samples/demo/app.bicep index 4d31bd0b..0a3355a2 100644 --- a/samples/demo/app.bicep +++ b/samples/demo/app.bicep @@ -1,40 +1,36 @@ extension radius -param application string +@description('The Radius Environment ID. Injected automatically by the rad CLI.') param environment string +@description('Container image for the demo app. Defaults to the published sample image; overridden in CI to test a locally-built image.') param image string = 'ghcr.io/radius-project/samples/demo:latest' -resource demo 'Applications.Core/containers@2023-10-01-preview' = { - name: 'demo' +// Environment name derived from the Environment ID, used to keep resource names +// unique per environment (e.g. dev/test/prod) within the same resource group. +var environmentName = last(split(environment, '/')) + +resource demoApp 'Radius.Core/applications@2025-08-01-preview' = { + name: 'demo-${environmentName}' properties: { - application: application - container: { - image: image - ports: { - web: { - containerPort: 3000 - } - } - livenessProbe: { - kind: 'httpGet' - containerPort: 3000 - path: '/healthz' - initialDelaySeconds: 10 - } - } - connections: { - redis: { - source: db.id - } - } + environment: environment } } -resource db 'Applications.Datastores/redisCaches@2023-10-01-preview' = { - name: 'db' +resource demoContainer 'Radius.Compute/containers@2025-08-01-preview' = { + name: 'demo-${environmentName}' properties: { - application: application environment: environment + application: demoApp.id + containers: { + web: { + image: image + ports: { + web: { + containerPort: 3000 + } + } + } + } } }