Skip to main content
The Cargo CDK (@cargo-ai/cdk) lets you describe a whole Cargo workspace in TypeScript and deploy it like infrastructure-as-code — the same model as Pulumi or the AWS CDK, but for Cargo resources. You write define* calls; the CDK figures out the dependency order, creates or updates each resource, and records what it made in a committed cargo.state.json so the next deploy only changes what changed.

Define resources

Every Cargo resource has a define* builder. Wire them together by passing one resource’s token into another.

Deploy

plan, deploy, --prune, --refresh, import and destroy — the full reconcile lifecycle.

State & drift

How cargo.state.json works, the lock file, and detecting changes made outside the CDK.

CLI

The CDK ships as cargo-ai cdk in the Cargo CLI.

Install

npm install -g @cargo-ai/cli
cargo-ai login

A first workspace

Create a directory and add a resource file. Importing a file is registration — there’s no manifest to maintain.
my-workspace/contacts.ts
import { defineConnector, defineModel, secret } from "@cargo-ai/cdk";

export const hubspot = defineConnector("hubspot", {
  integration: "hubspot",
  config: { apiKey: secret("HUBSPOT_API_KEY") },
});

// `hubspot.datasetUuid` is a token — the model depends on the connector, so the
// CDK creates the connector first and injects the real uuid.
export const contacts = defineModel("contacts", {
  datasetUuid: hubspot.datasetUuid,
  extractSlug: "fetchRecords",
});
export HUBSPOT_API_KEY=...           # secret() reads this at deploy time
cargo-ai cdk plan --dir my-workspace   # offline diff, no API calls
cargo-ai cdk deploy --dir my-workspace # create everything, write cargo.state.json
plan is fully offline — it compiles your code and diffs it against cargo.state.json without touching the API. Run it freely.

How it works

  • Handles & tokens. define* returns a handle whose outputs (uuid, datasetUuid, url, …) are deferred tokens. Passing a token into another resource is what creates a dependency edge — the dependency graph is just your variable graph.
  • State. Every deploy writes cargo.state.json (commit it). It’s the authoritative link from a code resource to the real uuid Cargo assigned it.
  • Idempotent. Each resource is content-hashed; a re-deploy with no code changes is a no-op. Change one resource and only it updates.
Use secret() — never env() — for credentials. secret() resolves at deploy time and is kept out of the content hash and out of state. env() bakes the value into the hash (so rotating it shows as drift) and is meant for non-secret config you want tracked.