Infrastructure
View as Markdownmz-deploy apply converges your infrastructure objects declaratively — it creates what’s missing and alters what has drifted. This page covers all object types managed by apply.
Overview
mz-deploy apply applies all types in dependency order: clusters → roles → network policies → secrets → connections → sources → tables. Each step is idempotent — running apply multiple times converges to the same state.
Preview changes before applying:
mz-deploy apply --dry-run
Skip secrets (useful in CI where secret values aren’t available):
mz-deploy apply --skip-secrets
You can also target individual object types with subcommands for granular control:
mz-deploy apply clusters
mz-deploy apply secrets
Clusters
-- clusters/orders.sql
CREATE CLUSTER orders (SIZE = '25cc');
apply creates missing clusters and alters drifted configuration. Grants and comments are applied idempotently.
Roles
-- roles/order_reader.sql
CREATE ROLE order_reader;
Secrets
Secret values use client-side provider functions that are resolved at apply time. This means compile works without access to actual secret values.
Use env_var() to read values from environment variables:
-- models/materialize/public/pg_user.sql
CREATE SECRET pg_user AS env_var('PG_USER');
-- models/materialize/public/pg_password.sql
CREATE SECRET pg_password AS env_var('PG_PASSWORD');
Alternatively, use aws_secret() to pull values from AWS Secrets Manager:
-- models/materialize/public/pg_password.sql
CREATE SECRET pg_password AS aws_secret('prod/pg-password');
aws_secret() requires an aws_profile in your project.toml:
[profiles.default.security]
aws_profile = "my-aws-profile"
apply secrets is idempotent — it runs CREATE SECRET IF NOT EXISTS then ALTER SECRET to update the value.
Connections
Postgres connection using secrets:
-- models/materialize/public/pg_conn.sql
CREATE CONNECTION pg_conn TO POSTGRES (
HOST 'my-postgres.example.com',
DATABASE 'app',
USER SECRET pg_user,
PASSWORD SECRET pg_password,
SSL MODE 'require'
);
Sources
Postgres source:
-- models/materialize/public/pg_source.sql
CREATE SOURCE pg_source
IN CLUSTER orders
FROM POSTGRES CONNECTION pg_conn
(PUBLICATION 'mz_source');
Tables
-- models/materialize/public/orders.sql
CREATE TABLE orders FROM SOURCE pg_source
(REFERENCE public.orders);
After apply tables, the table’s column schema is automatically captured in types.lock. This is how compile knows what columns orders has when type-checking views that reference it. See Local development — Lock types for details.