Account-Level Object Architecture
Overview
The Account-Level Object Architecture is a new pattern in Liquibase that enables discovery and management of Snowflake account-level objects like warehouses, resource monitors, integrations, and network policies. This is the first implementation of this pattern in Liquibase.
Key Components
1. AccountSnowflake Object (AccountSnowflake.java)
The AccountSnowflake class serves as the top-level container for all account-level objects:
Extends:
AbstractDatabaseObjectPurpose: Container for account-level objects that exist at the account scope
Key Features:
Stores child objects in internal collection (
accountObjects)Exposes children via serialization attributes for YAML/JSON output
Provides typed accessors (e.g.,
getWarehouses())
Serialization Pattern
The key innovation is using Liquibase's attribute-based serialization:
// Store warehouses as attribute for serialization
setAttribute("warehouses", warehouseList);This ensures warehouses appear in snapshot output under the account:
accountSnowflake:
warehouses:
- liquibase.ext.snowflake.database.object.WarehouseSnowflake#COMPUTE_WH
- liquibase.ext.snowflake.database.object.WarehouseSnowflake#INT_DB_TEST_WH
2. StandaloneWarehouseSnapshotGenerator
The snapshot generator implements the discovery pattern:
Priority: 150 (higher than other generators)
Scope: Handles both
WarehouseSnowflakeandAccountSnowflakeobjectsDiscovery: Uses
SHOW WAREHOUSESSQL commandIntegration: Populates
AccountSnowflakeobjects with discovered warehouses
Key Methods
@Override
public Class<? extends DatabaseObject>[] addsTo() {
return new Class[] { AccountSnowflake.class };
}
@Override
protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) {
// Discover warehouses and add to AccountSnowflake
}3. Core Liquibase Integration
The architecture requires core Liquibase modifications:
Extension Point:
discoverRootLevelExtensionObjects()in snapshot frameworkObject Registration: AccountSnowflake and WarehouseSnowflake in service files
Type Discovery: Framework discovers account-level objects alongside traditional schema objects
Discovery Flow
Initialization: Liquibase snapshot framework starts
Root Object Discovery: Core calls
discoverRootLevelExtensionObjects()Account Discovery:
StandaloneWarehouseSnapshotGeneratordiscoversAccountSnowflakeWarehouse Population: Generator executes
SHOW WAREHOUSESand populates accountSerialization: Account object exposes warehouses via
setAttribute("warehouses", ...)Output: Warehouses appear nested under account in YAML/JSON
Object Hierarchy
AccountSnowflake (account-level container)
├── WarehouseSnowflake (compute clusters)
├── ResourceMonitorSnowflake (future: usage controls)
├── IntegrationSnowflake (future: external connections)
└── NetworkPolicySnowflake (future: IP access controls)Configuration
Service Registration
Objects must be registered in META-INF/services/liquibase.structure.DatabaseObject:
liquibase.ext.snowflake.database.object.AccountSnowflake
liquibase.ext.snowflake.database.object.WarehouseSnowflakeGenerators in META-INF/services/liquibase.snapshot.SnapshotGenerator:
liquibase.ext.snowflake.snapshot.StandaloneWarehouseSnapshotGeneratorSnapshot Control
The framework automatically includes account-level objects in snapshot types:
snapshotControl:
includedType:
- liquibase.ext.snowflake.database.object.AccountSnowflake
- liquibase.ext.snowflake.database.object.WarehouseSnowflake
Technical Implementation Details
Container Pattern
Unlike traditional schema-level objects (Tables, Columns), account-level objects use a container pattern:
Parent Object:
AccountSnowflakeacts as containerChild Objects:
WarehouseSnowflakeobjects stored in parentSerialization: Children exposed via parent's attributes
Priority System
Generator priorities ensure correct processing order:
Account Generator: Priority 150 (high)
Schema Generators: Lower priorities
Result: Account objects processed before schema objects
Database Connection
Account-level discovery requires appropriate Snowflake privileges:
Warehouse Discovery:
SHOW WAREHOUSESprivilegeConnection Scope: Account-level connection (not schema-specific)
Usage Examples
Snapshot Command
liquibase snapshot --snapshot-format=yamlExpected Output
objects:
liquibase.ext.snowflake.database.object.AccountSnowflake:
- accountSnowflake:
warehouses:
- liquibase.ext.snowflake.database.object.WarehouseSnowflake#COMPUTE_WH
- liquibase.ext.snowflake.database.object.WarehouseSnowflake#INT_DB_TEST_WH
Extension Points
Adding New Account-Level Objects
Create object class extending
AbstractDatabaseObjectAdd typed accessor to
AccountSnowflake(e.g.,getResourceMonitors())Update generator to discover new object type
Register in service files
Custom Discovery Logic
Override discovery methods in generator:
private Collection<NewAccountObject> discoverNewObjects(Database database) {
// Custom SHOW command or API call
}Testing
Integration Tests
Test framework validates:
Object discovery and population
Serialization correctness
Generator priority handling
Database connection requirements
User Acceptance Tests
End-to-end validation:
Snapshot generation includes account objects
YAML/JSON output structure correct
All warehouse properties captured
Troubleshooting
Common Issues
Empty Account Objects: Ensure
setAttribute()called after populatingMissing Warehouses: Check Snowflake privileges and connection
Serialization Problems: Verify attribute naming and types
Debug Output
Enable debug logging to trace:
Generator priority selection
Object discovery process
Serialization attribute updates
Framework integration points
Future Enhancements
Resource Monitor Support: Add ResourceMonitorSnowflake objects
Integration Objects: External service connections
Network Policies: IP-based access controls
User and Role Management: Account-level security objects
This architecture provides a foundation for comprehensive Snowflake account management through Liquibase.