Snowflake has shipped plenty of features for running code inside its warehouses, but until now it left the deployment of the warehouse objects themselves to third-party tools. That changes with Snowflake DCM Projects, which reached general availability on August 7, 2026. DCM, short for Database Change Management, lets you define databases, tables, tasks, and other Snowflake objects declaratively in SQL files, then let Snowflake figure out the diff and apply the changes. The headline: you can now version-control and idempotently deploy your Snowflake infrastructure without an external state file or a separate Terraform runner.
The move matters because every team running Snowflake at scale already has a deployment problem. Some use Terraform or dbt, some run hand-rolled SQL scripts in GitHub Actions, and most have a tangled mix of both. DCM Projects is Snowflake's native answer: a declarative layer that handles the plan, the diff, and the apply, all inside the account. For teams that already think about pipeline architecture choices, this adds a new dimension to the build question.
What is a DCM Project and how does the syntax work?
A DCM Project is a collection of SQL definition files that describe the desired state of your Snowflake objects. Instead of writing imperative CREATE OR ALTER statements and hoping they run in the right order, you write DEFINE statements that declare what an object should look like. Snowflake compares the declared state to the current state and computes the delta.
The DEFINE keyword is the building block. A database and table definition based on the pattern documented in the Snowflake DCM overview looks like:
DEFINE DATABASE my_analytics
COMMENT = 'Analytics warehouse objects';
DEFINE TABLE my_analytics.reporting.daily_revenue (
order_date DATE,
revenue NUMBER(12,2),
region VARCHAR
)
COMMENT = 'Daily revenue by region';
The real power comes from Jinja templating, which is built in. You can parameterize definitions for multiple environments:
DEFINE TABLE .reporting.daily_revenue (
order_date DATE,
revenue NUMBER(12,2),
region VARCHAR
)
COMMENT = 'Daily revenue for ';
With Jinja, you pass variables like env=staging at deploy time, so one project definition serves dev, staging, and production without duplicate files. Loops, conditions, and macros are all available, which means you can generate repetitive definitions (one table per region, one task per schema) without copy-paste sprawl.
Project files live in three places: a Snowflake Workspace managed inside Snowsight, a remote Git repository, or a local directory. You can manage them through Snowsight, the Snowflake CLI, SQL, or the Cortex Code CLI. That flexibility is deliberate: whether your team lives in the Snowflake UI or in a terminal, there is an entry point.
How does the plan-then-deploy workflow run?
The core workflow is plan, review, deploy. You define the desired state, Snowflake generates a plan showing what will change, you review it, and then you execute. The command at the center is EXECUTE DCM PROJECT, which is generally available and documented in the Snowflake SQL reference.
A deploy from the Snowflake CLI:
snow dcm execute --project my_analytics \
--variable env=production
Or via SQL:
EXECUTE DCM PROJECT my_analytics
USING VARIABLES (env => 'production');
One important nuance: the explicit PREVIEW and TEST commands are still in Preview as of the GA release. The GA plan-then-deploy story relies on EXECUTE DCM PROJECT, which applies changes. If you want a dedicated dry-run verb before applying, that specific SQL command is not yet production-ready. Plan accordingly: test in a lower environment where EXECUTE is safe, and treat staging as your dry run until the PREVIEW command ships as GA.
To monitor what DCM Projects have done in your account, query ACCOUNT_USAGE:
SELECT
project_name,
status,
executed_by,
executed_at
FROM SNOWFLAKE.ACCOUNT_USAGE.DCM_PROJECT_EXECUTIONS
ORDER BY executed_at DESC
LIMIT 20;
This view is your audit trail. Every execution logs who ran it and when. Wire it into a dashboard or an alert so you catch unintended schema drift the moment it happens. The exact view columns depend on the ACCOUNT_USAGE schema Snowflake publishes, so verify the column names against your account's information schema before building dashboards on top of it.
How does DCM compare to Terraform and raw SQL scripts?
Most teams deploying Snowflake objects today use one of two approaches. Terraform with the Snowflake provider gives you declarative state and a plan output, but it runs outside Snowflake and requires a state file you have to manage. Raw SQL scripts in CI/CD give you full control but no diff, no drift detection, and no idempotency without careful scripting. DCM Projects splits the difference.
| Dimension | DCM Projects | Terraform + provider | Raw SQL scripts |
|---|---|---|---|
| Where it runs | Inside Snowflake | External CI runner | Any CI runner |
| State management | Snowflake computes the diff | Terraform state file | None |
| Plan or dry run | EXECUTE DCM PROJECT (GA); PREVIEW command (Preview) | terraform plan (GA) | None without custom code |
| Jinja templating | Built in | HCL variables and for_each | Requires external templating |
| Object coverage | Broad, but pipes and streams in Preview | Broad via provider | Anything you script |
| Lock-in | Snowflake-only definitions | Portable HCL, provider-dependent | Fully portable SQL |
| Drift detection | Snowflake checks current vs desired on execute | terraform plan detects drift | None |
The trade-off is clear. DCM Projects removes the need for an external runner and a state file, which simplifies CI/CD and cuts the number of moving parts. But it locks your deployment definitions to Snowflake. If your infrastructure spans AWS, dbt, and Snowflake, Terraform still has a role for the parts outside Snowflake. If Snowflake is your whole world, DCM is the simpler path.
What does it cost and what edition do you need?
Here is the good news for anyone who owns the Snowflake bill: DCM Projects does not introduce a separate credit charge. The feature runs within your existing Snowflake account. The compute used for planning and applying changes runs on a warehouse, so the cost is the warehouse compute you are already paying for. There is no per-execution fee, no marketplace listing, and no premium edition requirement called out in the GA announcement.
Check whether the feature is visible in your account:
SHOW FUNCTIONS LIKE 'EXECUTE%DCM%';
If the command resolves, DCM Projects is available. If not, check with your account admin or Snowflake support, as feature rollout can lag the release-note date by days.
The real cost is the time to migrate. If you have hundreds of Terraform resources or thousands of lines of imperative SQL, converting them to DEFINE statements is a project, not an afternoon. Start with one schema or one pipeline, prove the workflow, and expand from there.

The chart above shows the capability split at GA. 7 capabilities are generally available, including the DEFINE statement core, Jinja templating, and the plan-then-deploy workflow. 8 capabilities remain in Preview, and several of them are the governance and pipeline objects you most need for production.
What is still in Preview and what should you avoid?
The GA is real, but it is not complete. These capabilities remain in Preview:
- TEST and PREVIEW commands: the dry-run verbs are not GA yet
- GitHub Actions for DCM Projects: no native CI integration yet
- DEFINE PIPE: cannot declaratively manage Snowpipe objects
- DEFINE STREAM: cannot declaratively manage streams
- DEFINE MASKING POLICY: cannot declaratively manage masking policies
- DEFINE ROW ACCESS POLICY: cannot declaratively manage row access policies
- ATTACH TAG: cannot declaratively attach tags to objects
- Inherited grants and container-level MANAGE GRANTS: advanced grant patterns not supported
If your governance story depends on masking policies, row access policies, or tag-based protections, DCM Projects cannot manage those objects declaratively today. You will still need imperative SQL or Terraform for that layer. For a deeper look at those governance objects, see our guide on Snowflake RBAC and masking.
Similarly, if your pipeline uses streams, you are out of luck for declarative management. You can declaratively define dynamic tables and tasks, but streams remain imperative. For teams building event-driven pipelines, this is the gap to watch.
What is the pragmatic migration path?
Start with objects that are fully GA: databases, tables, tasks, and dynamic tables. These cover the bulk of what most teams deploy repeatedly. Leave pipes, streams, and governance policies in your existing tooling for now.
A practical sequence:
- Pick one non-production schema with a handful of tables and a task
- Write DEFINE statements for those objects in a local directory or Git repo
- Run EXECUTE DCM PROJECT against a dev database
- Verify the objects match, then tear them down and re-execute to confirm idempotency
- Wire the Snowflake CLI into your CI pipeline with a shell step
- Expand schema by schema, checking the execution history after each run
- Move the project storage to a remote Git repository once the workflow is stable
The GRANT that controls who can execute DCM Projects:
GRANT EXECUTE MANAGE DCM PROJECT ON ACCOUNT TO ROLE dcm_deployer;
Restrict this to a dedicated deployment role. DCM Projects can create, alter, and drop objects, so the execute privilege is powerful. Do not grant it broadly, and do not let your CI service role carry it into production without a gate.
A before-and-after for a simple table change shows the value. Before DCM, adding a column meant writing an ALTER TABLE script, versioning it, running it in each environment, and hoping nobody ran it twice. With DCM, you change the DEFINE TABLE block, run EXECUTE DCM PROJECT, and Snowflake applies only the column addition:
-- Before: imperative, order-dependent
ALTER TABLE reporting.daily_revenue ADD COLUMN currency VARCHAR;
-- After: declarative, idempotent
DEFINE TABLE reporting.daily_revenue (
order_date DATE,
revenue NUMBER(12,2),
region VARCHAR,
currency VARCHAR
)
COMMENT = 'Daily revenue by region';
Run it once, run it a hundred times. The result is the same.
The bottom line for your deployment pipeline
DCM Projects GA is a genuine step forward for Snowflake-native DevOps. It removes the external state file and the separate IaC runner for the objects it covers, and it does so without a new line item on your bill. The gaps are real but bounded: governance objects and streams will come, and until they do, you run a hybrid stack. If you are starting a new Snowflake project today, begin with DCM definitions. If you are running a mature Terraform setup, do not rip it out, but start migrating the object types DCM supports and shrink your Terraform footprint over time.
