Creates an Azure Automation integer variable β a typed asset that runbooks read and write as shared state β for
hashicorp/azurerm ~> 4.0.
- Creates an
azurerm_automation_variable_int(the keystonethis) β an integer variable asset inside an existing Automation account. - Stores a whole-number
valuethat runbooks read and write, so a job can persist a counter, a threshold, or a last-processed marker between runs. - Supports encryption at rest through a single boolean: set
encrypted = trueand the value is wrappedsensitiveand never returned by the API on read. - Accepts an optional
description, emits the variableidandname, and handles no secret output.
π‘ Why it matters: Automation variables are the durable memory of unattended runbooks. Defining an integer variable as its own typed module makes the value a plan-time
numberβ a string typo becomes a type error instead of a runbook that silently reads back the wrong shape β and keeps the encrypt-at-rest decision to one explicit flag.
If this module saves you time:
- β Star the repository
- πΌ Connect on LinkedIn
- β Buy me a coffee
flowchart LR
aa["terraform-azurerm-automation-account"]
me["terraform-azurerm-automation-variable-int"]
v["azurerm_automation_variable_int"]
s1["terraform-azurerm-automation-variable-bool"]
s2["terraform-azurerm-automation-variable-datetime"]
s3["terraform-azurerm-automation-variable-object"]
s4["terraform-azurerm-automation-variable-string"]
rb["runbooks read/write the variable"]
aa -->|"automation_account_name"| me
aa -->|"also parents"| s1
aa -->|"also parents"| s2
aa -->|"also parents"| s3
aa -->|"also parents"| s4
me -->|"creates"| v
v -.->|"shared state"| rb
classDef me fill:#0078D4,stroke:#004578,color:#ffffff;
classDef target fill:#004578,stroke:#002d4d,color:#ffffff;
classDef ext fill:#f2f2f2,stroke:#c8c8c8,color:#111111;
class me me;
class v target;
class aa,s1,s2,s3,s4,rb ext;
flowchart TB
in["name + automation_account_name + value(int) + encrypted"]
this["azurerm_automation_variable_int.this"]
out["Outputs: id, name"]
in --> this
this --> out
classDef target fill:#004578,stroke:#002d4d,color:#ffffff;
classDef ext fill:#f2f2f2,stroke:#c8c8c8,color:#111111;
class this target;
class in,out ext;
Resource inventory
| Resource | Role | Cardinality |
|---|---|---|
azurerm_automation_variable_int |
keystone this |
single |
| Requirement | Value |
|---|---|
| Terraform | >= 1.12.0 |
| azurerm provider | ~> 4.0 |
| Provider block | None β the caller configures provider "azurerm" { features {} }, auth, and subscription |
Schema notes that bite (verified against the live schema):
- Three fields are force-new.
name,resource_group_name, andautomation_account_nameare immutable β changing any of them replaces the variable.value,encrypted, anddescriptionall update in place. valueis anumber, not a string. The provider stores it as an integer; passing a fractional or string-shaped value is a type error at plan time. Leave it null to create the variable with no value set.encryptedchanges read behavior. It defaults tofalse. When set totrue, the module wraps the valuesensitiveso it never surfaces in plan output, and Azure does not return the value on read β Terraform tracks it from configuration rather than from the API.- No tags. The resource type does not support
tags, so the module omits the variable β the universal tail istimeoutsonly.
- Automation Contributor (or equivalent) on the parent Automation account.
- An existing Automation account to hold the variable.
- The caller configures the
provider "azurerm" { features {} }block, authentication, and subscription β this module declares none of them.
terraform-azurerm-automation-variable-int/
βββ providers.tf # required_version + azurerm ~> 4.0 pin; no provider block
βββ variables.tf # keystone inputs, value/encrypted/description, timeouts (no tags)
βββ main.tf # azurerm_automation_variable_int.this
βββ outputs.tf # id first, then name
βββ README.md # this document
βββ SCOPE.md # cross-module contract
βββ LICENSE # MIT
βββ .gitignore
The smallest real call creates an integer variable in an existing Automation account:
module "retry_limit" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "MaxRetries"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 5
}βΉοΈ The caller configures
provider "azurerm" { features {} }, authentication, and the subscription β this module declares none of them. The Automation account must already exist.
Consumes
| Input | Type | Source module |
|---|---|---|
resource_group_name |
string |
terraform-azurerm-resource-group (name) |
automation_account_name |
string |
terraform-azurerm-automation-account (name) |
Emits
| Output | Description |
|---|---|
id |
Variable Resource ID (first) |
name |
Variable name β the key a runbook uses with Get-AutomationVariable |
1 Β· A simple integer value
module "batch_size" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "BatchSize"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 42
}π‘
valueis anumber, so42is stored as an integer β no quoting, no casting inside the runbook.
2 Β· Zero as a valid value
module "failure_count" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "ConsecutiveFailures"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 0
}βΉοΈ
0is a real value, distinct from null. Use it to seed a counter that a runbook increments from a known baseline.
3 Β· No value (null)
module "last_processed_id" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "LastProcessedId"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
# value omitted β the variable exists but holds no value until a runbook sets it
}π‘ Omit
value(it defaults to null) to declare the variable and let a runbook populate it at runtime withSet-AutomationVariable.
4 Β· Encrypted at rest
module "throttle_seed" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "ThrottleSeed"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 9000
encrypted = true
}π With
encrypted = truethe value is wrappedsensitiveand Azure does not return it on read. Terraform tracks the value from configuration, so keep the module the source of truth.
5 Β· With a description
module "page_size" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "PageSize"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 100
description = "Number of records fetched per API page by the sync runbook"
}βΉοΈ
descriptionupdates in place, so you can document a variable's purpose without replacing it.
6 Β· A negative value
module "temperature_floor" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "TemperatureFloor"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = -20
}π‘ Integer variables accept negative values β useful for thresholds, offsets, or bounds that dip below zero.
7 Β· A retry counter referenced by a runbook
module "max_retries" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "MaxRetries"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 3
description = "Upper bound on retry attempts for the reconciliation runbook"
}A PowerShell runbook reads and updates it as shared state:
$max = Get-AutomationVariable -Name 'MaxRetries'
for ($i = 0; $i -lt $max; $i++) { <# attempt #> }
Set-AutomationVariable -Name 'ConsecutiveFailures' -Value ($current + 1)π‘ The module's
nameoutput is exactly the key the runbook passes toGet-AutomationVariable. Reference it so a rename propagates instead of drifting.
8 Β· Many variables at once (for_each)
locals {
counters = {
MaxRetries = 3
BatchSize = 500
ConsecutiveFailures = 0
PageSize = 100
}
}
module "counter" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
for_each = local.counters
name = each.key
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = each.value
}π‘ A keyed
for_eachat the module level keeps each variable stable when you add or remove one β no re-indexing.
9 Β· Encrypted, from a map (for_each)
locals {
secrets = {
SigningRotationDays = { value = 30, encrypted = true }
TokenTtlMinutes = { value = 60, encrypted = true }
}
}
module "secure_counter" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
for_each = local.secrets
name = each.key
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = each.value.value
encrypted = each.value.encrypted
}π Each entry is wrapped
sensitivebecauseencrypted = true, so no value appears in plan output.
10 Β· A version stamp
module "config_version" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "ConfigVersion"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 7
description = "Bumped whenever the runbook config schema changes"
}π‘ An integer version stamp lets a runbook detect a config change with a single equality check.
11 Β· Custom timeouts
module "slow_region_counter" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "RegionCounter"
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 1
timeouts = {
create = "30m"
delete = "30m"
}
}βΉοΈ
timeoutsis the module's only universal-tail input β this resource type carries notags.
12 Β· Renaming means replacement
# Changing name (or resource_group_name / automation_account_name) destroys and
# recreates the variable β these three fields are force-new.
module "counter" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "RetryBudgetV2" # was "RetryBudget" β this is a replace, not an update
resource_group_name = "rg-automation-eastus"
automation_account_name = "aa-contoso"
value = 10
}
β οΈ To retune a variable in place, changevalue,encrypted, ordescriptionβ not the identity fields. Renaming loses any value a runbook wrote at runtime.
13 Β· ποΈ End-to-end composition
Stand up a resource group, an Automation account, and a set of integer variables the account's runbooks share as state. The variables' name outputs are the keys the runbooks reference:
module "rg" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-resource-group.git?ref=v1.0.0"
name = "rg-automation-eastus"
location = "eastus"
}
module "automation" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-account.git?ref=v1.0.0"
name = "aa-contoso"
resource_group_name = module.rg.name
location = module.rg.location
}
module "max_retries" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "MaxRetries"
resource_group_name = module.rg.name
automation_account_name = module.automation.name # from terraform-azurerm-automation-account
value = 3
description = "Retry budget for the reconciliation runbook"
}
module "consecutive_failures" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-automation-variable-int.git?ref=v1.0.0"
name = "ConsecutiveFailures"
resource_group_name = module.rg.name
automation_account_name = module.automation.name
value = 0 # seeded; the runbook increments it at runtime
}π‘ The account module supplies
automation_account_name; each variable module contributes one integer asset. Reference siblingnameoutputs so the runbook keys stay in sync with the deployed variables.
Required: name, resource_group_name, automation_account_name.
Optional: value, encrypted, description.
Universal tail: timeouts (no tags β the resource does not support them).
Full schemas
name = string # required, force-new
resource_group_name = string # required, force-new
automation_account_name = string # required, force-new
value = optional(number) # integer; null = variable created with no value
encrypted = optional(bool) # default false; true wraps the value sensitive, not returned on read
description = optional(string)
timeouts = optional(object({
create = optional(string) # Go duration, e.g. "30m"
read = optional(string)
update = optional(string)
delete = optional(string)
}))| Output | Description | Kind |
|---|---|---|
id |
Resource ID of the Automation Int variable | Passthrough |
name |
Name of the variable, as created | Passthrough |
automation_account_name |
Name of the parent Automation account this variable belongs to | Passthrough |
resource_group_name |
Name of the resource group holding the parent Automation account | Passthrough |
variable_type |
Constant "Int" | Derived |
is_encrypted |
Whether the value is encrypted at rest | Passthrough |
has_value |
Whether a value was supplied | Derived |
value_is_readable_by_terraform |
False when the variable is encrypted | Derived |
has_description |
Whether a description was set | Derived |
renaming_this_variable_destroys_its_value |
Constant true | Constant |
is_scoped_to_one_automation_account |
Constant true | Constant |
value_is_not_emitted_by_design |
Constant true | Constant |
No secret is emitted. When
encryptedis true the value is wrappedsensitiveand Azure does not return it on read.
- Identity fields are force-new.
name,resource_group_name, andautomation_account_nameare immutable β changing any of them destroys and recreates the variable, losing any value a runbook wrote at runtime.value,encrypted, anddescriptionall update in place. - The value is typed as a
number. Modeling it as an integer rather than a loose string means a malformed value fails at plan time, and runbooks read back a genuine number. Leavevaluenull to declare the variable without setting one. encryptedgates both storage and visibility. It defaults tofalse. When true,main.tfwraps the value withsensitive()so it never surfaces in plan output, and Azure stops returning the value on read β Terraform then tracks it from configuration, so the module stays the source of truth for encrypted values.- No tags, and no secret output. The resource type does not support
tags; the universal tail istimeoutsonly. The module emits 12 outputs -- identity, parentage and derived facts -- but never the value itself;has_valuereports presence instead. features {}dependence. The provider will not initialize without a caller-sidefeatures {}block β expected, and owned by the root module.
| Concern | Secure default | Opt-out (caller must type it) |
|---|---|---|
| Encryption at rest | encrypted = false (a plain integer counter is not sensitive) |
set encrypted = true to wrap the value and hide it on read |
| Value visibility | encrypted values are wrapped sensitive and never printed in plan |
β (enforced whenever encrypted = true) |
| Secret handling | emits no value output; only id and name |
β (a variable's value is never emitted) |
| Type safety | value is a number, validated at plan time |
β (a non-integer value cannot plan) |
terraform init -backend=false
terraform validate
terraform fmt -checkPin the module by immutable tag (?ref=v1.0.0), never a branch. This is plan-only; a human applies from CI.
terraform validate+fmt -checkprove the type contract offline β thatvalueis an integer,encryptedis a boolean, and the three identity fields are present β before any Azure call.- Only
terraform planagainst a subscription exercises the existence of the Automation account, the force-new replacement when an identity field changes, and the read-back behavior whenencrypted = true.
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
id = "/subscriptions/.../resourceGroups/rg-automation-eastus/providers/Microsoft.Automation/automationAccounts/aa-contoso/variables/MaxRetries"
name = "MaxRetries"
| Symptom | Cause | Fix |
|---|---|---|
Inappropriate value for attribute "value": a number is required |
A string or fractional value passed to value |
Pass a whole number (for example 42), or omit value to leave it unset |
| Variable replaced on a rename | Changed name, resource_group_name, or automation_account_name (force-new) |
Expected β these identity fields replace the resource; change value/encrypted/description to update in place |
| Value not visible after apply | encrypted = true β Azure does not return encrypted values on read |
Expected; Terraform tracks the value from configuration, so keep the module as the source of truth |
| Runbook reads null instead of a number | Variable created with value omitted, or a runbook cleared it |
Set value in the module, or have the runbook write with Set-AutomationVariable |
| Apply fails: parent not found | The Automation account named in automation_account_name does not exist |
Create the Automation account first (see the end-to-end composition example) |
azurerm_automation_variable_int- Sibling modules:
terraform-azurerm-automation-variable-string,terraform-azurerm-automation-variable-bool,terraform-azurerm-automation-variable-datetime,terraform-azurerm-automation-account - This module's
SCOPE.md
π "Infrastructure as Code should be standardized, consistent, and secure."