Skip to content

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.

Important: Single Agent Per Target

A single target should only ever be managed by one formae agent. Running multiple agents that share targets will result in unpredictable behavior. See the agent documentation for more details.

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 control which targets formae scans by setting the discoverable field:

forma {
  // This target participates in discovery
  new formae.Target {
    label = "prod-us-east-1"
    discoverable = true  // Scan this target for resources
    config = new aws.Config {
      region = "us-east-1"
    }
  }

  // This target does not participate in discovery
  new formae.Target {
    label = "staging-us-west-2"
    discoverable = false  // Don't scan (this is the default)
    config = new aws.Config {
      region = "us-west-2"
    }
  }
}

Only targets with discoverable = true will be scanned during discovery runs. This allows you to selectively enable discovery for specific accounts or regions while excluding others.

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.

What's next

  • Forma - Understand the complete forma structure
  • Stack - Learn how stacks organize resources
  • Discovery - See how targets enable resource discovery