Blueprints package multiple services together as a reusable deployment unit with configurable inputs. They enable you to create templates for common deployment patterns and allow customization at install time.
# backend-stack.blueprint.yaml
# yaml-language-server: $schema=https://api.ryvn.app/v1/schemas/resources.json
kind: Blueprint
metadata:
name: backend-stack
spec:
description: "Backend API and worker services"
displayName: "Backend Stack"
installations:
- service: api
- service: worker
inputs:
- name: replicas
type: number
displayName: "Number of Replicas"
description: "How many instances to run"
default: 2
# backend-stack-production.blueprintinstallation.yaml
# yaml-language-server: $schema=https://api.ryvn.app/v1/schemas/resources.json
kind: BlueprintInstallation
metadata:
name: backend-stack-production
spec:
blueprint: backend-stack
environment: production
inputs:
- name: replicas
value: 5
Blueprint Functions
Blueprints support special functions for accessing user inputs and environment properties during configuration.
Access user-provided blueprint input values.
config: |
replicas: {{ input "replicas" }}
storage_size: {{ input "storage_size" }}
api_key: {{ input "api_key" }}
Environment Functions
These functions provide information about the target environment during blueprint installation:
EnvironmentName
Returns the name of the environment where the blueprint is being installed.
config: |
environment: {{ EnvironmentName }}
log_prefix: {{ EnvironmentName }}-app
EnvironmentProviderType
Returns the cloud provider type: "aws", "gcp", or "azure".
condition: '{{ eq EnvironmentProviderType "aws" }}'
EnvironmentOrgId
Returns the organization ID.
config: |
org_id: {{ EnvironmentOrgId }}
EnvironmentNamespace
Returns the default namespace for the environment.
namespace: {{ EnvironmentNamespace }}
EnvironmentReleaseChannel
Returns the release channel (e.g., “stable”, “beta”).
config: |
release_channel: {{ EnvironmentReleaseChannel }}
enable_experimental: {{ ne EnvironmentReleaseChannel "stable" }}
Conditionals
Blueprints support conditionals for dynamic configuration based on user inputs and environment properties.
Important: Blueprint functions (input, Environment*) are evaluated when blueprint is installed or when blueprint inputs are changed, while .ryvn references are evaluated at deploy-time. You cannot mix blueprint functions and .ryvn syntax in the same conditional statement.# (✓) Supported - Using only blueprint functions
{{ if eq EnvironmentProviderType "aws" }}
# (✓) Supported - Using only .ryvn syntax
{{ if eq .ryvn.env.provider.type "aws" }}
# (x) Not supported - Mixing both in same conditional
{{ if and (eq EnvironmentProviderType "aws") (eq .ryvn.env.name "production") }}
Conditional Installations
Control which services are installed based on inputs or environment:
installations:
# Only install on AWS
- service: aws-specific-service
condition: '{{ eq EnvironmentProviderType "aws" }}'
# Only install when feature is enabled
- service: optional-feature
condition: '{{ eq (input "enable_feature") "true" }}'
# Complex condition combining multiple checks
- service: advanced-monitoring
condition: '{{ and (eq (input "tier") "enterprise") (ne EnvironmentProviderType "gcp") }}'
Conditional Configuration
Use conditionals within configuration blocks:
installations:
- service: database
config: |
replicas: {{ input "replicas" }}
{{ if eq EnvironmentProviderType "aws" }}
storage_class: gp3
availability_zones:
- us-east-1a
- us-east-1b
{{ else if eq EnvironmentProviderType "gcp" }}
storage_class: pd-ssd
availability_zones:
- us-central1-a
- us-central1-b
{{ else if eq EnvironmentProviderType "azure" }}
storage_class: managed-premium
availability_zones:
- eastus-1
- eastus-2
{{ end }}
Show inputs based on other input values:
inputs:
- name: database_type
type: string
displayName: "Database Type"
default: "internal"
# Only show when external database is selected
- name: external_host
type: string
displayName: "External Host"
condition: '{{ eq (input "database_type") "external" }}'
# Only show for premium tier
- name: ha_enabled
type: boolean
displayName: "High Availability"
condition: '{{ eq (input "tier") "premium" }}'
Properties
name
string — required
Unique identifier for this blueprint. Used to reference the blueprint from environments.
description
string — required
Detailed description of what this blueprint provides and its purpose.
description: "Backend API and worker services"
displayName
string — optional
Human-readable name displayed in the UI. If not provided, the name is used.
displayName: "Backend Stack"
string — optional
Name of the promotion pipeline to apply to this blueprint. All releases of this blueprint will follow the pipeline’s promotion paths.
promotionPipeline: main-pipeline
installations
array — required
List of service installations included in this blueprint. Each installation references a service and can include configuration.
installations:
- service: api
config: |
replicas: '{{ input "replicas" }}'
- service: worker
installations[].service
string — required
Name of the service to include in this blueprint.
installations[].name
string — optional
Custom name for this installation. If not provided, the service name is used.
installations[].namespace
string — optional
Kubernetes namespace to install the service into. If not provided, uses the environment’s default namespace.
installations[].condition
string — optional
Condition expression that determines whether this installation should be created. Supports template syntax with comparison operators.
condition: '{{ eq (input "storage_type") "s3" }}'
installations[].config
string or array — optional
Configuration for the service installation. Can be a YAML string or array of config items. Supports templating with blueprint inputs.
config: |
replicas: '{{ input "replicas" }}'
storage:
type: '{{ input "storage_type" }}'
installations[].secrets
array — optional
List of secrets for the service installation. Secrets can be generated or populated from blueprint inputs.
For server and job service types, prefer using secret environment variables via the env property instead of secrets, as they may conflict.
installations:
- service: database
secrets:
- name: db-credentials
generated:
type: random-string
length: 32
installations[].secrets[].name
string — required
The name of the Kubernetes secret to create.
installations[].secrets[].generated
object — optional
Configuration for auto-generating secret values. Cannot be used with values.
generated:
type: random-string
length: 32
Available generation types:
random-string — Generate a random alphanumeric string
random-bytes — Generate random bytes (base64 encoded)
rsa-key — Generate an RSA key pair
ec-key — Generate an EC key pair
The length property is only applicable for random-string and random-bytes types.
installations[].secrets[].values
array — optional
List of individual secret key-value pairs. Each value can reference a blueprint input or generated input.
secrets:
- name: external-db
values:
- key: password
valueFromInput: db_password
- key: username
valueFromInput: db_username
# Using a generated input
- name: api-credentials
values:
- key: token
valueFromInput: api_token # References a generated input
string or object — optional
Reference the entire secret value from a blueprint input. The input must be of type map and marked with isSecret: true. For generated string inputs, use values instead.
# As a string (shorthand)
secrets:
- name: custom-credentials
valueFromInput: credentials_map
# As an object
secrets:
- name: custom-credentials
valueFromInput:
name: credentials_map
installations[].env
array — optional
List of environment variables to pass to the service at runtime.
installations:
- service: api
env:
- key: LOG_LEVEL
value: debug
- key: API_KEY
valueFromInput: api_key
installations[].env[].key
string — required
The name of the environment variable.
installations[].env[].value
string — optional
The static value of the environment variable.
env:
- key: LOG_LEVEL
value: info
string or object — optional
Reference the value from a blueprint input.
env:
- key: REPLICAS
valueFromInput: replicas
# Or as an object
- key: REGION
valueFromInput:
name: aws_region
array — optional
List of input parameters that can be configured when installing the blueprint.
inputs:
- name: replicas
type: number
displayName: "Number of Replicas"
description: "How many instances to run"
default: 2
string — required
Unique identifier for this input parameter.
string — required
Type of the input parameter. Valid values: string, number, boolean, array, map
boolean — optional (default: false)
Whether this input contains sensitive data.
string — optional
Human-readable name displayed in the UI. If not provided, the name is used.
displayName: "Number of Replicas"
string — optional
Detailed description of what this input is for.
description: "How many instances to run"
any — optional
Default value for the input. If not provided, the input is required at install time.
string — optional
Name of the input group this input belongs to. Inputs in the same group are displayed together.
string — optional
Condition expression that determines whether this input should be displayed. Supports template syntax.
condition: '{{ eq (input "storage_type") "s3" }}'
boolean — optional (default: false)
Hides this input from the Dashboard installation form. Useful for internal configuration values like system defaults or automation-managed settings.
inputs:
- name: internal_api_endpoint
type: string
hidden: true
default: "https://internal.api.example.com"
description: "Internal API endpoint for service communication"
Hidden inputs can still be set when installing a blueprint via the API or IaC (Resources as Code).
object — optional
Configuration for auto-generating input values. Generated inputs are automatically populated when the blueprint is installed. Useful for credentials, API keys, or unique identifiers.
inputs:
- name: api_token
type: string
isSecret: true
generated:
type: random-string
length: 32
Available generation types:
random-string — Generate a random alphanumeric string
random-bytes — Generate random bytes (base64 encoded)
rsa-key — Generate an RSA key pair
ec-key — Generate an EC key pair
The length property is only applicable for random-string and random-bytes types.
Generated values are preserved across blueprint updates. Users can force regeneration from the Dashboard if needed.
object — optional
Pull the default value from an environment-scoped variable group when the blueprint is installed and no explicit value is provided. Only valid for map type inputs with isSecret: true. Mutually exclusive with default and generated.
inputs:
- name: db_credentials
type: map
isSecret: true
displayName: "Database Credentials"
defaultFrom:
variableGroup: db-credentials
When a blueprint with defaultFrom is installed into an environment, the system looks up the named variable group in that environment and uses its key-value pairs as the input value. If no variable group with that name exists, the input remains unset and must be provided explicitly.
string — required
Name of the variable group in the target environment. The group must exist when the blueprint is installed.
defaultFrom:
variableGroup: db-credentials
outputs
array — optional
List of outputs exposed by this blueprint. Outputs let blueprint consumers reference values produced by the blueprint’s underlying service installations (e.g., terraform outputs like database endpoints or connection strings).
Non-secret outputs are available via template syntax: {{ (blueprintInstallation "name").outputs.<outputName> }}. All outputs (including secrets) can be consumed via valueFromOutput.
outputs:
- name: endpoint
type: string
from: '{{ (serviceInstallation "postgres-rds").outputs.endpoint }}'
description: "The database endpoint"
- name: connection_string
type: string
isSecret: true
from: '{{ (serviceInstallation "postgres-rds").outputs.connection_string }}'
description: "Full connection string with credentials"
outputs[].name
string — required
Unique identifier for this output within the blueprint.
outputs[].type
string — required
Type of the output value. Valid values: string, number, boolean.
outputs[].from
string — required
Template expression that resolves the output value from installation outputs. Uses the serviceInstallation function to reference outputs: (serviceInstallation "name").outputs.<key>.
# Single value
from: '{{ (serviceInstallation "postgres-rds").outputs.endpoint }}'
# Composite value
from: '{{ (serviceInstallation "postgres-rds").outputs.endpoint }}:{{ (serviceInstallation "postgres-rds").outputs.port }}'
outputs[].description
string — optional
Detailed description of what this output represents.
description: "The database endpoint for client connections"
outputs[].displayName
string — optional
Human-readable name displayed in the UI.
displayName: "Database Endpoint"
outputs[].isSecret
boolean — optional (default: false)
If true, this output contains sensitive data. Secret outputs are routed through the secrets system — they are encrypted at rest, masked in the UI, and never rendered into plaintext manifests or resource reports.
Secret outputs are not available via template syntax. They must be consumed via valueFromOutput in env vars or secrets definitions.
outputs[].condition
string — optional
Condition expression that determines whether this output is available. Uses template syntax with blueprint functions.
condition: '{{ eq (input "enable_read_replica") "true" }}'
If the condition evaluates to false, the output is not produced and its status will show as skipped.
array — optional
Groups for organizing inputs in the UI.
inputGroups:
- name: scaling
displayName: "Scaling Configuration"
description: "Configure scaling behavior"
string — required
Unique identifier for this input group.
string — required
Display name shown in the UI.
displayName: "Scaling Configuration"
string — optional
Description for the group.
description: "Configure scaling behavior"
string — optional
Condition expression that determines whether this group should be displayed. If false, all inputs in the group are hidden.
condition: '{{ eq (input "environment") "production" }}'
When installing a blueprint, you provide values for the blueprint’s defined inputs. Each input value can be set using one of the following options:
any — optional
A literal value for the input.
inputs:
- name: replicas
value: 5
object — optional
Reference an environment-scoped variable group by name. Only valid for map type inputs with isSecret: true.
inputs:
- name: db_credentials
valueFromVariableGroup:
name: db-credentials
- name: db_password
valueFromVariableGroup:
name: db-credentials
key: password
This is useful when different environments have the same set of credentials stored in a variable group with a consistent name. The variable group must exist in the target environment.
valueFromVariableGroup is the explicit installation-time equivalent of defaultFrom on the blueprint input definition. Use defaultFrom when you want the variable group to be the fallback when no value is provided, and use valueFromVariableGroup when you want to explicitly bind the input to a variable group.
string — required
Name of the variable group in the target environment.
string — optional
The specific key to get from the variable group. If not specified, the entire variable group key-value map is used. When a key is specified, only that key’s value is used as the input value.
Examples
Basic Blueprint
Package multiple services together:
kind: Blueprint
metadata:
name: backend-stack
spec:
description: "Complete backend infrastructure"
installations:
- service: api
- service: worker
- service: database
Allow configuration at install time:
kind: Blueprint
metadata:
name: api-service
spec:
description: "API service with configurable scaling"
inputs:
- name: replicas
type: number
displayName: "Replica Count"
description: "Number of API replicas"
default: 2
- name: cpu_cores
type: number
displayName: "CPU Cores"
default: 1
installations:
- service: api
config: |
replicas: '{{ input "replicas" }}'
cpu_cores: '{{ input "cpu_cores" }}'
Show inputs based on other input values:
kind: Blueprint
metadata:
name: database-stack
spec:
description: "Database with optional external provider"
inputs:
- name: database_type
type: string
displayName: "Database Type"
default: "internal"
- name: external_host
type: string
displayName: "External Host"
description: "Database host address"
condition: '{{ eq (input "database_type") "external" }}'
- name: external_password
type: string
displayName: "External Password"
isSecret: true
condition: '{{ eq (input "database_type") "external" }}'
installations:
- service: postgres
condition: '{{ eq (input "database_type") "internal" }}'
- service: external-db-connector
condition: '{{ eq (input "database_type") "external" }}'
config: |
host: '{{ input "external_host" }}'
Auto-generate credentials and tokens:
kind: Blueprint
metadata:
name: api-with-auth
spec:
description: "API service with auto-generated credentials"
inputs:
- name: api_token
type: string
isSecret: true
generated:
type: random-string
length: 32
- name: instance_id
type: string
generated:
type: random-string
length: 16
installations:
- service: api
secrets:
- name: api-credentials
values:
- key: token
valueFromInput: api_token
env:
- key: INSTANCE_ID
valueFromInput: instance_id
Blueprint with Variable Group Defaults
Use environment-scoped variable groups as default values for secret map inputs. This allows each environment to provide its own credentials through a variable group with a consistent name:
kind: Blueprint
metadata:
name: api-with-db
spec:
description: "API service with database credentials from variable groups"
inputs:
- name: db_credentials
type: map
isSecret: true
displayName: "Database Credentials"
description: "Database connection credentials (host, port, username, password)"
defaultFrom:
variableGroup: db-credentials
installations:
- service: api
secrets:
- name: db-secret
valueFromInput: db_credentials
When installed, the system looks up the db-credentials variable group in the target environment and uses its key-value pairs. You can override this at install time:
# Use the default from the variable group
kind: BlueprintInstallation
metadata:
name: api-with-db-production
spec:
blueprint: api-with-db
environment: production
# No inputs needed - defaultFrom pulls from the "db-credentials" variable group
---
# Or explicitly bind to a different variable group
kind: BlueprintInstallation
metadata:
name: api-with-db-staging
spec:
blueprint: api-with-db
environment: staging
inputs:
- name: db_credentials
valueFromVariableGroup:
name: staging-db-credentials
Provider-Specific Configuration
Configure services differently based on cloud provider:
kind: Blueprint
metadata:
name: load-balancer
spec:
description: "Cloud provider-specific load balancer configuration"
inputs:
- name: use_internal_lb
type: boolean
displayName: "Use Internal Load Balancer"
default: false
- name: static_ip
type: string
displayName: "Static IP Address"
description: "Static IP for the load balancer (optional)"
condition: '{{ eq EnvironmentProviderType "gcp" }}'
installations:
- service: ingress-controller
config: |
service:
type: LoadBalancer
{{ if eq EnvironmentProviderType "aws" }}
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
{{ if input "use_internal_lb" }}
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
{{ end }}
{{ else if eq EnvironmentProviderType "azure" }}
annotations:
{{ if input "use_internal_lb" }}
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
{{ end }}
service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: /healthz
externalTrafficPolicy: Local
{{ else if eq EnvironmentProviderType "gcp" }}
annotations:
{{ if input "use_internal_lb" }}
cloud.google.com/load-balancer-type: "Internal"
{{ end }}
{{ if input "static_ip" }}
loadBalancerIP: {{ input "static_ip" }}
{{ end }}
{{ end }}
Multi-Tier Application
Complex blueprint with multiple conditional features:
kind: Blueprint
metadata:
name: application-stack
spec:
description: "Full application stack with optional components"
inputs:
- name: environment_tier
type: string
displayName: "Environment Tier"
description: "Deployment tier: dev, staging, or production"
default: "dev"
- name: enable_monitoring
type: boolean
displayName: "Enable Advanced Monitoring"
default: false
- name: enable_caching
type: boolean
displayName: "Enable Caching Layer"
default: false
- name: cache_size_gb
type: number
displayName: "Cache Size (GB)"
default: 10
condition: '{{ eq (input "enable_caching") true }}'
- name: monitoring_retention_days
type: number
displayName: "Monitoring Retention (Days)"
default: 30
condition: '{{ eq (input "enable_monitoring") true }}'
installations:
# Core application - always installed
- service: application
config: |
replicas: {{ if eq (input "environment_tier") "production" }}5{{ else if eq (input "environment_tier") "staging" }}3{{ else }}1{{ end }}
resources:
limits:
cpu: {{ if eq (input "environment_tier") "production" }}"2000m"{{ else }}"1000m"{{ end }}
memory: {{ if eq (input "environment_tier") "production" }}"4Gi"{{ else }}"2Gi"{{ end }}
environment:
TIER: {{ upper (input "environment_tier") }}
CACHE_ENABLED: {{ if input "enable_caching" }}"true"{{ else }}"false"{{ end }}
# Cache - conditional installation
- service: redis-cache
condition: '{{ eq (input "enable_caching") true }}'
config: |
storage:
size: {{ input "cache_size_gb" }}Gi
replicas: {{ if eq (input "environment_tier") "production" }}3{{ else }}1{{ end }}
# Monitoring - conditional installation
- service: prometheus
condition: '{{ eq (input "enable_monitoring") true }}'
config: |
retention:
time: {{ input "monitoring_retention_days" }}d
storage:
size: {{ if eq (input "environment_tier") "production" }}100Gi{{ else }}50Gi{{ end }}
# High availability - only for production on AWS
- service: ha-proxy
condition: '{{ and (eq (input "environment_tier") "production") (eq EnvironmentProviderType "aws") }}'
config: |
replicas: 3
antiAffinity: hard
Blueprint with Outputs
Expose values from underlying installations for other services to consume:
kind: Blueprint
metadata:
name: database-stack
spec:
description: "Managed database with exposed connection details"
inputs:
- name: instance_size
type: string
displayName: "Instance Size"
default: "db.t3.medium"
- name: enable_read_replica
type: boolean
displayName: "Enable Read Replica"
default: false
outputs:
- name: host
type: string
from: '{{ (serviceInstallation "postgres-rds").outputs.endpoint }}'
displayName: "Database Host"
description: "The database endpoint for client connections"
- name: port
type: number
from: '{{ (serviceInstallation "postgres-rds").outputs.port }}'
description: "The database port"
- name: connection_string
type: string
isSecret: true
from: '{{ (serviceInstallation "postgres-rds").outputs.connection_string }}'
description: "Full connection string with credentials"
- name: read_replica_host
type: string
from: '{{ (serviceInstallation "postgres-rds").outputs.read_replica_endpoint }}'
condition: '{{ eq (input "enable_read_replica") "true" }}'
description: "Read replica endpoint (only available when read replica is enabled)"
installations:
- service: postgres-rds
config: |
instance_class: '{{ input "instance_size" }}'
enable_read_replica: {{ input "enable_read_replica" }}
Consuming services can reference blueprint outputs via valueFromOutput:
kind: Blueprint
metadata:
name: api-service
spec:
description: "API that consumes database outputs"
installations:
- service: api
env:
# Non-secret output
- key: DATABASE_HOST
valueFromOutput:
blueprintInstallation: database-stack
name: host
secrets:
# Secret output routed through the secrets system
- name: db-connection
values:
- key: connection_string
valueFromOutput:
blueprintInstallation: database-stack
name: connection_string
Or reference non-secret outputs in config templates:
config: |
database:
host: {{ (blueprintInstallation "database-stack").outputs.host }}
port: {{ (blueprintInstallation "database-stack").outputs.port }}
Secret outputs (isSecret: true) are not available via template syntax. They must be consumed via valueFromOutput in env vars or secrets definitions to ensure they flow through the secrets system.
Storage Configuration by Provider
Demonstrate provider-specific storage configurations:
kind: Blueprint
metadata:
name: data-platform
spec:
description: "Data platform with provider-optimized storage"
inputs:
- name: storage_tier
type: string
displayName: "Storage Performance Tier"
description: "Storage performance: standard, fast, or premium"
default: "standard"
- name: backup_enabled
type: boolean
displayName: "Enable Automated Backups"
default: true
installations:
- service: database
config: |
storage:
{{ if eq EnvironmentProviderType "aws" }}
storageClass: {{ if eq (input "storage_tier") "premium" }}"gp3"{{ else if eq (input "storage_tier") "fast" }}"io2"{{ else }}"gp2"{{ end }}
iops: {{ if eq (input "storage_tier") "premium" }}16000{{ else if eq (input "storage_tier") "fast" }}8000{{ else }}3000{{ end }}
{{ else if eq EnvironmentProviderType "gcp" }}
storageClass: {{ if eq (input "storage_tier") "premium" }}"pd-extreme"{{ else if eq (input "storage_tier") "fast" }}"pd-ssd"{{ else }}"pd-standard"{{ end }}
{{ else if eq EnvironmentProviderType "azure" }}
storageClass: {{ if eq (input "storage_tier") "premium" }}"managed-premium"{{ else if eq (input "storage_tier") "fast" }}"managed-premium"{{ else }}"managed"{{ end }}
{{ end }}
size: 100Gi
backup:
enabled: {{ input "backup_enabled" }}
{{ if input "backup_enabled" }}
schedule: "0 2 * * *"
retention: 7d
{{ end }}