The managed, serverless compute a Data Factory uses for data flow activities, targeting
hashicorp/azurerm ~> 4.0.
- βοΈ Creates one
azurerm_data_factory_integration_runtime_azureβ the compute behind data flow activities, provisioned on demand. - π§
locationaccepts a magic value that is not a region.AutoResolvemakes Data Factory pick a region per activity, so the runtime has no fixed place. - π’
core_countis a closed set, not a range β 8, 16, 32, 48, 80, 144, 272. A value like 12 or 64 is refused. - β±οΈ
time_to_live_mindefaults to 0, so the cluster is torn down after every activity and the next data flow pays full startup again. Raising it keeps the cluster billed while idle. - β
The provider's one cross-field rule fires at
terraform planand needs credentials. This module checks the same rule atterraform validateβ offline.
π‘ Why it matters: every argument except the name and the vnet toggle is a cost decision. None of them changes what a pipeline does; all of them change what it costs and how fast it starts.
If this module saved you time:
- β Star the repository β it is the cheapest signal that this work is worth continuing.
- πΌ Connect on LinkedIn: linkedin.com/in/microsoftexpert
- β Buy me a coffee: buymeacoffee.com/microsoftexpert
flowchart TB
RG["terraform-azurerm-resource-group"]
ADF["terraform-azurerm-data-factory"]
THIS["terraform-azurerm-data-factory-integration-runtime-azure"]
SELF["azurerm_data_factory_integration_runtime_self_hosted, its own module"]
SSIS["azurerm_data_factory_integration_runtime_azure_ssis, its own module"]
LS["a linked service or activity"]
FLOW["a data flow activity"]
CLUSTER["a data flow cluster, provisioned on demand and billed while warm"]
RG -->|"name"| ADF
ADF -->|"id"| THIS
ADF -->|"id"| SELF
ADF -->|"id"| SSIS
THIS -->|"name, referenced by NAME and never by id"| LS
LS -->|"runs on"| FLOW
FLOW -->|"starts and bills"| CLUSTER
THIS -->|"no credential of its own"| CLUSTER
SELF -->|"carries authorization keys a node registers with"| CLUSTER
classDef this fill:#0078D4,stroke:#004578,color:#ffffff,stroke-width:2px
classDef keystone fill:#004578,stroke:#00243d,color:#ffffff,stroke-width:2px
classDef sibling fill:#eef3f8,stroke:#b9c8d8,color:#1b2733
class THIS this
class ADF keystone
class RG,SELF,SSIS,LS,FLOW,CLUSTER sibling
Two edges carry the point: this runtime is referenced by name, never by ID, and it holds no credential of its own β unlike the self-hosted runtime, whose authorization keys let a node register with the factory.
flowchart TB
subgraph INPUTS["Inputs"]
NAME["name (force-new)"]
ADFID["data_factory_id (force-new)"]
LOC["location (force-new), a region OR the magic value AutoResolve"]
CLUSTER["compute_type, core_count, time_to_live_min, cleanup_enabled"]
VNET["virtual_network_enabled (force-new) and the interactive authoring TTL"]
DESC["description"]
end
THIS["azurerm_data_factory_integration_runtime_azure.this"]
subgraph OUTPUTS["Outputs"]
ONAME["name, the value linked services reference"]
OAUTO["location_is_auto_resolve, and the data-residency consequence"]
OCOST["cluster_stays_warm_and_billed, torn_down_after_every_activity, larger_than_default"]
OPAIR["the pairing the PROVIDER checks at plan and this module checks at plan"]
OFN["force_new_fields, which includes a boolean"]
OFACTS["the constant facts, including no credential of its own"]
end
NAME --> THIS
ADFID --> THIS
LOC --> THIS
CLUSTER --> THIS
VNET --> THIS
DESC --> THIS
THIS --> ONAME
LOC --> OAUTO
CLUSTER --> OCOST
VNET --> OPAIR
VNET --> OFN
THIS --> OFACTS
classDef this fill:#0078D4,stroke:#004578,color:#ffffff,stroke-width:2px
classDef sibling fill:#eef3f8,stroke:#b9c8d8,color:#1b2733
class THIS this
class NAME,ADFID,LOC,CLUSTER,VNET,DESC,ONAME,OAUTO,OCOST,OPAIR,OFN,OFACTS sibling
| Resource | Count | Notes |
|---|---|---|
azurerm_data_factory_integration_runtime_azure.this |
1 | The keystone. A real ARM child of the factory. |
timeouts |
dynamic, 0..1 |
All four keys exist β Terraform's, not the cluster's. |
| Requirement | Value |
|---|---|
| Terraform | >= 1.12.0 |
hashicorp/azurerm |
~> 4.0 |
| Provider block | None. The caller configures the provider, including the mandatory features {} block. |
Schema notes that bite β verified against the live provider source, not inferred from the schema:
- π΄ The interactive-authoring pairing is enforced in a
CustomizeDiff. Settinginteractive_authoring_time_to_live_in_minutesrequiresvirtual_network_enabled = true, and the provider checks it in aCustomizeDiffβ which fires atterraform planand needs credentials. Both operands are plain arguments, so this module also checks it in avalidation {}atterraform validate, offline. - π΄
locationacceptsAutoResolve, which is not a region. An auto-resolve runtime picks a region per activity from the source and sink β so a data-residency requirement is not satisfied merely because the factory is in the right region. - π΄
core_countis a CLOSED SET: 8, 16, 32, 48, 80, 144, 272. An intermediate value is refused. - π΄
virtual_network_enabledis FORCE-NEW. It reads like a toggle and is a rebuild; any warm cluster is lost. β οΈ compute_typeis case-sensitive, one ofGeneral,ComputeOptimized,MemoryOptimized, defaulting toGeneral.β οΈ time_to_live_mindefaults to 0. Non-zero keeps the cluster warm and billed whether or not work arrives.β οΈ cleanup_enabled = falsewithtime_to_live_min = 0is accepted and close to meaningless.β οΈ Setting the interactive TTL at all enables the feature β there is no separate switch.β οΈ Timeouts default to 30m / 5m / 30m / 30m and bound Terraform's management of the record, not cluster startup or activity duration.- βΉοΈ The requires-import error names this resource correctly.
| Permission | Scope | Why |
|---|---|---|
Microsoft.DataFactory/factories/integrationruntimes/write |
the Data Factory | Create and update. |
Microsoft.DataFactory/factories/integrationruntimes/read |
the Data Factory | Refresh and plan. |
Microsoft.DataFactory/factories/integrationruntimes/delete |
the Data Factory | Destroy β see below. |
Data Factory Contributor |
the Data Factory | The built-in role containing all three. |
π This runtime holds no credential of its own. It runs under the factory's identity and whatever the linked services carry, so nothing on this resource is secret and no output is sensitive. That is not true of the self-hosted runtime.
π° Creating this resource provisions no cluster and starts no billing. Charges begin when a data flow
activity runs, and continue for time_to_live_min afterwards.
- An existing Data Factory, and its Resource ID.
- A decision about
location: a real Azure region, orAutoResolve. They are different modes, not a value and a default. - If interactive authoring is wanted,
virtual_network_enabled = true. - The
Microsoft.DataFactoryresource provider registered in the subscription.
terraform-azurerm-data-factory-integration-runtime-azure/
βββ providers.tf # required_version + the pinned azurerm; no provider block
βββ variables.tf # 11 typed inputs, 10 validations
βββ main.tf # the keystone, the cost-shaped locals, one dynamic block
βββ outputs.tf # 39 outputs; id first
βββ README.md # this file
βββ SCOPE.md # the cross-module contract
βββ LICENSE # MIT
βββ .gitignore
provider "azurerm" {
features {}
}
module "data_flow_runtime" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-dataflow"
data_factory_id = var.data_factory_id
location = "eastus"
}βΉοΈ The empty call gives you an 8-core
Generalcluster with no warm window β cheap, and slow to start.
Consumes
| Input | Type | Typical source |
|---|---|---|
data_factory_id |
string |
terraform-azurerm-data-factory β id |
location |
string |
the caller β a region or AutoResolve |
Emits (selected β 39 in total)
| Output | Description |
|---|---|
name |
The value linked services and activities reference. |
location_is_auto_resolve |
Whether the magic value was used. |
cluster_stays_warm_and_billed |
Billed while idle. |
force_new_fields |
Includes a boolean. |
the_interactive_authoring_pairing_is_enforced_at_PLAN_by_the_provider |
Constant. Why this module duplicates it. |
1 Β· The minimum call
module "runtime" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-dataflow"
data_factory_id = var.data_factory_id
location = "eastus"
}π‘ 8 cores,
General,time_to_live_min = 0β the cluster is torn down after every activity.
2 Β· An auto-resolve runtime
module "auto" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-autoresolve"
data_factory_id = var.data_factory_id
location = "AutoResolve"
}
output "has_a_fixed_region" {
value = !module.auto.location_is_auto_resolve # false
}
β οΈ AutoResolveis not a region. Data Factory picks one per activity from the source and sink, so this runtime has no fixed place β which matters for data residency and for latency.
3 Β· Asserting a fixed region for data residency
module "eu_only" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-eu"
data_factory_id = var.data_factory_id
location = var.runtime_location
}
check "compute_has_a_fixed_region" {
assert {
condition = !module.eu_only.location_is_auto_resolve
error_message = "An auto-resolve runtime chooses a region per activity; it cannot satisfy a residency requirement."
}
}π Placing the factory in the right region does not constrain where an auto-resolve runtime's compute runs.
4 Β· An intermediate core count is refused
# β NOT ACCEPTED β core_count is a closed set, not a range
module "wrong_size" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-wrong"
data_factory_id = var.data_factory_id
location = "eastus"
core_count = 64 # 48 and 80 are legal; 64 is not
}
β οΈ The accepted values are 8, 16, 32, 48, 80, 144, 272. Anyone sizing by doubling from 32 will land on 64 and be refused.
5 Β· A warm cluster β and what it costs
module "warm" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-warm"
data_factory_id = var.data_factory_id
location = "eastus"
time_to_live_min = 15
}
output "billing_shape" {
value = {
warm_and_billed = module.warm.cluster_stays_warm_and_billed # true
torn_down = module.warm.cluster_is_torn_down_after_every_activity # false
}
}
β οΈ The cluster is billed for the whole 15 minutes whether or not another activity arrives. The trade is latency against cost, and the provider's default sits at the cheap, slow end.
6 Β· Disabling cleanup with no time to live
module "meaningless" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-odd"
data_factory_id = var.data_factory_id
location = "eastus"
cleanup_enabled = false
time_to_live_min = 0 # the provider's default
}
output "reported" {
value = module.meaningless.cleanup_disabled_with_no_time_to_live # true
}βΉοΈ Accepted, and close to meaningless β disabling cleanup keeps the cluster only until the TTL is reached, and there is no TTL to reach. Reported rather than refused; the intent was probably to set both.
7 Β· A larger, specialised cluster
module "memory_heavy" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-memory"
data_factory_id = var.data_factory_id
location = "eastus"
compute_type = "MemoryOptimized"
core_count = 48
time_to_live_min = 10
}
check "cost_shape_is_intentional" {
assert {
condition = module.memory_heavy.is_larger_than_the_default_cluster
error_message = "Expected a larger-than-default cluster for this workload."
}
}βΉοΈ
compute_typeandcore_countchange cost and speed, never behaviour.
8 Β· A lowercase compute type is refused
# β NOT ACCEPTED β the set is case-sensitive
module "wrong_case" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-wrong-case"
data_factory_id = var.data_factory_id
location = "eastus"
compute_type = "general" # wants "General"
}9 Β· Interactive authoring without a managed vnet β caught offline
# β NOT ACCEPTED β and refused at `terraform plan`, offline and without credentials
module "interactive_without_vnet" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-interactive"
data_factory_id = var.data_factory_id
location = "eastus"
interactive_authoring_time_to_live_in_minutes = 30
# virtual_network_enabled left at false
}π This is the module's substantive improvement. The provider enforces the same rule in a
CustomizeDiff, which fires atterraform planand needs credentials. Both operands are plain arguments, so this module checks it atterraform validateβ offline, and reachable by a caller with no subscription. The provider's check remains the authority; this one simply arrives earlier.
10 Β· Interactive authoring, correctly paired
module "interactive" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-interactive"
data_factory_id = var.data_factory_id
location = "eastus"
virtual_network_enabled = true
interactive_authoring_time_to_live_in_minutes = 30 # 10, 30, 60 or 120
}
output "interactive_on" {
value = module.interactive.interactive_authoring_enabled # true
}βΉοΈ Setting the TTL is what enables the feature β there is no separate switch, which is why the module emits
interactive_authoring_enabledas a derived boolean.
11 Β· The boolean that is a rebuild
module "runtime" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-dataflow" # changing this REPLACES
data_factory_id = var.data_factory_id # changing this REPLACES
location = "eastus" # changing this REPLACES
virtual_network_enabled = true # changing this ALSO REPLACES
core_count = 16 # changing this updates IN PLACE
}
output "what_forces_replacement" {
value = module.runtime.force_new_fields
# ["name", "data_factory_id", "location", "virtual_network_enabled"]
}
β οΈ virtual_network_enabledreads like a toggle and is a rebuild. Moving an existing runtime into or out of the managed virtual network destroys and recreates it, losing any warm cluster.
12 Β· Many runtimes from one map
locals {
runtimes = {
small = { cores = 8, ttl = 0 }
large = { cores = 48, ttl = 15 }
}
}
module "runtimes" {
for_each = local.runtimes
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-${each.key}"
data_factory_id = var.data_factory_id
location = "eastus"
core_count = each.value.cores
time_to_live_min = each.value.ttl
}
output "warm_runtimes" {
value = [for k, m in module.runtimes : k if m.cluster_stays_warm_and_billed]
}π‘ A useful review artefact: the list of runtimes that cost money while idle.
13 Β· Timeouts bound Terraform, not the cluster
module "runtime" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-dataflow"
data_factory_id = var.data_factory_id
location = "eastus"
timeouts = {
create = "45m"
read = "10m"
update = "45m"
delete = "45m"
}
}
β οΈ These bound how long Terraform waits to manage the runtime record. Nothing here affects cluster startup, activity duration, or the warm window β that last one istime_to_live_min.
14 Β· ποΈ End-to-end composition
provider "azurerm" {
features {}
}
module "rg" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-resource-group.git?ref=v1.0.0"
name = "rg-analytics-eastus"
location = "eastus"
}
module "adf" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory.git?ref=v1.0.0"
name = "adf-analytics-eastus"
resource_group_name = module.rg.name
location = module.rg.location
managed_virtual_network_enabled = true
identity = {
type = "SystemAssigned"
}
}
module "runtime" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-data-factory-integration-runtime-azure.git?ref=v1.0.0"
name = "ir-dataflow"
data_factory_id = module.adf.id
location = module.rg.location # a real region, not AutoResolve
compute_type = "General"
core_count = 16
time_to_live_min = 10
virtual_network_enabled = true
interactive_authoring_time_to_live_in_minutes = 30
description = "Data flow compute for the curated pipelines."
}
check "runtime_is_what_we_intended" {
assert {
condition = !module.runtime.location_is_auto_resolve
error_message = "Compute must have a fixed region for this workload."
}
assert {
condition = module.runtime.cluster_stays_warm_and_billed
error_message = "Expected a warm cluster; a TTL of 0 makes every data flow pay full startup."
}
}
output "runtime_name" {
value = module.runtime.name # linked services reference this, NOT the id
}π The factory's
managed_virtual_network_enabledand the runtime'svirtual_network_enabledare separate settings on separate resources. This module checks its own pairing offline; the factory's is the caller's.
Required: name, data_factory_id, location.
The cluster: compute_type, core_count, time_to_live_min, cleanup_enabled.
The managed vnet: virtual_network_enabled, interactive_authoring_time_to_live_in_minutes.
Metadata: description, timeouts. There is no tags variable β the resource supports none.
Full input schemas
| Name | Type | Default | Notes |
|---|---|---|---|
name |
string |
β | Force-new. Non-empty only; a leading / is refused. |
data_factory_id |
string |
β | Force-new. Anchored Resource-ID validator. |
location |
string |
β | Force-new. A region or AutoResolve. Not validated against a region list. |
compute_type |
string |
"General" |
Case-sensitive set of three. |
core_count |
number |
8 |
Closed set: 8/16/32/48/80/144/272. |
time_to_live_min |
number |
0 |
Non-negative whole number. Non-zero is billed while idle. |
cleanup_enabled |
bool |
true |
False keeps the cluster until the TTL. |
virtual_network_enabled |
bool |
false |
Force-new. Carries the interactive-authoring pairing check. |
interactive_authoring_time_to_live_in_minutes |
number |
null |
10/30/60/120. Setting it enables the feature. |
description |
string |
null |
Empty string refused. |
timeouts |
object({ create, read, update, delete }) |
null |
Terraform's, not the cluster's. |
| Output | Description | Notes |
|---|---|---|
id |
The runtime's Resource ID. | First, by convention. |
name |
The runtime's name. | What linked services reference. |
data_factory_id, data_factory_name |
The parent factory. | Name parsed from the end of the ID. |
resource_group_name, subscription_id |
Where the factory lives. | |
location |
As configured. | May not be a region. |
location_is_auto_resolve |
The magic value. | Assert on this for residency. |
an_auto_resolve_runtime_has_no_fixed_region |
Constant. | |
compute_type, core_count, time_to_live_min, cleanup_enabled |
The cluster's shape. | |
the_core_count_is_a_closed_set_not_a_range |
Constant. | |
cluster_is_torn_down_after_every_activity |
True at the default. | |
cluster_stays_warm_and_billed |
Billed while idle. | Assert on this. |
cleanup_disabled_with_no_time_to_live |
Accepted, near-meaningless. | |
is_larger_than_the_default_cluster, is_a_specialised_compute_type |
Cost signals. | |
this_runtime_costs_money_only_while_it_runs |
Constant. | |
virtual_network_enabled, interactive_authoring_time_to_live_in_minutes |
The vnet pairing. | |
interactive_authoring_enabled |
Derived boolean. | State implied by a number. |
the_interactive_authoring_pairing_is_enforced_at_PLAN_by_the_provider |
Constant. | Why this module duplicates it. |
turning_the_virtual_network_on_or_off_replaces_the_runtime |
Constant. | |
force_new_fields, fields_that_can_change_after_creation |
The change surface. | Includes a boolean. |
description |
Metadata. | |
import_address, the_import_guard_names_this_resource_correctly |
Imports. | |
this_runtime_is_referenced_by_NAME_not_by_id |
Constant. | Renaming breaks silent references. |
the_module_cannot_see_what_runs_on_this_runtime |
Constant. | Read before deleting. |
no_credential_is_configured_here, no_secret_is_accepted_or_emitted_by_this_module |
Constants. | Unlike self-hosted. |
destroying_the_factory_destroys_this_runtime_too |
Constant. | |
lifecycle_prevent_destroy_is_not_available_to_a_module_caller |
Constant. | |
this_is_a_real_azure_resource_not_a_composite |
Constant. | |
this_resource_supports_no_azure_resource_tags |
Constant. | |
the_timeouts_bound_terraform_not_the_cluster |
Constant. |
No output is sensitive, and none can be β every argument is a name, a size or a duration.
A cross-field rule moved from plan-time to validate-time. Interactive authoring requires
virtual_network_enabled = true, and the provider enforces that in a CustomizeDiff β which is evaluated
inside the provider and therefore needs credentials and a round trip. Both operands are plain top-level
arguments, so this module also checks the pairing in a validation {}. Both refusals land at
terraform plan, but this one is decided from the configuration alone β no credentials, no round trip. The
check is placed on virtual_network_enabled and reads the other one-directionally, because a validation
condition must reference its own variable and two variables validating each other is rejected as a cycle. The
provider's check remains the authority; this one arrives earlier, and somewhere a caller without a
subscription can reach β which is also the only place the improvement is demonstrable, and where the harness
proves it.
location may not be a place. AutoResolve is a distinct mode, not a default: Data Factory chooses
where each activity runs based on its source and sink. A data-residency requirement is therefore not
satisfied by placing the factory correctly. The module reports the mode rather than refusing it, because
auto-resolve is legitimate and common β and it does not validate against a region list, because the set of
regions changes and a failing validation would block terraform destroy as well as apply. The report is
case-insensitive and says so: this module has not verified whether Azure treats the magic value
case-sensitively, so it does not claim either way.
Almost everything else is cost. compute_type and core_count select the VM family and size;
time_to_live_min decides how long the cluster stays warm β and billed β after an activity finishes. The
provider's default of 0 is the cheap, slow end: every data flow pays full cluster startup, typically several
minutes. None of these arguments changes what a pipeline does. The module emits each consequence as a derived
flag because none of them is visible in a plan.
One boolean is a rebuild. virtual_network_enabled is force-new. Moving an existing runtime into or out
of the managed virtual network destroys and recreates it, losing any warm cluster β and it looks exactly like
an in-place toggle.
References are by name. Linked services and activities select an integration runtime by name, not by
Resource ID. So name is the output a composition consumes, the ID is for imports and RBAC scoping, and
renaming the runtime breaks every reference β silently, in configuration this module cannot see.
lifecycle is not valid inside a module block, so a caller cannot add prevent_destroy. A
CanNotDelete lock prevents deletion but not the replacement that editing name, location or
virtual_network_enabled would cause.
| Concern | This module's default | Opt-out |
|---|---|---|
| Secrets | None accepted, none emitted. This runtime holds no credential. | Not applicable. |
| Cost | The provider's defaults β 8 cores, General, no warm window. |
Raise core_count or time_to_live_min. |
| A warm, billed cluster | Reported via cluster_stays_warm_and_billed. |
Ignore the output. |
AutoResolve |
Reported, never refused β it is a legitimate mode. | Ignore the output. |
| A region list | Not validated. The set changes, and refusing would block destroy. | β |
core_count |
Enforced against the provider's closed set. | None β the set is closed. |
compute_type |
Enforced, case-sensitively. | None. |
| Interactive authoring without a vnet | Refused offline, without credentials β the provider needs a round trip. | None. |
cleanup_enabled = false with no TTL |
Reported, not refused. | Ignore the output. |
tags |
Not offered β the resource supports none. | Tag the factory. |
π There is no security toggle to close here: the resource holds no credential. The exposures are the delete, the silent rename, and the bill β the module documents the first two and reports the third.
terraform init -backend=false
terraform validate
terraform fmt -checkPin the module with ?ref=v1.0.0 β never a branch. This library is plan-only: a human applies from CI.
terraform plan and the module's own validation {} blocks cover, offline and without credentials:
- the interactive-authoring pairing β the rule the provider checks only inside a
CustomizeDiffthat needs credentials, refused here in both its failing forms (TTL with the flag unset, and TTL with the flag explicitly false); - every legal
core_countaccepted and the intermediate values 12, 64 and 0 refused; - every legal
compute_typeaccepted and a lowercase one refused; - all four interactive TTLs accepted when correctly paired, and 45 refused;
AutoResolveaccepted in both casings, alongside a real region;- every derived flag β the warm/torn-down pair,
cleanup_disabled_with_no_time_to_live,interactive_authoring_enabled,location_is_auto_resolveβ each with one fixture per branch throughterraform console; - structural assertions that every output this README promises is actually declared.
terraform validate reaches none of that through a module call. Validate evaluates no module
variable values, so this module's validation {} blocks are never reached and it reports success. The
refusals above land at plan β still offline and without credentials.
Only a real apply can tell you whether the factory has a managed virtual network, what a cluster
actually costs, or what currently references the runtime by name.
runtime_name = "ir-dataflow"
id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-analytics-eastus/providers/Microsoft.DataFactory/factories/adf-analytics-eastus/integrationruntimes/ir-dataflow"
location = "eastus"
location_is_auto_resolve = false
compute_type = "General"
core_count = 16
time_to_live_min = 10
cluster_stays_warm_and_billed = true
cluster_is_torn_down_after_every_activity = false
is_larger_than_the_default_cluster = true
interactive_authoring_enabled = true
force_new_fields = ["name", "data_factory_id", "location", "virtual_network_enabled"]
| Symptom | Cause | Fix |
|---|---|---|
core_count must be one of 8, 16, 32, 48, 80, 144 or 272. on 64 |
It is a closed set, not a range. | Use 48 or 80. |
compute_type must be General, ComputeOptimized or MemoryOptimized. on "general" |
Case-sensitive. | Capitalise it. |
when interactive_authoring_time_to_live_in_minutesis set,virtual_network_enabledmust be set totrue. |
The pairing. This module catches it at plan; the provider catches it at plan. | Set virtual_network_enabled = true. |
interactive_authoring_time_to_live_in_minutes must be 10, 30, 60 or 120. |
A closed set. | Pick one of the four. |
| Data flows are slow to start | time_to_live_min is 0 β the provider's default. |
Raise it, and accept the idle billing. |
| The runtime costs money with nothing running | A non-zero TTL keeps the cluster warm and billed. | Check cluster_stays_warm_and_billed. |
| Disabling cleanup appears to do nothing | time_to_live_min is 0, so there is no TTL to reach. |
Check cleanup_disabled_with_no_time_to_live. |
| Compute ran outside the expected region | location is AutoResolve β a mode, not a region. |
Check location_is_auto_resolve; set a real region. |
| Toggling the managed vnet destroyed the runtime | virtual_network_enabled is force-new. |
Expected. The warm cluster is lost. |
| A pipeline stopped finding its runtime after a rename | Runtimes are referenced by name. | Update the referencing linked services and activities. |
A slow cluster start is not covered by timeouts |
Those bound Terraform's management of the record. | Nothing here bounds cluster startup. |
azurerm_data_factory_integration_runtime_azureazurerm_data_factory_integration_runtime_self_hostedβ carries authorization keys- Integration runtime concepts
- Data flow performance and cost
SCOPE.mdβ this module's cross-module contract- Sibling modules:
terraform-azurerm-data-factory,terraform-azurerm-data-factory-dataset-delimited-text
π "Infrastructure as Code should be standardized, consistent, and secure."