Target
A target defines where resources should be created and managed. It tells formae the destination for changes and the source for discovery. Think of it as specifying which cloud account, region, or environment your infrastructure should live in.
How targets work
Every forma needs at least one target. For AWS, a target specifies the region where resources should be created, and optionally includes account ID and credentials.
When you define a target in a forma, it becomes the default for all resources unless a resource explicitly references a different target. This allows you to:
- Deploy all resources to a single region/account
- Deploy different resources to different regions in the same forma
- Support multi-region deployments
Examples
Single target for all resources
Most formae use a single target that applies to all resources:
forma {
// Define the target
new formae.Target {
label = "my-aws-target"
config = new aws.Config {
region = "us-east-1"
}
}
// All resources use the target above by default
new bucket.Bucket {
label = "my-bucket"
bucketName = "my-app-bucket"
}
new vpc.VPC {
label = "my-vpc"
cidrBlock = "10.0.0.0/16"
}
}
Multiple targets in one forma
For multi-region deployments, you can define multiple targets and have different resources use different targets:
forma {
// US East target
local usEastTarget = new formae.Target {
label = "us-east-target"
config = new aws.Config {
region = "us-east-1"
}
}
usEastTarget
// EU West target
local euWestTarget = new formae.Target {
label = "eu-west-target"
config = new aws.Config {
region = "eu-west-1"
}
}
euWestTarget
// This bucket goes to US East (default is first target)
new bucket.Bucket {
label = "us-bucket"
bucketName = "my-us-bucket"
}
// This bucket explicitly goes to EU West
new bucket.Bucket {
label = "eu-bucket"
bucketName = "my-eu-bucket"
target = euWestTarget.res
}
}
Using properties for flexible targets
Make your targets configurable using properties:
properties {
region = new formae.Prop {
flag = "region"
default = "us-east-1"
}
}
forma {
new formae.Target {
label = "dynamic-target"
config = new aws.Config {
region = properties.region.value
}
}
// Resources inherit the configurable target
new bucket.Bucket {
label = "my-bucket"
bucketName = "my-bucket-" + properties.region.value
}
}
Then override from the command line:
formae apply --mode reconcile --region eu-west-1 main.pkl
Target and discovery
When discovery is enabled, you must explicitly configure which targets formae should scan for existing resources in your configuration. Discovery doesn't automatically use targets defined in your formae - you specify the discovery targets in the agent configuration.
Best practices
Use shared targets in vars.pkl:
// vars.pkl
target: formae.Target = new formae.Target {
label = "default-aws-target"
config = new aws.Config {
region = properties.region.value
}
}
Then import and use in your formae:
import "./vars.pkl"
forma {
vars.target // Use the shared target
// Your resources here
}
This pattern keeps target configuration consistent across multiple formae. Learn more in Modular infrastructure.