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.

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.

What's next

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