Skip to content

Res

A res (short for resolvable) is how you reference properties from other resources or access secrets. It serves two main purposes:

  1. Reference properties of other infrastructure resources
  2. Access secrets securely, keeping sensitive values protected throughout the process

Resource Property Resolution

Infrastructure resources often depend on each other. For example, a subnet needs to know the VPC ID, or a database instance needs subnet IDs. The res construct lets you reference these values declaratively—you don't need to worry about creating resources in the right order.

formae automatically handles:

  • Detecting when resource properties are available
  • Waiting for properties that are still being created
  • Injecting resolved values at the right time

This eliminates common infrastructure management problems like explicit dependency declaration, manual ordering, and race conditions.

Note: The examples below use the local pattern to create variables for resources that need to be referenced later. This allows you to use .res to access their properties. Resources that don't need to be referenced can be created directly without local. Learn more about this pattern in Formae 101 - Fundamentals.

Examples

Referencing VPC and Subnet IDs:

local vpc = new vpc.VPC {
  label = "main-vpc"
  cidrBlock = "10.0.0.0/16"
}
vpc

local subnet1 = new subnet.Subnet {
  label = "subnet-1"
  vpcId = vpc.res.vpcId  // Reference the VPC's ID using .res
  cidrBlock = "10.0.1.0/24"
  availabilityZone = "us-west-2a"
}
subnet1

new dbsubnetgroup.DBSubnetGroup {
  label = "db-subnet-group"
  dbSubnetGroupDescription = "Subnet group for RDS"
  subnetIds {
    subnet1.res.subnetId  // Reference subnet's ID
  }
}

Referencing secrets:

You can create secrets and reference them securely using resolvables. This keeps sensitive values protected while allowing you to use them in resource configurations.

// Create a secret with a randomly generated password
local dbSecret = new secret.Secret {
  label = "db-password"
  name = "my-db-password"
  description = "Database password secret"
  secretString = formae.value(random.password(12, false)).opaque.setOnce
}
dbSecret

// Reference the secret in a database instance
new dbinstance.DBInstance {
  label = "my-database"
  allocatedStorage = 20
  dbInstanceClass = "db.t3.micro"
  engine = "postgres"
  masterUsername = "admin"
  masterUserPassword = dbSecret.res.secretString  // Reference the secret using .res
}

In this example: - formae.value() wraps the password - .opaque marks it as a secret that should never be displayed - .setOnce ensures the value is generated once and reused - dbSecret.res.secretString references the secret's value in the database configuration

Note: Learn more about .opaque and .setOnce in the Values concept page.