Skip to main content
ubx ships with schemas cached for the major cloud providers — AWS, GCP, Azure, Kubernetes. But Pulumi’s provider ecosystem is vast: Datadog, Cloudflare, PagerDuty, GitHub, Snowflake, and hundreds more. Any provider published to the Pulumi Registry works in ubx with one addition: a provider block that declares the source (the registry namespace and provider name) and the version. On first ubx validate, ubx fetches the provider’s schema from the Pulumi Registry, caches it locally, and uses it for type-checking. This is a one-time network request — subsequent validates use the cache and work offline. The provider schema fetch is categorically different from cloud credentials: it’s a public registry call, not a cloud API call, and it never touches your actual Datadog account.

What you’ll learn

  • How to use any Pulumi Registry provider with source = "publisher/provider"
  • The one-time schema auto-sync on first validate
  • How third-party provider usage differs from cloud credential requirements

Why this matters

Managing Datadog monitors, Cloudflare DNS records, or GitHub repositories in the same .iac files as your AWS infrastructure means your full platform configuration lives in one place — the same language, the same type system, the same ubx apply. No separate Terraform configs, no separate tooling.

The source code

unit "datadog_monitor" "api_latency" {
  name    = "myapp-${input.env}: API p99 latency"
  type    = "metric alert"
  message = "High API p99 latency detected. Notifying @slack-platform."
  query   = "avg(last_5m):avg:trace.express.request{env:${input.env}} > 0.5"
}

unit "datadog_monitor" "error_rate" {
  name    = "myapp-${input.env}: Error rate"
  type    = "metric alert"
  message = "Error rate above threshold. Notifying @pagerduty."
  query   = "avg(last_5m):sum:errors{env:${input.env}}.as_rate() > 0.01"
}

How it works

1

ubx detects an uncached provider schema

When ubx validate encounters a unit "datadog_monitor" block and the Datadog provider schema isn’t cached at ~/.ubx/schemas/datadog.json, it checks the provider block for source = "pulumi/datadog" and fetches the schema from https://api.pulumi.com/registry/packages/datadog.
2

The schema is cached locally after the first fetch

The downloaded schema is written to ~/.ubx/schemas/datadog@5.x.json. All subsequent ubx validate calls use the cache — no network request, no Datadog credentials, no Pulumi account needed. Run ubx schema sync datadog to explicitly refresh the cache.
3

Type checking works identically to built-in providers

Once cached, the Datadog schema is used exactly like the AWS schema: unknown attributes produce warnings, missing required attributes produce errors, and attribute types are checked. The provider being third-party is invisible to the rest of the compile pipeline.

What ubx generates

// Generated by ubx — do not edit
import * as pulumi from "@pulumi/pulumi";
import * as datadog from "@pulumi/datadog";

const config = new pulumi.Config();
const env = config.get("env") || "prod";

const apiLatency = new datadog.Monitor("api_latency", {
    name: `myapp-${env}: API p99 latency`,
    type: "metric alert",
    message: "High API p99 latency detected. Notifying @slack-platform.",
    query: `avg(last_5m):avg:trace.express.request{env:${env}} > 0.5`,
});

const errorRate = new datadog.Monitor("error_rate", {
    name: `myapp-${env}: Error rate`,
    type: "metric alert",
    message: "Error rate above threshold. Notifying @pagerduty.",
    query: `avg(last_5m):sum:errors{env:${env}}.as_rate() > 0.01`,
});

Common mistakes

The schema auto-sync requires network access to api.pulumi.com. If you’re in an air-gapped environment or have network restrictions, run ubx schema sync datadog --no-registry and provide the schema file manually. Use ubx validate --no-network to skip the auto-sync and validate with the cached schema only (produces warnings if the schema isn’t cached yet).
ubx apply for Datadog resources requires Datadog API credentials — set DATADOG_API_KEY and DATADOG_APP_KEY environment variables before running. These are cloud credentials, not schema credentials — the schema fetch works without them.

Run it

# First validate fetches the Datadog schema (requires network to api.pulumi.com)
ubx validate
# Subsequent validates use the cache (offline-capable)
ubx validate --no-network
# Apply requires Datadog API credentials
DATADOG_API_KEY=xxx DATADOG_APP_KEY=yyy ubx apply

What you learned

Any Pulumi Registry provider works in ubx with source = "publisher/provider" on a provider block
The schema is auto-fetched from the Pulumi Registry on first validate and cached locally
Schema fetching is a public registry call — distinct from cloud credentials needed for apply

Next steps

Backend S3 state

Store Pulumi state in S3 with per-stack isolation

provider block reference

Full provider block syntax and all source formats