Provisions a single Databricks compute cluster and its attached library dependencies as one unit, against the
databricks/databricksprovider~> 1.117.0.
- π₯οΈ Creates one
databricks_clusterβ the keystone compute resource for interactive and automated workloads. - π¦ Attaches zero or more libraries via separate
databricks_libraryresources, keyed by a stable caller-chosen identifier,for_each-driven β nevercount, never the cluster's inlinelibraryblock. - π Defaults to
USER_ISOLATIONaccess mode and a 30-minute auto-termination window β a caller must type extra characters to loosen either. - π« Never accepts a credential, host, or account ID.
- π Workspace-plane only β this resource cannot be used with an account-level provider.
π‘ Why it matters: a cluster is never created without its required libraries already declared, so library drift is caught at plan time rather than discovered at job-run time. Cost and access-mode defaults are chosen for a regulated, multi-tenant workspace, not the API's own looser defaults.
If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:
- β Star this repository to help others discover this Terraform module.
- π€ Connect with me on LinkedIn: linkedin.com/in/microsoftexpert
- β Buy me a coffee: buymeacoffee.com/microsoftexpert
Whether it's a star, a professional connection, or a coffee, every gesture helps keep these modules actively maintained and continually improving. Thank you for being part of the community!
flowchart LR
POLICY["terraform-databricks-cluster-policy"]
style POLICY fill:#F2F2F2,color:#1B3139,stroke:#CCCCCC,stroke-width:1px
POOL["terraform-databricks-instance-pool"]
style POOL fill:#F2F2F2,color:#1B3139,stroke:#CCCCCC,stroke-width:1px
THIS["terraform-databricks-cluster"]
style THIS fill:#FF3621,color:#fff,stroke:#1B3139,stroke-width:1px
JOB["terraform-databricks-job"]
style JOB fill:#F2F2F2,color:#1B3139,stroke:#CCCCCC,stroke-width:1px
PERMS["terraform-databricks-permissions"]
style PERMS fill:#F2F2F2,color:#1B3139,stroke:#CCCCCC,stroke-width:1px
POLICY -->|"id becomes policy_id (optional)"| THIS
POOL -->|"id becomes instance_pool_id (optional)"| THIS
THIS -->|"id becomes task cluster_id (planned)"| JOB
THIS -->|"id becomes object_id (planned)"| PERMS
terraform-databricks-cluster-policy and terraform-databricks-instance-pool are optional upstream
siblings, consumed only by ID (policy_id, instance_pool_id) β this module never creates either.
terraform-databricks-job and terraform-databricks-permissions are downstream consumers of this
module's id. Validated via the Mermaid Chart MCP before being embedded here.
βΉοΈ
terraform-databricks-cluster-policyandterraform-databricks-instance-poolwere being authored in parallel with this module in the same session and did not yet haveoutputs.tffiles when this README was written β the edges above and the end-to-end composition example (Β§ Example Library, item 14) reflect their plannedidoutput contract, not a verified cross-moduleterraform plan.
flowchart TB
subgraph INPUTS["var.*"]
CORE["cluster_name / spark_version / node_type_id"]
SIZE["autoscale / num_workers / autotermination_minutes"]
REFS["policy_id / instance_pool_id (optional, by id)"]
ESCAPE["spark_conf / custom_tags"]
LIBS["libraries (keyed map)"]
end
KEYSTONE["databricks_cluster.this"]
style KEYSTONE fill:#1B3139,color:#fff,stroke:#1B3139,stroke-width:1px
CHILD["databricks_library.this[key] (separate resource type, for_each)"]
style CHILD fill:#FF3621,color:#fff,stroke:#1B3139,stroke-width:1px
subgraph OUTPUTS["outputs"]
ID["id (cluster id)"]
LIBIDS["library_ids (map of key to library id)"]
end
CORE --> KEYSTONE
SIZE --> KEYSTONE
REFS --> KEYSTONE
ESCAPE --> KEYSTONE
LIBS --> CHILD
KEYSTONE -->|"cluster_id"| CHILD
KEYSTONE --> ID
CHILD --> LIBIDS
Resource inventory: two resource types β databricks_cluster.this (single, keystone) and
databricks_library.this (for_each over var.libraries, keyed by library identifier). The
child is a genuinely separate resource type in this pinned provider version, not a nested block β
see "Schema notes that bite" below.
| Requirement | Value |
|---|---|
| Terraform | >= 1.12.0 |
databricks/databricks |
~> 1.117.0 |
| Provider block | None β the caller's root module configures provider "databricks" {} |
custom_tags |
Supported β confirmed top-level optional map(string) on databricks_cluster; exposed as a typed escape hatch |
spark_conf |
Supported β confirmed top-level optional map(string); exposed as a typed escape hatch for the long tail of Spark configuration |
timeouts |
Schema-confirmed (create/update/delete all optional strings) but not exposed by this module β out of this module's bounded typed-contract scope; add it in a future minor version if a caller needs longer creation timeouts |
Schema notes that bite:
databricks_clusterexposes two ways to attach libraries: an inlinelibrarynested block (nesting_mode: set) directly on the cluster, and the fully separatedatabricks_libraryresource keyed by its own requiredcluster_id. This module uses only the separate resource, viafor_eachβ the inline block cannot be keyed by a stable identifier the way a separate resource can, and mixing both would create two divergent library-attachment paths for the same cluster. See SCOPE.md's "Design decisions."jar,whl, andrequirementsare plain string attributes ondatabricks_libraryin this pinned provider version, confirmed againstschema.jsonβ not nested blocks.pypi,maven, andcranremain nested blocks and are rendered viadynamicblocks inmain.tf.databricks_libraryrequires exactly one library type per entry (provider docs: "It's possible to set only one type of library within one resource. Otherwise, the plan will fail with an error."). This module enforces that with avalidation {}block onvar.librariesrather than letting a malformed entry fail only atplantime against a live workspace.terraform providers schema -jsondoes not surface ForceNew/"requires replace" metadata β that information lives only in the provider's own documentation, not the schema dump. Any force-new claim in this README or Architecture Notes aboutnode_type_id,spark_version, or similar cluster arguments is sourced from the live provider docs consulted at authoring time, not fromschema.json, and should be re-verified at any future revision rather than assumed stale-safe from this file.node_type_idis Required unlessinstance_pool_idis set (or a referencedpolicy_idpresets it) β confirmed in the live provider docs' argument reference. This module types it as optional and does not hard-validate the either/or relationship, for the same policy-driven- defaults reasoning as theautoscale/num_workersprecedence rule (see Architecture Notes).data_security_modeenum discrepancy: this library's Secure-by-default convention previously named the legacy opt-out value"LEGACY_SINGLE_USER_STANDARD". That string does not exist in the livedatabricks/databricksprovider schema or docs for~> 1.117.0β the real legacy values areLEGACY_PASSTHROUGHandLEGACY_TABLE_ACL(plusNONE/NO_ISOLATION). This module'svalidation {}block uses the confirmed live values. Flagged as a correction candidate for that convention, not silently patched over.databricks_libraryimport is not currently supported, per the live provider docs β see Troubleshooting.autotermination_minutesaccepts0(disabled) or an integer between10and10000inclusive β validated viavalidation {}since Terraform's type system can't express a bounded numeric range natively.
- Workspace-level: cluster creation permission (
CAN_MANAGEat the workspace level, or the unrestricted cluster-creation entitlement, depending on the workspace's cluster-creation policy configuration β sourced from Databricks' access-control documentation for clusters, not the raw provider schema, which does not encode permission requirements). - If
policy_idis set:CAN_USEon the referenced cluster policy. - Attaching a
databricks_libraryrequires the same cluster-management permission as the parent cluster; the provider does not expose a separate library-level permission.
- Workspace-level provider context (not account-level) β
databricks_clusteranddatabricks_libraryare both workspace-plane resources per the live schema. - If
instance_pool_idis set, the referenced pool must already exist in the same workspace. - If
policy_idis set, the referenced cluster policy must already exist in the same workspace.
terraform-databricks-cluster/
βββ providers.tf # required_providers only β no provider {} block
βββ variables.tf # cluster_name, spark_version (required); autoscale, num_workers,
β # data_security_mode, autotermination_minutes, policy_id,
β # instance_pool_id, spark_conf, custom_tags, libraries (optional)
βββ main.tf # databricks_cluster.this + databricks_library.this (for_each)
βββ outputs.tf # id first, then library_ids
βββ SCOPE.md # cross-module contract
βββ README.md # this file
βββ examples/
βββ basic/
βββ main.tf # smallest real, runnable call
module "shared_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "shared-autoscaling"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
autoscale = {
min_workers = 1
max_workers = 8
}
}The caller's root module configures provider "databricks" {} (host + auth) and passes it in
implicitly, or explicitly via a providers = {} map for a multi-workspace root β this module
accepts neither a provider block nor any credential-shaped variable.
Consumes:
| Input | Type | Source module |
|---|---|---|
policy_id |
optional(string) |
terraform-databricks-cluster-policy output id |
instance_pool_id |
optional(string) |
terraform-databricks-instance-pool output id |
Emits:
| Output | Description | Consumed by |
|---|---|---|
id |
Cluster ID (databricks_cluster.this.id) |
terraform-databricks-job (task cluster targeting), terraform-databricks-permissions |
library_ids |
Map of library key β databricks_library.this[key].id |
Auditing / drift-detection tooling |
1 Β· Minimal least-privilege baseline
module "baseline_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "baseline"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
}π‘ With no
autoscale/num_workersset, this cluster relies entirely on the Databricks API's own single-node defaults for sizing.data_security_modedefaults toUSER_ISOLATIONandautotermination_minutesdefaults to30β both this module's secure defaults, not the API's.
2 Β· Autoscaling cluster
module "autoscaling_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "shared-autoscaling"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
autoscale = {
min_workers = 1
max_workers = 8
}
}3 Β· Fixed-size cluster with explicit num_workers
module "fixed_size_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "fixed-size"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS4_v2"
num_workers = 4
}βΉοΈ Omit
autoscaleentirely to get a fixed-size cluster β this module rendersnum_workersonly whenautoscaleis null.
4 Β· SINGLE_USER access mode (explicit opt-in)
module "single_user_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "ml-single-user"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
data_security_mode = "SINGLE_USER"
num_workers = 2
}π The Databricks API requires
single_user_namewhendata_security_mode = "SINGLE_USER". This module does not exposesingle_user_nameas a separate variable β set the assigned principal out of band via the workspace UI/API, or track it in a future module version if this becomes a common pattern.
5 Β· Legacy access mode (explicit opt-in, not Unity-Catalog-safe)
module "legacy_table_acl_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "legacy-shared"
spark_version = "13.3.x-scala2.12"
node_type_id = "Standard_DS3_v2"
data_security_mode = "LEGACY_TABLE_ACL"
num_workers = 2
}
β οΈ LEGACY_TABLE_ACLandLEGACY_PASSTHROUGHare not Unity-Catalog-compatible access modes. Reserve these for migrating existing workloads only β new clusters should useUSER_ISOLATIONorSINGLE_USER.
6 Β· Policy-driven sizing (autoscale and num_workers both omitted)
module "policy_driven_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "policy-scoped"
spark_version = "15.4.x-scala2.12"
policy_id = "600123456789abcd"
}βΉοΈ Both
autoscale/num_workersandnode_type_idare legitimately absent here β the referenced cluster policy supplies sizing and node-type defaults. This module does not hard-validate against this configuration; see Architecture Notes.
7 Β· Instance-pool-backed cluster
module "pooled_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "pooled"
spark_version = "15.4.x-scala2.12"
instance_pool_id = "1234-567890-abcd123"
autoscale = {
min_workers = 2
max_workers = 6
}
}βΉοΈ
node_type_idis omitted β the instance pool supplies it.instance_pool_idis consumed here only by reference;terraform-databricks-instance-poolowns the pool's lifecycle.
8 Β· spark_conf and custom_tags escape hatches
module "tuned_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "tuned"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
num_workers = 4
spark_conf = {
"spark.databricks.io.cache.enabled" = "true"
"spark.databricks.io.cache.maxDiskUsage" = "50g"
}
custom_tags = {
cost_center = "analytics-platform"
environment = "prod"
}
}9 Β· Auto-termination disabled (cost risk, explicit opt-in)
module "always_on_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "always-on-shared"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
num_workers = 2
autotermination_minutes = 0
}
β οΈ autotermination_minutes = 0disables auto-termination entirely. This cluster bills continuously until manually terminated β only use this for a deliberate, reviewed workload with its own cost-governance process.
10 Β· Single library via PyPI
module "cli_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "cli-enabled"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
num_workers = 2
libraries = {
databricks-cli = {
pypi = {
package = "databricks-cli"
}
}
}
}11 Β· Multiple libraries mixing pypi, maven, and jar in one call
module "multi_library_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "data-quality"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
num_workers = 4
libraries = {
fbprophet = {
pypi = {
package = "fbprophet==0.6"
}
}
deequ = {
maven = {
coordinates = "com.amazon.deequ:deequ:1.0.4"
exclusions = ["org.apache.avro:avro"]
}
}
internal-app = {
jar = "/Volumes/analytics/raw/libraries/app-0.0.1.jar"
}
}
}π Each
librariesentry sets exactly one library type. This module rejects an entry with zero or more than one type set at plan time β see "Schema notes that bite."
12 Β· CRAN and requirements.txt libraries
module "r_and_python_reqs_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "r-and-python"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
num_workers = 2
libraries = {
rkeops = {
cran = {
package = "rkeops"
}
}
pinned-requirements = {
requirements = "/Workspace/Shared/pipelines/requirements.txt"
}
}
}βΉοΈ
requirementsrequires a cluster running DBR 15.0 or later per the live provider docs.
13 Β· Cluster with no libraries (valid, common baseline)
module "no_library_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "notebook-only"
spark_version = "15.4.x-scala2.12"
node_type_id = "Standard_DS3_v2"
num_workers = 2
# libraries defaults to {} β no databricks_library resources are created.
}ποΈ 14 Β· End-to-end composition β cluster-policy + instance-pool β cluster β (planned) job
module "team_policy" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster-policy.git?ref=v1.0.0"
name = "analytics-team-policy"
#... policy definition fields omitted for brevity; not part of this module.
}
module "shared_pool" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-instance-pool.git?ref=v1.0.0"
name = "analytics-shared-pool"
node_type_id = "Standard_DS3_v2"
#... remaining pool sizing fields omitted for brevity; not part of this module.
}
module "analytics_cluster" {
source = "git::https://github.com/microsoftexpert/terraform-databricks-cluster.git?ref=v1.0.0"
cluster_name = "analytics-shared"
spark_version = "15.4.x-scala2.12"
policy_id = module.team_policy.id
instance_pool_id = module.shared_pool.id
autoscale = {
min_workers = 2
max_workers = 10
}
libraries = {
databricks-cli = {
pypi = {
package = "databricks-cli"
}
}
}
}
# Planned β terraform-databricks-job is not yet authored in this catalog batch.
# module "nightly_etl" {
# source = "git::https://github.com/microsoftexpert/terraform-databricks-job.git?ref=v1.0.0"
#
# tasks = {
# etl = {
# existing_cluster_id = module.analytics_cluster.id
# notebook_task = {
# notebook_path = "/Shared/pipelines/nightly_etl"
# }
# }
# }
# }βΉοΈ
terraform-databricks-cluster-policyandterraform-databricks-instance-poolwere authored in parallel with this module in the same session and did not have finaloutputs.tffiles at the time this composition was written βmodule.team_policy.idandmodule.shared_pool.idreflect their plannedidoutput contract, not a verified cross-moduleterraform plan.terraform-databricks-jobis not yet authored in this catalog batch at all; its block above is commented out and reflects the planned catalog contract per this library's module suite table.
| Variable | Type | Default | Notes |
|---|---|---|---|
cluster_name |
string |
β (required) | Non-empty; stricter than the schema's own Optional |
spark_version |
string |
β (required) | |
node_type_id |
string |
null |
Required unless instance_pool_id/policy_id supplies it (not hard-validated) |
instance_pool_id |
string |
null |
By reference β terraform-databricks-instance-pool output id |
policy_id |
string |
null |
By reference β terraform-databricks-cluster-policy output id |
data_security_mode |
string |
"USER_ISOLATION" |
Closed enum, validated |
autotermination_minutes |
number |
30 |
0 or 10β10000, validated |
autoscale |
object({ min_workers, max_workers }) |
null |
Preferred over num_workers when set |
num_workers |
number |
null |
Ignored (rendered null) when autoscale is set |
spark_conf |
map(string) |
{} |
Escape hatch |
custom_tags |
map(string) |
{} |
Escape hatch |
libraries |
map(object({...})) |
{} |
for_each-keyed; exactly one library type per entry, validated |
Full variable declarations
variable "cluster_name" {
type = string
# validation: must not be empty
}
variable "spark_version" {
type = string
# validation: must not be empty
}
variable "node_type_id" {
type = string
default = null
}
variable "instance_pool_id" {
type = string
default = null
}
variable "policy_id" {
type = string
default = null
}
variable "data_security_mode" {
type = string
default = "USER_ISOLATION"
# validation: one of USER_ISOLATION, SINGLE_USER, LEGACY_PASSTHROUGH, LEGACY_TABLE_ACL, NONE, NO_ISOLATION
}
variable "autotermination_minutes" {
type = number
default = 30
# validation: 0, or between 10 and 10000 inclusive
}
variable "autoscale" {
type = object({
min_workers = number
max_workers = number
})
default = null
}
variable "num_workers" {
type = number
default = null
}
variable "spark_conf" {
type = map(string)
default = {}
}
variable "custom_tags" {
type = map(string)
default = {}
}
variable "libraries" {
type = map(object({
jar = optional(string)
whl = optional(string)
requirements = optional(string)
pypi = optional(object({
package = string
repo = optional(string)
}))
maven = optional(object({
coordinates = string
repo = optional(string)
exclusions = optional(list(string))
}))
cran = optional(object({
package = string
repo = optional(string)
}))
}))
default = {}
# validation: each entry must set exactly one of jar, whl, requirements, pypi, maven, cran
}| Output | Description | Sensitive? |
|---|---|---|
id |
Cluster ID (databricks_cluster.this.id) |
No |
library_ids |
Map of library key β databricks_library.this[key].id |
No |
autoscale/num_workersprecedence, not mutual-exclusivity validation. The Databricks API treats these as mutually exclusive, but this module does not enforce that with a hardvalidation {}block β apolicy_id-scoped cluster can legitimately leave both null, relying entirely on the referenced cluster policy for sizing.main.tfinstead implements a precedence rule: whenautoscaleis set,num_workersis always renderednull, regardless of what the caller passed tonum_workers.for_eachkey stability for libraries.databricks_library.thisis keyed by the caller's chosen string invar.libraries, not a list index β removing one library from the middle of the map does not re-index or force replacement of any other library, unlike acount-based or inline-block-driven approach would risk.- Separate resource over inline block, deliberately.
databricks_clusterexposes an inlinelibraryblock, but this module attaches libraries exclusively through the standalonedatabricks_libraryresource so each attachment has its own stable identity and can be added, removed, or changed independently without touching the keystone cluster resource's plan. node_type_idoptionality is real, not an oversight. It is typedoptional(string)because it is legitimately absent wheninstance_pool_idor a referencedpolicy_idsupplies the node type β see "Schema notes that bite."- No sensitive outputs. Neither
idnorlibrary_idscarries a credential or secret; no output in this module is markedsensitive = true.
| Concern | Secure default | Opt-out (caller must set explicitly) |
|---|---|---|
| Cluster autotermination | autotermination_minutes = 30 if the caller does not set it |
Set autotermination_minutes = 0 to disable (module documents the cost risk in a > β οΈ callout) |
| Cluster access mode | data_security_mode = "USER_ISOLATION" |
"SINGLE_USER", "LEGACY_PASSTHROUGH", "LEGACY_TABLE_ACL", "NONE", or "NO_ISOLATION" require explicit opt-in |
| Cluster autoscaling | autoscale block preferred over fixed num_workers when the caller supplies a min/max |
Fixed-size clusters require the caller to omit autoscale and set num_workers explicitly |
| Cluster policy enforcement | policy_id is a nullable escape hatch, not a required input |
Omitting policy_id is allowed but flagged with a > βΉοΈ callout recommending policy enforcement in regulated environments |
This table matches what main.tf/variables.tf actually implement β no row here that the code
doesn't enforce, and no enforced default missing from this table.
cd terraform-databricks-cluster
terraform init -backend=false
terraform validate
terraform fmt -checkPin consumers to an immutable tag β ?ref=v1.0.0 β never a branch. This module is plan-only; a
human applies from CI after review.
terraform validate / terraform fmt -check catch: missing required arguments (cluster_name,
spark_version), the data_security_mode enum validation, the autotermination_minutes range
validation, and the libraries-exactly-one-type validation. They do not catch: whether the
applying identity actually holds cluster-creation permission or CAN_USE on a referenced policy,
whether a referenced instance_pool_id/policy_id actually exists in the target workspace,
whether max_workers is genuinely greater than min_workers in autoscale (documented but not
type-system-enforceable), or any real Databricks API-side constraint (quota, node-type
availability, region). Those require an actual plan/apply against a live workspace, out of
scope for this authoring process.
$ terraform output
id = "1234-567890-abcd1234"
library_ids = {
"databricks-cli" = "1234-567890-abcd1234/databricks-cli"
}
| Symptom | Cause | Fix |
|---|---|---|
terraform validate fails on data_security_mode |
Value outside the confirmed enum | Correct to one of USER_ISOLATION, SINGLE_USER, LEGACY_PASSTHROUGH, LEGACY_TABLE_ACL, NONE, NO_ISOLATION |
terraform validate fails on autotermination_minutes |
Value outside 0 or 10β10000 |
Correct the value; 0 disables auto-termination entirely |
terraform validate fails on a libraries entry |
Zero or more than one of jar/whl/requirements/pypi/maven/cran set on the same entry |
Set exactly one library type per entry |
Apply fails with a permissions error even though terraform validate passed |
Applying identity lacks cluster-creation permission, or CAN_USE on the referenced policy_id |
Confirm the identity holds the required Databricks permission |
Apply fails referencing instance_pool_id or policy_id |
The referenced pool/policy doesn't exist in the target workspace, or belongs to a different workspace | Confirm the ID and workspace match; both must be created before this module applies |
terraform import databricks_library.this[...] fails |
Library import is not currently supported by the provider | Remove the resource from state and re-apply instead, or manage the library entry purely through var.libraries going forward |
| Cluster restarts unexpectedly on an unrelated apply | node_type_id or spark_version changed β the provider resizes/restarts the cluster in place rather than issuing a Terraform-level force-new |
Treat any change to these fields as a deliberate operational event, not a no-op |
databricks_clusterprovider resourcedatabricks_libraryprovider resourceterraform-databricks-cluster-policy(optional upstream, providespolicy_id)terraform-databricks-instance-pool(optional upstream, providesinstance_pool_id)terraform-databricks-job(planned downstream consumer ofid)terraform-databricks-permissions(planned downstream consumer ofid)- This module's
SCOPE.md
π "Infrastructure as Code should be standardized, consistent, and secure."