What you will be able to do
- Design separate dev, test and production environments with zero-copy clones and DCM deployment targets
- Choose between DCM Projects, the Terraform provider and dbt Projects for each layer of a Snowflake estate
- Lay out a validate, deploy and verify CI/CD pipeline that runs Snowflake CLI with a federated service user
- Explain how the Git repository clone and versioned CREATE OR ALTER files support deployment and rollback
Key concept
Define as code — You describe the target state of your Snowflake objects in files kept in version control. A tool then compares those files with the account and applies only the changes needed. Environments, pipelines and rollback all rely on this one source of truth.
1.Environments, data layers and workload isolation
An architecture that supports a development lifecycle starts with one rule: you build and test changes somewhere other than production. Snowflake's DevOps guidance recommends separate development, test and production environments. Development work then can't damage production data. These environments don't have to share an account. A DCM Projects deployment target can point each environment at its own Snowflake account or database.
Inside a single account, the quickest way to set up a realistic dev, test or sandbox copy is zero-copy cloning. CREATE <object> … CLONE is mainly used for databases, schemas and tables. For those three object types it also accepts an AT | BEFORE clause, so a clone can show the source as it was at an earlier timestamp, offset or statement. The sources treat a sandbox as just another isolated environment built the same way, not as a separate feature. How long that history is kept is covered in the data-recovery lesson.
Within an environment, data usually moves through layers, or zones. Snowflake's dynamic-table guidance uses the medallion names. Raw data lands first, then it's cleaned, then it's aggregated, and each step runs as SQL inside Snowflake. That is the ELT shape: load first, transform in place. The DevOps guidance names dbt Projects on Snowflake as the tool for managing those SQL transformations.
| Layer | What it holds |
|---|---|
| Bronze | The raw landing table |
| Silver | A cleaned or conformed dynamic table with TARGET_LAG = DOWNSTREAM |
| Gold | An aggregated dynamic table with a time-based freshness goal |
Workload isolation follows the same thinking. The DCM example in the next section gives each team its own database, warehouse and admin role, and makes warehouse size a per-team template value. Each team's work therefore runs on compute sized for that team. Coverage note: the source documentation for this lesson doesn't cover data-lake design, storage directory structure, or migration from other platforms. Those exam-guide bullets aren't taught here, so read the Snowflake documentation on them directly.
Checkpoint 1 of 8· Check yourself
A team needs a development copy of the production SALES database as it was before last night's load. They don't want to rebuild it from scratch. What fits?
Cloning copies a database without rebuilding it. The AT | BEFORE clause uses Time Travel to capture an earlier point. A DCM deploy creates object definitions, not the data.
“For databases, schemas, and non-temporary tables, CLONE supports an additional AT | BEFORE clause for cloning using Time Travel.”Source: docs.snowflake.com
2.Objects as code: DCM Projects, Terraform and dbt
Snowflake's DevOps model rests on three principles: define objects as code, validate changes before you deploy them, and automate deployment with CI/CD. Two declarative tools put the first principle into practice, and they work at different layers.
DCM Projects (Database Change Management) are the Snowflake-native tool for objects inside databases. A project has a manifest.yml file, which sets deployment targets, owner roles and templating per environment. It also has definition files under sources/definitions/ that contain DEFINE, GRANT and ATTACH statements. Jinja2 templating lets one definition set up infrastructure for many teams:
{% for team in teams %}
DEFINE DATABASE {{team.name}}_DB;
DEFINE WAREHOUSE {{team.name}}_WH
WITH
warehouse_size = '{{team.wh_size}}'
auto_suspend = 300;
DEFINE ROLE {{team.name}}_ADMIN;
GRANT OWNERSHIP ON DATABASE {{team.name}}_DB TO ROLE {{team.name}}_ADMIN;
GRANT OWNERSHIP ON WAREHOUSE {{team.name}}_WH TO ROLE {{team.name}}_ADMIN;
{% endfor %}For multiple environments, the manifest declares one target per environment. Each target names an account, a project object, an owner role and a templating configuration. The same definition files then deploy everywhere, with settings that differ by environment.
targets:
DEV:
account_identifier: MYORG-MYACCOUNT_DEV
project_name: MY_DB.MY_SCHEMA.MY_PROJECT_DEV
project_owner: DEV_DEPLOYER
templating_config: DEV| Consideration | DCM Projects | Snowflake Terraform provider |
|---|---|---|
| Typical scope | Objects inside a database (schemas, tables, views, dynamic tables, tasks), plus databases, warehouses and roles | Account-level objects such as users, integrations and policies |
| Resources outside Snowflake | Not supported | Supported through other Terraform providers |
| Authoring language | SQL DEFINE statements with Jinja2 | HCL with modules |
| Where it runs | Inside Snowflake | Outside Snowflake |
| Multiple environments | Deployment targets and configuration profiles in manifest.yml | Modules and per-environment pipelines |
Many organizations use both tools. Terraform covers the account level that platform teams own, and DCM covers the in-database objects that data engineers own. Each object should be managed by only one tool, so the two never try to reconcile the same state. Their plans also see different things. DCM plans against internal object state, while Terraform reads state through public SQL and can miss attributes that SHOW and DESCRIBE don't return. In return, every statement Terraform runs appears in query history. dbt Projects do a different job. They deploy dbt Core transformations as a versioned DBT PROJECT object that you can schedule with tasks, and you use them alongside one of the other two tools.
Checkpoint 2 of 8· Match them up
Match each tool or file to its role
Tap a term, then the definition that fits it.
DCM and Terraform both declare object state, at different layers. dbt manages transformations, and the DCM manifest holds the per-environment targets.
“Terraform for the account-level layer that platform teams own, and DCM Projects for the objects inside databases that data engineers own.”Source: docs.snowflake.com
Sources1
3.CI/CD pipelines with Snowflake CLI
Snowflake CLI (snow) is the command-line tool a pipeline runs to deploy DCM projects, Snowpark applications, Native Apps and standalone SQL scripts, so you don't need a custom client. Snowflake maintains a GitHub Action, which is generally available, plus a GitLab CI/CD component and an Azure DevOps extension, both in public preview. Each one installs the CLI and configures authentication. On Jenkins, Bitbucket, CircleCI or any other runner that can run a shell command, a single command installs the CLI:
uv tool install snowflake-cli
snow --version| Stage | When it runs | Example commands |
|---|---|---|
| Validate | On a pull request; nothing is modified, and the output is posted as a PR comment | snow dcm plan |
| Deploy | After the pull request merges to main | snow dcm deploy, snow sql -f <file>, snow snowpark deploy, snow git execute |
| Verify | After the deploy step | snow dcm test (expectation checks) |
Checkpoint 3 of 8· Put it in order
Put the stages of a Snowflake CI/CD pipeline in order
- 1.Validate: compute the planned changes on the pull request
- 2.Verify: refresh derived data and run expectation checks
- 3.Deploy: apply the validated changes after merge
Reviewers confirm the plan before merging, the merge triggers the deploy, and the verify stage checks the result.
“validate proposed changes on a pull request, deploy them on merge, and verify the result.”Source: docs.snowflake.com
Every integration sets up Snowflake the same way. You create a service user for the pipeline, configure how it authenticates, and grant it only the roles it needs. The recommended method is workload identity federation (WIF) with OIDC. The runner gets a short-lived identity token that Snowflake validates directly, so no long-lived secret is stored anywhere.
| Method | When to use it |
|---|---|
| Workload identity federation (OIDC) | Recommended wherever the CI system supports it |
| Key pair | When OIDC isn't available, for example with older CLI versions or on-premises runners; store the private key as a CI secret |
| Password | Legacy workflows only; not recommended for production CI/CD |
Checkpoint 4 of 8· Fill the gap
Which identity type completes this service-user definition so the runner authenticates without any stored secret?
CREATE USER <username>
TYPE = SERVICE
WORKLOAD_IDENTITY = (
TYPE = ?
ISSUER = '<ci-platform-issuer>'
SUBJECT = '<ci-platform-subject>'
);Workload identity federation uses an OIDC token issued by the CI platform. The ISSUER and SUBJECT values match that platform's claims.
Source: docs.snowflake.comTo harden a pipeline, use one dedicated service user per repository or environment. Restrict which source IPs can authenticate with network policies. Commit only the connection skeleton of config.toml and inject secrets through environment variables. If you can't use OIDC, rotate keys on a schedule. When settings conflict, precedence runs as follows: command-line parameters win, then connection-specific environment variables, then config.toml, and generic variables such as SNOWFLAKE_USER come last.
Checkpoint 5 of 8· Exam question
A retail analytics team is designing schema zones in Snowflake to support data warehouse layering. Raw JSON order events land continuously, need light validation and conforming into typed tables, and business-ready aggregates power dashboards. Which zone design best supports this workflow?
Correct answer: A — Land raw JSON in a bronze schema unchanged, conform it into a typed silver schema, then publish curated aggregates in a gold schema for dashboards.
- A. This layered bronze/silver/gold design isolates raw ingestion from conforming logic and from business aggregation, which is exactly the separation of concerns data warehouse zoning is meant to provide.
- B. Pushing JSON parsing and validation into every downstream BI tool duplicates transformation logic per consumer and removes the single conformed layer the rest of the architecture depends on.
- C. Querying an external stage directly for dashboards bypasses Snowflake's typed table performance benefits and leaves no governed, validated layer between raw files and reporting.
- D. Using an audit-log schema in place of a genuine conforming layer means untyped, unvalidated raw data feeds dashboards directly, defeating the purpose of layered zoning.
Sources4
4.Git integration as the deployment source
Snowflake can integrate with a remote repository on GitHub, GitLab, BitBucket, Azure DevOps or AWS CodeCommit, including repositories hosted at custom URLs. Files sync into a Git repository clone in Snowflake that includes all branches, tags and commits. Developers keep their usual tools, and Snowflake becomes one more client of the repository.
From the clone you can fetch the latest branches and tags, browse files, and reference file paths as handler code for functions, procedures and tasks. You can run EXECUTE IMMEDIATE from .sql files, and commit and push from Workspaces, Streamlit apps and notebooks. In a pipeline, snow git execute runs SQL files straight from this integration as the deploy step.
Checkpoint 6 of 8· Check yourself
After a team integrates its GitHub repository with Snowflake, what happens to the developers' local repositories?
The clone syncs from the remote and includes every branch, tag and commit. It sits alongside local repositories rather than replacing them.
“Through the Git repository clone, Snowflake becomes another client of your repository separate from your local repository.”Source: docs.snowflake.com
Checkpoint 7 of 8· Exam question
An architecture team is designing the directory structure for an S3-backed external stage that lands IoT sensor files before loading them into Snowflake. Files arrive continuously from thousands of devices across multiple regions, and both COPY INTO performance and future reprocessing need to stay manageable. Which structure should they choose?
Correct answer: A — Partition the stage path by ingestion date and region, like `/region=eu/year=2026/month=09/day=17/`, and reference that pattern in COPY INTO.
- A. Partitioning by date and region gives COPY INTO a predictable prefix to scan and lets reprocessing target a narrow date range instead of the entire bucket.
- B. A flat, unpartitioned prefix forces COPY INTO and any reprocessing job to list and filter a rapidly growing file set with no structural shortcut, which degrades badly at scale.
- C. Provisioning a stage per device multiplies the number of objects to manage without adding any real isolation benefit, since a shared partitioned stage already scopes data per device through path metadata.
- D. Removing folder structure entirely does prevent name collisions, but it destroys the ability to prune by date or region during loading and reprocessing, which is the actual bottleneck here.
Sources5
5.Rollback: redeploy the previous version
The cheapest rollback is the one you never need. A DCM plan lists every create, alter and drop before anything changes. You can run it as snow dcm plan --target PROD or with EXECUTE DCM PROJECT … PLAN. Terraform has the same plan-then-apply step.
For a single object that isn't managed by DCM or Terraform, CREATE OR ALTER <object> creates the object or alters it to match the definition. If you keep that statement in a versioned file in a remote repository, rolling back means running the previous version of the file. The Python API offers the same behaviour through create_or_alter.
CREATE OR ALTER TABLE vacation_spots (
city VARCHAR,
airport VARCHAR,
avg_temperature_air_f FLOAT,
avg_relative_humidity_pct FLOAT,
avg_cloud_cover_pct FLOAT,
precipitation_probability_pct FLOAT
) data_retention_time_in_days = 1;Checkpoint 8 of 8· Check yourself
A column change deployed with a CREATE OR ALTER TABLE file from Git breaks a report. What is the documented way to roll the definition back?
CREATE OR ALTER converges the object to whatever definition it's given, so re-running the earlier version restores the earlier definition.
“you can roll back changes to a previous version by executing a previous version of the file”Source: docs.snowflake.com
Sources1
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.A username and password stored as a pipeline secret is fine for production CI/CD.Why is that wrong?
Password authentication is only for legacy workflows. Use a SERVICE user with OIDC workload identity federation, or a key pair if OIDC isn't available.
Covered in CI/CD pipelines with Snowflake CLI
2.dbt Projects on Snowflake can replace DCM Projects or Terraform for managing object state.Why is that wrong?
dbt manages SQL transformations. You still need DCM or Terraform to declare the objects themselves, and dbt runs alongside them.
3.A Terraform plan and a DCM plan detect exactly the same changes.Why is that wrong?
DCM plans against internal object state. Terraform reads state through public SQL and can miss attributes that SHOW and DESCRIBE don't return.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“By maintaining separate environments for development, test, and production, your teams can isolate development activities from the production environment”
↩︎ Environments, data layers and workload isolation“DCM Projects (Database Change Management Projects) are the Snowflake-native option for the objects inside your databases.”
↩︎ Objects as code: DCM Projects, Terraform and dbt“Each target maps to a specific Snowflake account (or database), project object, owner role, and templating configuration.”
↩︎ Objects as code: DCM Projects, Terraform and dbt“which creates the object or alters it to match the definition specified by the command”
↩︎ Rollback: redeploy the previous version“Declare the desired state of your Snowflake objects in version-controlled files.”
↩︎ Key concept“they manage SQL transformations rather than the declared state of your objects”
↩︎ Exam trap 2“For objects both tools manage, a DCM plan detects more.”
↩︎ Exam trap 3“you can manage Snowflake objects and non-Snowflake resources in the same configuration”
↩︎ Prediction“Terraform for the account-level layer that platform teams own, and DCM Projects for the objects inside databases that data engineers own.”
↩︎ Checkpoint“you can roll back changes to a previous version by executing a previous version of the file”
↩︎ Checkpoint - 2.
“This command is primarily used for creating zero-copy clones of databases, schemas, and tables.”
↩︎ Environments, data layers and workload isolation“For databases, schemas, and non-temporary tables, CLONE supports an additional AT | BEFORE clause for cloning using Time Travel.”
↩︎ Checkpoint - 3.
“Many teams organize pipeline layers using medallion vocabulary (bronze, silver, gold).”
↩︎ Environments, data layers and workload isolation - 4.
“automate Snowflake deployments for DCM projects, Snowpark applications, Snowflake Native Apps, and standalone SQL scripts”
↩︎ CI/CD pipelines with Snowflake CLI“Snowflake recommends workload identity federation (WIF) with OpenID Connect (OIDC) so that no long-lived secrets are stored in the CI system.”
↩︎ CI/CD pipelines with Snowflake CLI“Create a dedicated service user for each pipeline environment”
↩︎ CI/CD pipelines with Snowflake CLI“Password authentication is supported for legacy workflows but is not recommended for production CI/CD.”
↩︎ Exam trap 1“validate proposed changes on a pull request, deploy them on merge, and verify the result.”
↩︎ Checkpoint - 5.
“files from the remote repository are synchronized to a Git repository clone in Snowflake”
↩︎ Git integration as the deployment source“Commit and push changes to the remote repository from Workspaces, Streamlit apps, and Snowflake notebooks.”
↩︎ Git integration as the deployment source“Through the Git repository clone, Snowflake becomes another client of your repository separate from your local repository.”
↩︎ Checkpoint