Skip to content
Closed
31 changes: 31 additions & 0 deletions Data/neo4jDatabases/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Radius.Data/neo4jDatabases

## Overview

The `Radius.Data/neo4jDatabases` Resource Type represents a Neo4j graph database. It is intended for application-centric usage and can also be provisioned as a shared resource in a Radius Environment.

## Recipes

| Platform | IaC | Recipe Name | Stage |
|------------|-----------|--------------------------------------|-------|
| Kubernetes | Bicep | `kubernetes-neo4j.bicep` | Alpha |

## Recipe Input Properties

Developers set the following properties in the resource definition when authoring applications:

- `environment` (string, required): The Environment ID.
- `application` (string, optional): Application ID when the DB is app-scoped.

## Recipe Output Properties

Recipes must populate the following read-only properties on the resource:

- `host` (string): DNS hostname clients use to connect.
- `port` (integer): Bolt port (typically `7687`).
- `username` (string): Username for client connections.
- `password` (string): Password for client connections.

## Notes

- The reference Kubernetes recipe is designed for development and evaluation. For production use, consider adding persistence (PVC), authentication, and backup/restore to your own recipe variant.
48 changes: 48 additions & 0 deletions Data/neo4jDatabases/neo4jDatabases.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace: Radius.Data
types:
neo4jDatabases:
capabilities: ["SupportsRecipes"]
description: |
The Radius.Data/neo4jDatabases Resource Type adds a Neo4j graph database to an application.

Example usage in an application Bicep file:

resource neo4j 'Radius.Data/neo4jDatabases@2025-09-11-preview' = {
name: 'neo4j'
properties: {
environment: environment
// application: myApp.id // Optional: include when bound to an app
}
}

Then add a connection from a Container (or other resource) to the Neo4j resource as needed.

apiVersions:
'2025-09-11-preview':
schema:
type: object
properties:
environment:
type: string
description: (Required) The Radius Environment ID. Typically provided by the rad CLI. The typical value is `environment`.
application:
type: string
description: (Optional) The Radius Application ID when the database is app-scoped. Omit to provision a shared database in an Environment.
host:
type: string
readOnly: true
description: (Read Only) The DNS hostname used by clients to connect to Neo4j.
port:
type: integer
readOnly: true
description: (Read Only) The Bolt protocol port used to connect to Neo4j (typically `7687`).
username:
type: string
readOnly: true
description: (Read Only) The username for connecting to Neo4j.
password:
type: string
readOnly: true
description: (Read Only) The password for connecting to Neo4j.
required:
- environment
31 changes: 31 additions & 0 deletions Data/neo4jDatabases/recipes/kubernetes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Kubernetes Recipe - Neo4j (Alpha)

This Alpha recipe deploys Neo4j to Kubernetes as an `apps/StatefulSet` with a `ReadWriteOnce` PersistentVolumeClaim and a `ClusterIP` Service exposing the Bolt port (7687). It is suitable for local development and evaluation.

Authentication is enabled via parameters. The recipe accepts a username and password and returns these in the outputs so that the corresponding resource properties can be populated in Radius.

Outputs:

- `values.host`: Internal DNS name of the Service
- `values.port`: Bolt port (7687)
- `values.username`: Username provided to the recipe
- `values.database`: Database name used by the deployment
- `secrets.password`: Password provided to the recipe

## Usage

This recipe is intended to be registered to a Radius Environment and mapped to `Radius.Data/neo4jDatabases@2025-09-11-preview`.

When a developer defines a `neo4jDatabases` resource, Radius will invoke this recipe and populate the resource outputs.

### Parameters

- `database` (string, default: resource name): Database name to configure.
- `user` (string, default: `neo4j`): Username to provision.
- `password` (secure string, default: `uniqueString(context.resource.id)`): Password to provision.
- `tag` (string, default: `community`): Tag for the `neo4j` container image.

### Notes

- This reference recipe enables persistence via a 10Gi PVC and uses a single replica StatefulSet.
- For production use, consider customizing storage class, resource requests/limits, authentication hardening, backup/restore, and service exposure.
127 changes: 127 additions & 0 deletions Data/neo4jDatabases/recipes/kubernetes/bicep/kubernetes-neo4j.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
@description('Information about what resource is calling this Recipe. Generated by Radius.')
param context object

@description('Name of the Neo4j database. Defaults to the name of the Radius resource.')
param database string = context.resource.name

@description('Neo4j username')
param user string = 'neo4j'

@description('Neo4j password')
@secure()
#disable-next-line secure-parameter-default
param password string = uniqueString(context.resource.id)

@description('Tag to pull for the neo4j container image.')
param tag string = 'community'

extension kubernetes with {
kubeConfig: ''
namespace: context.runtime.kubernetes.namespace
} as kubernetes

var uniqueName = 'neo4j-${uniqueString(context.resource.id)}'
var port = 7687

resource svc 'core/Service@v1' = {
metadata: {
name: uniqueName
labels: {
name: uniqueName
}
}
spec: {
type: 'ClusterIP'
selector: {
app: 'neo4j'
resource: context.resource.name
}
ports: [
{
port: port
}
]
}
}

resource neo4j 'apps/StatefulSet@v1' = {
metadata: {
name: uniqueName
}
spec: {
serviceName: uniqueName
replicas: 1
selector: {
matchLabels: {
app: 'neo4j'
resource: context.resource.name
}
}
template: {
metadata: {
labels: {
app: 'neo4j'
resource: context.resource.name
// Label pods with the application name so `rad run` can find the logs.
'radapp.io/application': context.application == null ? '' : context.application.name
}
}
spec: {
containers: [
{
name: 'neo4j'
image: 'neo4j:${tag}'
ports: [
{
containerPort: 7474
name: 'http'
}
{
containerPort: port
name: 'bolt'
}
]
volumeMounts: [
{
name: 'neo4j-data'
mountPath: '/data'
}
]
}
]
}
}
volumeClaimTemplates: [
{
metadata: {
name: 'neo4j-data'
}
spec: {
accessModes: ['ReadWriteOnce']
resources: {
requests: {
storage: '10Gi'
}
}
}
}
]
}
}

output result object = {
resources: [
'/planes/kubernetes/local/namespaces/${svc.metadata.namespace}/providers/core/Service/${svc.metadata.name}'
'/planes/kubernetes/local/namespaces/${neo4j.metadata.namespace}/providers/apps/Deployment/${neo4j.metadata.name}'
]
values: {
host: '${svc.metadata.name}.${svc.metadata.namespace}.svc.cluster.local'
port: port
database: database
username: user
}
secrets: {
#disable-next-line outputs-should-not-contain-secrets
password: password
}
}
Loading