Kubernetes-native control plane for Snowflake
Snowplane manages Snowflake resources declaratively as Kubernetes custom resources — similar in spirit to AWS ACK and Crossplane. Define your Snowflake infrastructure as CRDs and let the operator reconcile them.
| Category | Resources |
|---|---|
| 🗄️ Core Infrastructure | Database, Schema, Warehouse |
| 📊 Data Objects | Table, TableConstraint, View, MaterializedView, InternalStage, ExternalStage, StreamOnTable, StreamOnView, StreamOnExternalTable, StreamOnDirectoryTable, StreamOnDynamicTable, DynamicTable, ExternalTable, FileFormat, Pipe, Sequence |
| 🎭 Identity & Access | User, AccountRole, DatabaseRole, GrantPrivilegesToAccountRole, GrantPrivilegesToDatabaseRole, AccountRoleAssignment, DatabaseRoleAssignment, GrantPrivilegesToShare, GrantOwnership |
| 📡 Data Sharing | Share |
| ⏰ Orchestration | Task (DAG scheduling, serverless or warehouse-backed), Alert (condition-based monitoring & notification) |
| 🔧 Programmability | ProcedureSQL, ProcedureJavascript, ProcedurePython, ProcedureJava, ProcedureScala, FunctionSQL, FunctionJavascript, FunctionPython, FunctionJava, FunctionScala, ExternalFunction |
| 📦 Storage | ExternalVolume (S3/GCS/Azure multi-cloud storage for Iceberg tables) |
| 🔍 AI/ML | CortexSearchService (semantic & hybrid search powered by LLM embeddings) |
| 📂 App Development | GitRepository (Git integration for version-controlled code), Streamlit (Snowflake-native interactive Python apps) |
| 🔗 Integrations | StorageIntegrationAWS, StorageIntegrationGCS, StorageIntegrationAzure, ExternalOAuthIntegration, OAuthIntegrationForCustomClients, OAuthIntegrationForPartnerApplications, SAML2Integration, SCIMIntegration, EmailNotificationIntegration, QueueNotificationIntegration, WebhookNotificationIntegration, APIIntegration, APIAuthenticationIntegrationWithAuthorizationCodeGrant, APIAuthenticationIntegrationWithClientCredentials, APIAuthenticationIntegrationWithJWTBearer |
| 🔒 Secrets | SecretWithAuthorizationCodeGrant, SecretWithBasicAuthentication, SecretWithClientCredentials, SecretWithGenericString |
| 🛡️ Security & Governance | NetworkPolicy, NetworkPolicyAttachment, NetworkRule, AuthenticationPolicy, PasswordPolicy, PasswordPolicyAttachment, MaskingPolicy, MaskingPolicyApplication, RowAccessPolicy, Tag, TagAssociation, ResourceMonitor |
| 📤 Utilities | FieldExport (copy status fields into ConfigMaps/Secrets), SQLStatement (escape-hatch for arbitrary SQL), ProviderConfig |
| 🐳 Snowpark Container Services | ComputePool, Service, ImageRepository |
| 🔄 Replication & Failover | FailoverGroup, PrimaryConnection, SecondaryConnection |
Every resource supports full lifecycle management (create, alter, drop), drift detection, adoption of pre-existing objects, and deletion policies. See the API Reference below for detailed field documentation.
- 🔗 Cross-Resource References — Ref/Name XOR pattern: every cross-resource field supports either a Kubernetes object reference (
fooRef) or a plain Snowflake identifier (fooName), mutually exclusive via CEL. Covers database, schema, warehouse, policy, tag, and integration references with automatic dependency resolution and backoff. AllObjectReferencefields support an optionalnamespacefor cross-namespace references — enabling platform teams to manage shared infrastructure in a central namespace while project teams reference it from their own namespaces - 🔄 Observe-Diff-Apply Reconciliation — Only altered fields are pushed to Snowflake, minimizing API calls
- 🔍 Drift Detection & Correction — Field-level drift detection with structured reporting, detect-only policy option
- 🏷️ Resource Adoption — Adopt pre-existing Snowflake resources via
spec.managementPolicies.adoptionPolicy: adopt - 🔒 Immutable Field Enforcement — Two layers: CRD schema (CEL
self == oldSelf), reconciler-level errors - 🛡️ Dangerous Grant Protection — Blocks grants to ACCOUNTADMIN/SECURITYADMIN/ORGADMIN and dangerous privileges by default
- 🛡️ Policy Body Validation — Blocklist-based SQL injection prevention for MaskingPolicy and RowAccessPolicy
bodyfields - 🏷️ Ownership Conflict Detection — Prevents duplicate CRs from managing the same Snowflake object via label-based conflict detection
- ⚛️ CREATE OR ALTER — Atomic
CREATE OR ALTERenabled by default for Database, DynamicTable, Schema, Table, Warehouse, Task, Tag, View, FileFormat, MaskingPolicy, PasswordPolicy, AuthenticationPolicy, NetworkRule, RowAccessPolicy & User, with graceful fallback for unsupported Snowflake editions (opt out viaspec.managementPolicies.createOrAlter: false) - 🗑️ Deletion Policies —
Delete(drop resource) orOrphan(leave intact) - 🏷️ ForceNew Annotation — Delete+recreate on immutable field changes
- 📡 OpenTelemetry Tracing — Optional OTLP gRPC tracing for reconcile loop debugging (
--enable-tracing,--otel-endpoint) - ⚖️ Controller Sharding — Deterministic hash-based horizontal partitioning across controller replicas (
--shard-id,--shard-count)
- 🔑 Key Pair Authentication — RSA key pair auth via Kubernetes Secrets (supports encrypted PKCS#8 with passphrase)
- 🔑 Username/Password — Password auth via Kubernetes Secrets
- 🌐 Workload Identity Federation — EKS IRSA, GKE WI, AKS WI via projected ServiceAccount tokens
- 🔒 Sensitive Field Redaction — Passwords, PEM keys, tokens
[REDACTED]in all logs and events - 🛡️ CEL Validation Rules — Immutable field enforcement, ref/name XOR mutual exclusion, enum/range validation, dangerous-grant blocking at the CRD level
- 🔧 CRD Schema Defaults — Auto-defaults for
deletionPolicy,providerRef, Usertypevia CRD schema
- 📊 Custom Prometheus Metrics — Reconciliation, Snowflake ops, client pool, rate limits, drift, circuit breaker
- 📉 Grafana Dashboard — Pre-built dashboard at
config/grafana/snowplane-dashboard.json - 🔌 Connection Pooling — LRU client cache with config-change rotation, configurable max size, and idle TTL eviction
- ⏱️ Rate Limiting — Hierarchical two-level rate limiting: per-controller + per-account aggregate token-bucket limiters (configurable QPS/burst)
- 🔌 Circuit Breaker — Per-provider 3-state failure isolation (closed/open/half-open)
- ☸️ Helm Chart — Production-ready with CRDs, RBAC, ServiceMonitor, PDB
- 📋 Condition-based Status — Ready, Synced, ReferencesResolved, Terminal, DriftDetected, CredentialsInvalid, LateInitialized
┌──────────────────────────-────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌────────-──────┐ ┌────────────────────────┐ │
│ │ ProviderConfig│ │ Snowflake Resource │ │
│ │ CR │ │ Custom Resources │ │
│ └──────┬────────┘ └────────┬───────────────┘ │
│ │ │ │
│ ┌──────▼─────────────────────▼──────────────────┐│
│ │ Snowplane Controller Manager ││
│ │ ││
│ │ ┌──────────────────────────────────────────┐ ││
│ │ │ 🔗 Reference Resolver (generic) │ ││
│ │ │ Resolves fooRef/fooName → FQN (XOR) │ ││
│ │ │ Waits for dependency readiness │ ││
│ │ └──────────────────────────────────────────┘ ││
│ │ ││
│ │ ┌──────────────────────────────────────────┐ ││
│ │ │ Resource Controllers (see above) │ ││
│ │ │ Observe → Diff → Apply reconciliation │ ││
│ │ └──────────────────────────────────────────┘ ││
│ │ ││
│ │ ┌──────────────────┐ ┌───────────────────┐ ││
│ │ │ 📤 FieldExport │ │ 🔍 Drift Engine │ ││
│ │ └──────────────────┘ └───────────────────┘ ││
│ └────────────────────┬───────────────────────────┘│
│ │ │
└───────────────────────┼────────────────────────────┘
│
┌────────▼────────┐
│ ❄️ Snowflake │
│ Account │
└─────────────────┘
- Go 1.25+
- A Kubernetes cluster (kind, minikube, or remote)
- A Snowflake account with appropriate permissions
# Clone the repository
git clone https://github.com/hupe1980/snowplane.git
cd snowplane
# Install CRDs
kubectl apply -f config/crd/bases/
# Build and run locally (outside cluster)
just build
./bin/managerCreate a Secret with your Snowflake credentials:
apiVersion: v1
kind: Secret
metadata:
name: snowflake-credentials
namespace: snowplane-system
type: Opaque
stringData:
password: "your-snowflake-password"Create a ProviderConfig:
apiVersion: snowplane.hupe1980.github.io/v1alpha1
kind: ProviderConfig
metadata:
name: default
spec:
account: "your-account"
region: "us-east-1"
user: "your-user"
role: "SYSADMIN"
warehouse: "COMPUTE_WH"
authenticationType: UsernamePassword
credentials:
secretRef:
name: snowflake-credentials
namespace: snowplane-system
key: passwordapiVersion: snowplane.hupe1980.github.io/v1alpha1
kind: Database
metadata:
name: my-database
spec:
name: MY_DATABASE
comment: "Managed by Snowplane"
providerRef:
name: default
deletionPolicy: Deletekubectl apply -f database.yaml
kubectl get databases| Flag | Default | Description |
|---|---|---|
--metrics-bind-address |
:8080 |
Metrics endpoint bind address |
--health-probe-bind-address |
:8081 |
Health/readiness probe bind address |
--leader-elect |
false |
Enable leader election for HA deployments |
--leader-election-id |
snowplane-leader-election |
Leader election identity |
--max-concurrent-reconciles |
3 |
Max concurrent reconciles per controller |
--rate-limit-qps |
10 |
Sustained queries/sec to Snowflake per controller per provider (0 = disabled) |
--rate-limit-burst |
20 |
Max burst size for per-controller Snowflake API rate limiter |
--account-rate-limit-qps |
50 |
Aggregate queries/sec to Snowflake per account across all controllers (0 = disabled) |
--account-rate-limit-burst |
100 |
Max burst size for per-account aggregate rate limiter |
--requeue-interval |
5m |
Drift detection re-observe interval |
--enable-alpha-resources |
true |
Enable alpha-maturity controllers |
--disable-controllers |
"" |
Comma-separated controllers to disable (e.g. grantprivilegestoaccountrole,internalstage,view) |
--circuit-breaker-threshold |
5 |
Consecutive Snowflake failures before circuit opens |
--circuit-breaker-reset-timeout |
60s |
Backoff duration before half-open probe |
--allowed-roles |
"" |
Comma-separated allowlist of Snowflake roles permitted in ProviderConfig (case-insensitive; empty = all allowed) |
--snowflake-op-timeout |
60s |
Timeout for individual Snowflake API operations |
--watch-namespaces |
"" |
Comma-separated namespaces to watch (empty = all) |
--development |
false |
Human-readable debug logging |
| Endpoint | Check | Description |
|---|---|---|
/healthz |
Ping | Returns 200 if the manager process is running |
/readyz |
Snowflake connectivity | Pings all cached clients; 200 when all reachable |
Spec Lifecycle Policies (spec.managementPolicies):
| Field | Default | Values | Description |
|---|---|---|---|
adoptionPolicy |
fail-if-exists |
adopt / fail-if-exists |
Control adoption of pre-existing resources |
driftPolicy |
correct |
correct / detect-only |
Report drift without correcting it, or correct automatically |
createOrAlter |
true |
true / false |
Atomic CREATE OR ALTER (Database, DynamicTable, Schema, Table, Warehouse, Task, Tag, View, FileFormat, MaskingPolicy, PasswordPolicy, AuthenticationPolicy, NetworkRule, RowAccessPolicy, User) |
Annotations:
| Annotation | Default | Values | Description |
|---|---|---|---|
snowplane.hupe1980.github.io/force-new |
false |
true / false |
Delete + recreate on immutable field change |
snowplane.hupe1980.github.io/allow-dangerous-grant |
false |
true / false |
Allow grants to system roles / dangerous privileges |
snowplane.hupe1980.github.io/abandon-on-delete |
false |
true / false |
Remove finalizer without dropping the Snowflake resource |
| Label | Values | Description |
|---|---|---|
snowplane.hupe1980.github.io/maturity |
alpha / beta / stable |
CRD maturity classification |
snowplane.hupe1980.github.io/external-name-hash |
SHA-256 prefix | Ownership label — prevents duplicate CRs from managing the same Snowflake object |
helm install snowplane charts/snowplane/ \
--namespace snowplane-system --create-namespace| Parameter | Default | Description |
|---|---|---|
replicaCount |
1 |
Controller manager replicas |
controller.maxConcurrentReconciles |
3 |
Max concurrent reconciles per controller |
controller.requeueInterval |
5m |
Drift detection interval |
controller.enableAlphaResources |
true |
Enable alpha-maturity controllers |
controller.disableControllers |
"" |
Comma-separated controllers to disable |
controller.allowedRoles |
"" |
Comma-separated allowlist of permitted Snowflake roles |
controller.snowflakeOpTimeout |
60s |
Timeout for individual Snowflake API operations |
rateLimit.qps |
10 |
Per-controller Snowflake API rate limit per provider |
rateLimit.burst |
20 |
Per-controller rate limit burst size |
rateLimit.accountQps |
50 |
Per-account aggregate rate limit (all controllers) |
rateLimit.accountBurst |
100 |
Per-account aggregate burst size |
circuitBreaker.threshold |
5 |
Consecutive failures before circuit opens |
circuitBreaker.resetTimeout |
60s |
Backoff before half-open probe |
leaderElection.enabled |
true |
Enable leader election |
metrics.serviceMonitor.enabled |
false |
Create Prometheus ServiceMonitor |
grafana.dashboard.enabled |
false |
Deploy Grafana dashboard ConfigMap |
revisionHistoryLimit |
3 |
ReplicaSet history limit |
watchNamespaces |
"" |
Namespaces to watch (empty = all) |
priorityClassName |
"" |
Pod PriorityClass name |
topologySpreadConstraints |
[] |
Topology spread constraints |
extraEnv |
[] |
Additional environment variables |
extraVolumes |
[] |
Additional volumes |
extraVolumeMounts |
[] |
Additional volume mounts |
CRDs are automatically installed from charts/snowplane/crds/ on first install.
All metrics use the snowplane_ namespace.
| Metric | Type | Labels | Description |
|---|---|---|---|
snowplane_reconcile_total |
Counter | controller, result |
Reconciliation attempts |
snowplane_reconcile_duration_seconds |
Histogram | controller |
Reconciliation loop duration |
snowplane_snowflake_operation_total |
Counter | controller, operation, result |
Snowflake API call count |
snowplane_snowflake_operation_duration_seconds |
Histogram | controller, operation |
Snowflake API call duration |
snowplane_client_pool_size |
Gauge | — | Active Snowflake clients in pool |
snowplane_rate_limit_waits_total |
Counter | controller |
Rate limiter wait events |
snowplane_orphaned_resources_total |
Counter | controller |
Orphan-policy deletions |
snowplane_ownership_conflicts_total |
Counter | controller |
Ownership conflicts during adoption |
snowplane_adoption_total |
Counter | controller, result |
Adoption outcomes |
snowplane_drift_detected_total |
Counter | controller |
Drift detection events |
snowplane_account_rate_limit_waits_total |
Counter | provider |
Per-account aggregate rate limiter wait events |
snowplane_late_init_total |
Counter | controller, result |
Late-initialization events |
snowplane_preflight_failures_total |
Counter | controller, reason |
Pre-flight check failures |
snowplane_snowflake_error_codes_total |
Counter | provider, code |
Snowflake errors by error code |
snowplane_circuit_breaker_trips_total |
Counter | provider |
Circuit breaker trips |
snowplane_circuit_breaker_state |
Gauge | provider |
Breaker state (0=closed, 1=open, 2=half-open) |
snowplane_providerconfig_healthy |
Gauge | provider, account |
1=connected, 0=unhealthy |
snowplane_db_max_open_connections |
Gauge | provider |
Max open DB connections per provider |
snowplane_db_open_connections |
Gauge | provider |
Current open DB connections per provider |
snowplane_db_in_use_connections |
Gauge | provider |
In-use DB connections per provider |
snowplane_db_idle_connections |
Gauge | provider |
Idle DB connections per provider |
snowplane_db_wait_count |
Gauge | provider |
Cumulative DB connection wait count per provider |
snowplane_db_wait_duration_seconds |
Gauge | provider |
Cumulative DB connection wait duration per provider |
snowplane_nul_bytes_stripped_total |
Counter | — | NUL bytes removed from SQL strings (security observability) |
snowplane_sql_statement_executions_total |
Counter | namespace, operation |
SQLStatement executions (audit trail) |
snowplane_policy_body_rejections_total |
Counter | controller |
Policy body denylist rejections |
Import config/grafana/snowplane-dashboard.json via Grafana UI → Dashboards → Import. Panels include:
- 📈 Reconcile rate & error rate per controller
- ⏱️ Reconcile duration percentiles (P50 / P95 / P99)
- ❄️ Snowflake API latency & operation counts
- 🔌 Client pool size & rate limiter waits
- 🔍 Drift detection frequency per controller
- 🔌 Circuit breaker state & trip frequency
- 🏥 ProviderConfig health status
- 🔗 Connection pool utilization & wait times
Complete field-level documentation for all Snowplane CRDs is available in the API Reference.
| Category | Resources |
|---|---|
| 🔌 Provider | ProviderConfig |
| 🗄️ Core Infrastructure | Database, SecondaryDatabase, SharedDatabase, Schema, Warehouse |
| 📊 Data Objects | Table, View, MaterializedView, InternalStage, ExternalStage, StreamOnTable, StreamOnView, StreamOnExternalTable, StreamOnDirectoryTable, StreamOnDynamicTable, DynamicTable, FileFormat, Pipe, Sequence, ExternalTable |
| 🎭 Identity & Access | User, AccountRole, DatabaseRole, GrantPrivilegesToAccountRole, GrantPrivilegesToDatabaseRole, AccountRoleAssignment, DatabaseRoleAssignment, GrantPrivilegesToShare, GrantOwnership |
| ⏰ Orchestration | Task, Alert |
| 📦 Storage | ExternalVolume |
| 🔍 AI/ML | CortexSearchService |
| 📂 App Development | GitRepository, Streamlit |
| 🔗 Integrations | StorageIntegrationAWS, StorageIntegrationGCS, StorageIntegrationAzure, ExternalOAuthIntegration, OAuthIntegrationForCustomClients, OAuthIntegrationForPartnerApplications, SAML2Integration, SCIMIntegration, EmailNotificationIntegration, QueueNotificationIntegration, WebhookNotificationIntegration, APIIntegration, APIAuthenticationIntegrationWithAuthorizationCodeGrant, APIAuthenticationIntegrationWithClientCredentials, APIAuthenticationIntegrationWithJWTBearer |
| 🛡️ Security & Governance | AuthenticationPolicy, NetworkPolicy, NetworkPolicyAttachment, NetworkRule, PasswordPolicy, PasswordPolicyAttachment, MaskingPolicy, MaskingPolicyApplication, RowAccessPolicy, Tag, TagAssociation, ResourceMonitor |
| 🔧 Programmability | ProcedureSQL, ProcedureJavascript, ProcedurePython, ProcedureJava, ProcedureScala, FunctionSQL, FunctionJavascript, FunctionPython, FunctionJava, FunctionScala |
| 🔄 Replication & Failover | FailoverGroup, PrimaryConnection, SecondaryConnection |
| 📤 Utilities | FieldExport, SQLStatement |
All controllers include field-level drift detection on each reconciliation cycle:
- 🔎 Observe current Snowflake state
- 📊 Compute field-level diffs between spec and observed
- 🔔 If drift detected: set
DriftDetectedcondition → emit event → correct (or report only)
Detect-Only Policy — report drift without correcting:
spec:
managementPolicies:
driftPolicy: detect-onlyAdopt pre-existing Snowflake resources:
spec:
managementPolicies:
adoptionPolicy: adoptWithout this policy, the reconciler returns a Terminal error if the resource already exists. With adopt, status is populated from current state and LateInitialized condition is set.
Snowplane is designed for safe coexistence with manually-managed or Terraform-managed resources:
- 🔍 Read-only observation —
SHOWqueries never mutate state - 🔒 Finalizer-gated writes — CREATE/ALTER/DROP only for finalized resources
- 🚫 No implicit takeover — Existing resources produce
Terminalerrors unless adoption is enabled - 🏷️ Orphan deletion policy — Remove CRD without dropping the Snowflake resource
| Condition | Description |
|---|---|
✅ Ready |
Resource exists and matches desired state |
🔄 Synced |
Successful reconciliation completed |
🔗 ReferencesResolved |
Cross-resource references resolved and Ready |
🔍 DriftDetected |
Out-of-band changes detected |
❌ Terminal |
Non-retryable error (e.g. invalid identifier) |
♻️ Recoverable |
Transient error — retried automatically |
🔑 CredentialsInvalid |
Credentials invalid or missing (ProviderConfig) |
📥 LateInitialized |
Status populated from existing resource during adoption |
The cmd/tfimport tool converts Terraform state files to Snowplane CRD manifests:
go run ./cmd/tfimport -state terraform.tfstate -provider default -namespace snowflake > manifests.yaml
kubectl apply -f manifests.yamlSupported resources:
| Terraform Resource | Snowplane CRD |
|---|---|
snowflake_database |
Database |
snowflake_schema |
Schema |
snowflake_warehouse |
Warehouse |
snowflake_user |
User |
snowflake_account_role / snowflake_role |
AccountRole |
snowflake_database_role |
DatabaseRole |
snowflake_grant_privileges_to_account_role |
GrantPrivilegesToAccountRole |
snowflake_grant_privileges_to_database_role |
GrantPrivilegesToDatabaseRole |
snowflake_grant_privileges_to_share |
GrantPrivilegesToShare |
snowflake_table |
Table |
snowflake_view |
View |
snowflake_materialized_view |
MaterializedView |
snowflake_stage (internal) |
InternalStage |
snowflake_stage (external) |
ExternalStage |
snowflake_procedure_java |
ProcedureJava |
snowflake_procedure_javascript |
ProcedureJavascript |
snowflake_procedure_python |
ProcedurePython |
snowflake_procedure_scala |
ProcedureScala |
snowflake_procedure_sql |
ProcedureSQL |
snowflake_function_java |
FunctionJava |
snowflake_function_javascript |
FunctionJavascript |
snowflake_function_python |
FunctionPython |
snowflake_function_scala |
FunctionScala |
snowflake_function_sql |
FunctionSQL |
Generated manifests use deletionPolicy: Orphan. Sensitive fields are skipped and must be configured manually.
.
├── api/v1alpha1/ # CRD type definitions & validation
├── cmd/
│ ├── manager/ # Controller manager entrypoint
│ └── tfimport/ # Terraform state → Snowplane converter
├── config/
│ ├── crd/bases/ # CRD YAML manifests
│ ├── grafana/ # Grafana dashboard JSON
│ ├── manager/ # Deployment, PDB, NetworkPolicy
│ ├── rbac/ # RBAC roles and bindings
│ └── samples/ # Example CR YAML files
├── charts/snowplane/ # Helm chart
├── docs/ # Documentation
├── hack/ # Dev & codegen scripts
├── kro/ # KRO ResourceGraphDefinitions (composite resources)
├── internal/
│ ├── circuitbreaker/ # Per-provider 3-state failure isolation
│ ├── clients/
│ │ ├── clientfactory/ # Client cache with hash-based rotation
│ │ └── snowflake/ # Snowflake SDK wrapper & SQL builder
│ ├── controller/ # All reconcilers (managed resources + FieldExport + ProviderConfig)
│ │ └── refresolver/ # Generic ref/name resolver (ResolveSourceRef[T])
│ ├── drift/ # Field-level drift detection engine
│ ├── metrics/ # Custom Prometheus metrics
│ ├── provider/ # Provider config builder & client resolution
│ ├── ratelimit/ # Hierarchical per-controller + per-account rate limiter
│ ├── sfretry/ # Retry wrapper for transient Snowflake errors
│ ├── testutil/ # Shared test utilities and reconciler suite
│ ├── tracked/ # Generic tracked parameter computation via struct tags
│ └── utils/ # Conditions, finalizers, sanitizers
└── test/
├── e2e/ # End-to-end tests (kind + real Snowflake)
└── integration/ # envtest integration tests
| Guide | Description |
|---|---|
| 📘 Getting Started | Installation, ProviderConfig setup, first resources |
| 📖 API Reference | Complete field-level documentation for all CRDs |
| ☸️ Helm Chart | Helm chart configuration and RBAC |
| 🏭 Production Guide | Production hardening, security, scaling, DR |
| 📊 Observability | Metrics, logging, events, probes, Grafana, circuit breaker |
| 🔍 Drift Detection | Drift engine, detect-only policy, field-level reporting |
| 📋 CRD Lifecycle | Maturity classification and graduation |
| 🏗️ Architecture | Reconciler state machine, adapter pattern, resilience layers |
| 🛠️ Development | Project layout, patterns, contributing |
| 🔧 Troubleshooting | Condition reference, common scenarios, debug collection |
| 🌐 Workload Identity | External OAuth and Workload Identity Federation |
| 🔐 Snowflake Role Setup | Required Snowflake roles and permissions |
| 🚀 GitOps with Argo CD | Health checks, sync waves, ArgoCD setup |
| 🚀 GitOps with Flux | Kustomization dependencies, health checks, Flux setup |
| 🧩 Adding a Resource | Guide for adding new Snowflake resource types |
| 🏷️ Annotations | Annotations reference |
| 💡 Concepts | Core concepts overview |
| 📝 Contributing | Contributing guide |
| 🧩 KRO Integration | Kube Resource Orchestrator composite resources |
- 🍴 Fork the repository
- 🌿 Create a feature branch (
git checkout -b feature/amazing-feature) - ✅ Run tests (
just test) - 🔍 Run linter (
just lint) - 💾 Commit your changes (
git commit -m 'Add amazing feature') - 📤 Push to the branch (
git push origin feature/amazing-feature) - 🔀 Open a Pull Request
This project is licensed under the Apache License 2.0 — see the LICENSE file for details.