Project Structure
On this page, you will:
- Understand the module-based approach for Snowflake Terraform
- Create the directory structure for modules
- Learn how to pass providers to modules
Why Modules?
In the Getting Started section, you created a Terraform configuration with multiple aliased providers and basic user management. That flat structure works for simple setups, but as your data warehouse grows, you'll need a more scalable approach.
Terraform modules provide:
- Reusability: Define a resource pattern once, use it many times
- Encapsulation: Hide complexity behind a simple interface
- Consistency: Every database, warehouse, and user follows the same patterns
- Maintainability: Update the module, and all instances benefit
For example, the snowflake_database module we'll build creates not just the database, but also:
- A
DB_READERdatabase role with read-only access - A
DB_WRITERdatabase role with full access - All necessary grants for both roles
- Future grants for objects that don't exist yet
This means creating a new database is as simple as:
module "database_analytics" {
source = "./modules/snowflake_database"
# ... providers ...
database_name = "ANALYTICS"
database_comment = "Production analytics models."
grant_database_reader_to_account_roles = ["ANALYTICS_DEVELOPER"]
grant_database_writer_to_account_roles = ["ANALYTICS_TRANSFORMER"]
}
Create the Modules Directory
Navigate to your Snowflake Terraform directory:
cd ~/projects/data/data-stack-infrastructure/terraform/snowflake
Create the directory structure for your modules:
mkdir -p modules
Your directory structure will look like this:
terraform/snowflake/
├── modules/
│ ├── snowflake_warehouse/
│ ├── snowflake_database/
│ ├── snowflake_database_role/
│ ├── snowflake_role/
│ ├── snowflake_schema/
│ ├── snowflake_user/
│ ├── snowflake_storage_integration/
│ └── snowflake_saml2_integration/
├── backend.tf
├── main.tf
├── providers.tf
├── variables.tf
├── terraform.tfvars
├── users.auto.tfvars
├── outputs.tf
├── users.tf
├── warehouses.tf # Coming soon
├── databases.tf # Coming soon
├── functional_roles.tf # Coming soon
└── README.md
Using Provider Aliases in Modules
You set up four aliased providers in the Getting Started section:
| Provider | Role | Purpose |
|---|---|---|
snowflake.account_admin |
ACCOUNTADMIN | Network policies, storage integrations |
snowflake.sys_admin |
SYSADMIN | Warehouses, databases, schemas |
snowflake.security_admin |
SECURITYADMIN | Grants and privileges |
snowflake.user_admin |
USERADMIN | Users and roles |
When you create a module, you specify which providers it needs using configuration_aliases. Here's how the snowflake_warehouse module declares its provider requirements:
terraform {
required_providers {
snowflake = {
source = "Snowflake-Labs/snowflake"
version = "~> 0.99"
configuration_aliases = [snowflake.sys_admin, snowflake.security_admin]
}
}
}
When calling the module, you pass the providers from your root configuration:
module "warehouse_loading" {
source = "./modules/snowflake_warehouse"
providers = {
snowflake.sys_admin = snowflake.sys_admin
snowflake.security_admin = snowflake.security_admin
}
warehouse_name = "LOADING"
warehouse_comment = "Warehouse for data loading operations."
# ...
}
Inside the module, resources specify which provider to use:
# Create the warehouse using SYSADMIN
resource "snowflake_warehouse" "this" {
provider = snowflake.sys_admin
name = var.warehouse_name
# ...
}
# Grant usage using SECURITYADMIN
resource "snowflake_grant_privileges_to_account_role" "usage" {
provider = snowflake.security_admin
privileges = ["USAGE"]
account_role_name = each.value
# ...
}
Which Provider for Which Operation?
Here's a quick reference for which provider to use:
| Operation | Provider | Why |
|---|---|---|
| Create warehouse | sys_admin |
SYSADMIN owns object creation |
| Create database | sys_admin |
SYSADMIN owns object creation |
| Create schema | sys_admin |
SYSADMIN owns object creation |
| Grant privileges | security_admin |
SECURITYADMIN manages grants |
| Grant role to user | security_admin |
SECURITYADMIN manages grants |
| Create role | user_admin |
USERADMIN creates roles |
| Create user | user_admin |
USERADMIN creates users |
| Create network policy | account_admin |
Account-level security |
| Create storage integration | account_admin |
Account-level integration |
Commit Your Work
git add terraform/snowflake/modules/
git commit -m "Create modules directory structure"
Summary
You've set up the foundation for a module-based Snowflake configuration:
- Modules directory created
- Understanding of how to pass providers to modules
- Reference for which provider to use for each operation
What's Next
With the project structure in place, you're ready to start building modules. In the next section, you'll create the snowflake_warehouse module and set up warehouses for different workloads.
Continue to Warehouses →