Skip to main content
Terraform installations deploy Terraform services to environments. Configure infrastructure resources, secrets, and service-specific settings for your cloud infrastructure.
# yaml-language-server: $schema=https://api.ryvn.app/v1/schemas/resources.json
kind: ServiceInstallation
metadata:
  name: s3-bucket-production
spec:
  service: s3-bucket
  environment: production
  config: |
    bucket_name: "prod-bucket"
    enable_versioning: true
    secret_key: {{ k8sSecretValue "prod-bucket-key" "secret_key" }}

Properties

service

string — required Name of the Terraform service to install.
service: s3-buckets

environment

string — required Target environment for this installation.
environment: production

name

string — optional Custom name for this installation. If not specified, uses the service name.
name: data-buckets

namespace

string — optional Kubernetes namespace to install into. If not provided, uses the environment’s default namespace.
namespace: infrastructure

releaseChannel

string — optional Release channel to follow for this installation. If not specified, uses the environment’s channel.
releaseChannel: stable

Variable Groups

All variable groups in the environment are automatically available to Terraform installations as Kubernetes secrets — no explicit linking required. Reference them in your config using k8sSecretValue:
config: |
  secret_key: {{ k8sSecretValue "my-variable-group" "secret_key" }}
Unlike web-server and job installations, Terraform installations do not use the variableGroups field. Any variable group created in the environment is automatically accessible.

config

string or array — optional Service configuration. For Terraform, this is the terraform variables in YAML format.
# As string
config: |
  bucket_name: "prod-data-bucket"
  enable_versioning: true
  lifecycle_rules:
    - name: "archive-old-data"
      enabled: true
      transition_days: 90
      storage_class: "GLACIER"

# As array with file path
config:
  - path: config/production.yaml

secrets

array — optional Secrets to be passed to the Terraform module. Each secret can be generated, reference an organization secret, or get values from blueprint inputs.
secrets:
  - name: aws-credentials
    values:
      - key: access_key
        valueFromInput:
          name: awsAccessKey
      - key: secret_key
        valueFromInput:
          name: awsSecretKey

secrets[].name

string — required Name of the secret.
secrets:
  - name: aws-credentials

secrets[].generated

object — optional Configuration for generating a secret automatically. Cannot be used with values or orgSecret.
secrets:
  - name: encryption-key
    generated:
      type: random-bytes
      length: 32

secrets[].generated.type

string — required Type of secret to generate. Valid values: random-string, random-bytes, rsa-key, ec-key.
generated:
  type: random-string

secrets[].generated.length

integer — optional Length of the random string or bytes to generate. Only valid for random-string and random-bytes types.
generated:
  type: random-bytes
  length: 32

secrets[].values

array — optional Key-value pairs for the secret. Cannot be used with generated or orgSecret.
secrets:
  - name: db-credentials
    values:
      - key: username
        valueFromInput:
          name: dbUsername
      - key: password
        valueFromInput:
          name: dbPassword

secrets[].values[].key

string — required Secret key name.
values:
  - key: access_key

secrets[].values[].valueFromInput

object — optional Reference to a blueprint input for the value. If the referenced input has a condition that evaluates to false, this secret key is automatically omitted.
values:
  - key: password
    valueFromInput:
      name: dbPassword

secrets[].values[].valueFromInput.name

string — required Name of the blueprint input to get the value from.
valueFromInput:
  name: dbPassword

secrets[].orgSecret

string — optional Name of organization-level secret to get values from. Cannot be used with values or generated.
Prefer using variable groups instead of orgSecret. All environment variable groups are automatically available to Terraform installations as Kubernetes secrets and can be referenced in config via k8sSecretValue.
secrets:
  - name: cloud-credentials
    orgSecret: prod-cloud-creds

Outputs

Terraform installation outputs are available to other installations via template syntax. After a Terraform service completes its apply, any outputs defined in the Terraform module become available for reference in other installation configs.

Referencing Outputs

Use the serviceInstallation template function to reference outputs from a Terraform installation: {{ (serviceInstallation "installation-name").outputs.* }}

Scalar Outputs

Reference simple string, number, or boolean outputs directly:
# Reference a database endpoint
database_url: '{{ (serviceInstallation "postgres-service").outputs.endpoint }}'

# Reference a port number
database_port: '{{ (serviceInstallation "postgres-service").outputs.port }}'

# Reference a boolean
is_multi_az: '{{ (serviceInstallation "postgres-service").outputs.multi_az }}'

Nested Outputs

Access nested object properties using dot notation:
# Reference nested output properties
bucket_name: '{{ (serviceInstallation "storage-service").outputs.bucket.name }}'
bucket_arn: '{{ (serviceInstallation "storage-service").outputs.bucket.arn }}'
bucket_region: '{{ (serviceInstallation "storage-service").outputs.bucket.region }}'

# Reference deeply nested properties
connection_string: '{{ (serviceInstallation "database-service").outputs.connection.primary.endpoint }}'

Array Outputs

Use the index function to access array elements:
# Get first subnet ID from array
primary_subnet: '{{ index (serviceInstallation "network-service").outputs.subnet_ids 0 }}'

# Access nested property in array element
subnet_cidr: '{{ index (serviceInstallation "network-service").outputs.subnets 0 "cidr" }}'

# Get array length
subnet_count: '{{ len (serviceInstallation "network-service").outputs.subnet_ids }}'

Complex Outputs with toJson

For complex data structures, use toJson to serialize the entire output:
# Serialize array to JSON
all_subnets: '{{ (serviceInstallation "network-service").outputs.subnet_ids | toJson }}'

# Serialize nested object to JSON
security_groups: '{{ (serviceInstallation "network-service").outputs.security_groups | toJson }}'

# Serialize with default fallback
node_groups: '{{ (serviceInstallation "eks-cluster").outputs.node_groups | default "[]" | toJson }}'

Default Values

Provide fallback values for optional outputs:
# Use default if output doesn't exist
cache_endpoint: '{{ (serviceInstallation "redis-cluster").outputs.endpoint | default "localhost:6379" }}'

# Default for complex structures
config: '{{ (serviceInstallation "app-config").outputs.settings | default "{}" | toJson }}'

Combining with Environment State

Combine installation outputs with environment values:
# Combine installation output with environment name
full_bucket_name: '{{ (serviceInstallation "storage-service").outputs.bucket.name }}-{{ .ryvn.env.name }}'

# Use in DNS configuration
service_url: 'https://{{ (serviceInstallation "api-service").outputs.hostname }}.{{ .ryvn.env.state.public_domain.name }}'

Cross-Installation Dependencies

When one installation references another’s outputs, Ryvn automatically manages the deployment order:
kind: Environment
metadata:
  name: production
spec:
  installations:
    # This installs first
    - service: postgres-database
      config: |
        instance_class: "db.r5.large"

    # This installs second, using postgres outputs
    - service: api-server
      config: |
        database_host: '{{ (serviceInstallation "postgres-database").outputs.endpoint }}'
        database_port: '{{ (serviceInstallation "postgres-database").outputs.port }}'
        database_name: '{{ (serviceInstallation "postgres-database").outputs.database_name }}'

Examples

RDS database with generated password:
kind: ServiceInstallation
metadata:
  name: rds-postgres-production
spec:
  service: rds-postgres
  environment: production
  config: |
    instance_class: "db.r5.xlarge"
    allocated_storage: 100
    engine_version: "15.3"
    multi_az: true
    backup_retention_period: 7
  secrets:
    - name: master-password
      generated:
        type: random-string
        length: 32
With generated secrets and variable group references in config:
kind: ServiceInstallation
metadata:
  name: infrastructure-production
spec:
  service: infrastructure
  environment: production
  config: |
    # All environment variable groups are automatically available
    aws_access_key: {{ k8sSecretValue "prod-aws-creds" "access_key" }}
    aws_secret_key: {{ k8sSecretValue "prod-aws-creds" "secret_key" }}
  secrets:
    - name: encryption-keys
      generated:
        type: random-bytes
        length: 32