terraform-azurerm
Renders Terraform JSON for Azure virtual networks with derived subnets and network security groups, and for storage accounts with private containers.
- Latest
- 0.1.2 ·
- License
- Apache-2.0
- Owners
- Moep90
- Source
- github.com/kadet-hub/generators · 0 repo stars, shared by 35 generators
- Thumbs up
- 👍 0 on GitHub Discussions
- Popularity
- 18 · 540 pulls
Request a feature Report a problem
Badge
Show the latest listed version in your README. shields.io draws the badge from this page's badge.json, which every catalog build updates; once no version is listed, it reads "not listed".
[](https://kadet-hub.org/generators/terraform-azurerm/)
Terraform azurerm Generator
Published on kadet-hub: pin a released version by digest from its catalog page.
Kapitan kadet generator that renders Terraform JSON (*.tf.json) for the Azure provider hashicorp/azurerm, pinned to 5.10.0:
- network: a resource group, a virtual network, one subnet per entry with its prefix derived from the address space, and per subnet a network security group with its association.
- storage: a storage account locked down to Microsoft Entra ID and private access, plus private blob containers.
Names follow the Cloud Adoption Framework naming convention with the recommended abbreviations. Subnet prefixes are computed at compile time, so the compiled output shows every CIDR.
Usage
Kapitan Configuration
parameters:
kapitan:
dependencies:
- type: oci
source: ghcr.io/kadet-hub/terraform-azurerm@sha256:<digest>
output_path: lib/terraform-azurerm
compile:
- output_path: terraform/
input_type: kadet
output_type: json
input_paths:
- lib/terraform-azurermoutput_type: json is required: without it Kapitan writes YAML, which Terraform ignores. Run terraform init and terraform plan in the compiled terraform/ directory.
Provider and authentication
providers.tf.json holds the only terraform block (required_version >= 1.5.0, hashicorp/azurerm 5.10.0) and the provider "azurerm" block with an empty features block. It sets storage_use_azuread = true when any storage account keeps shared_access_key_enabled: false, because the provider otherwise uses Shared Key for storage data plane requests.
The output contains no subscription_id and no credentials. Since provider 4.0 the subscription is required for plan and apply; set ARM_SUBSCRIPTION_ID (or select a default subscription in the az CLI) and authenticate the way the provider documents. terraform validate does not need it.
Inventory Contract
All keys live under parameters.generators.terraform-azurerm. network and storage are maps from a key to one bundle. The key, mapped to [a-z0-9_], names the output file and the Terraform resources (azurerm_subnet.<network>_<subnet>, azurerm_storage_container.<storage>_<container>). Compilation fails when two entries map to the same Terraform name or the same storage account name.
network.<key>:
| Key | Default | Meaning |
|---|---|---|
workload |
required | Workload component of the names |
environment |
required | Environment component, for example prod |
location |
required | Azure region, for example westeurope |
location_short |
location |
Region component of the names, for example weu |
instance |
"001" |
Instance component; quote it, YAML reads 001 as the number 1 |
address_space |
required | One IPv4 CIDR for the virtual network |
tags |
{} |
Tags on the resource group, virtual network and network security groups |
subnets |
required | Ordered map of subnet name to the settings below |
network.<key>.subnets.<name>:
| Key | Default | Meaning |
|---|---|---|
newbits |
required unless prefix |
Bits added to the address space prefix length; newbits: 8 on a /16 gives a /24 |
prefix |
null |
Explicit CIDR; overrides newbits |
nsg |
true |
Create a network security group and associate it with the subnet |
security_rules |
[] |
security_rule objects with the provider’s argument names; name, priority, direction, access and protocol are required, omitted arguments are sent as null. Needs nsg: true |
default_outbound_access_enabled |
false |
false makes the subnet private |
private_endpoint_network_policies |
"Enabled" |
Disabled, Enabled, NetworkSecurityGroupEnabled or RouteTableEnabled |
Prefix derivation: explicit prefixes are reserved first. Then, in the order the subnets appear in the inventory, each newbits subnet gets the first aligned block of its size that overlaps no subnet allocated so far. Appending a newbits subnet keeps the existing prefixes; inserting one earlier, reordering, or adding an explicit prefix that overlaps a derived one moves derived prefixes, which replaces those subnets. Compilation fails for subnets smaller than /29, prefixes outside the address space, overlapping prefixes, and when no free block of the requested size is left. Resources are emitted sorted by name.
The network security group always carries security_rule, an empty list when no rules are given, so rules added outside Terraform are removed on the next apply.
storage.<key>:
| Key | Default | Meaning |
|---|---|---|
workload, environment, location |
required | As for network |
location_short |
location |
As for network |
instance |
"001" |
As for network |
resource_group |
Key under network; the account goes into that network’s resource group |
|
resource_group_name |
Name of an existing resource group; set exactly one of the two | |
account_replication_type |
"ZRS" |
LRS, GRS, RAGRS, ZRS, GZRS or RAGZRS |
public_network_access |
"Disabled" |
Enabled, Disabled or SecuredByPerimeter |
shared_access_key_enabled |
false |
false allows only Microsoft Entra ID authorization |
infrastructure_encryption_enabled |
false |
Changing it replaces the account |
versioning_enabled |
true |
Blob versioning |
delete_retention_days |
7 |
Blob soft delete, 1 to 365 days |
container_delete_retention_days |
7 |
Container soft delete, 1 to 365 days |
ip_rules |
[] |
Public IPv4 addresses or CIDRs the firewall admits; a single address without prefix, CIDRs up to /30; ranges that include RFC 1918 addresses are rejected |
allowed_subnets |
[] |
Subnet names of the resource_group network the firewall admits; those subnets get the Microsoft.Storage service endpoint, which covers accounts in the virtual network’s region. Not allowed with resource_group_name |
containers |
[] |
Names of private blob containers |
tags |
{} |
Tags on the storage account |
Fixed storage account arguments: account_tier = "Standard", account_kind = "StorageV2", https_traffic_only_enabled = true, min_tls_version = "TLS1_2", allow_nested_items_to_be_public = false, default_to_oauth_authentication = true, cross_tenant_replication_enabled = false, local_user_enabled = false, network_rules { default_action = "Deny", bypass = ["AzureServices"], ip_rules, virtual_network_subnet_ids }. Containers use container_access_type = "private".
network_rules always carries ip_rules and virtual_network_subnet_ids, as empty lists when unset, because the provider documentation requires one of them whenever the block is present. The firewall governs the public endpoint, so both lists only admit traffic with public_network_access: Enabled.
Names
| Resource | Name |
|---|---|
| Resource group | rg-<workload>-<environment>-<location_short>-<instance> |
| Virtual network | vnet-<workload>-<environment>-<location_short>-<instance> |
| Subnet | snet-<subnet>-<workload>-<environment>-<location_short>-<instance> |
| Network security group | nsg-<subnet>-<workload>-<environment>-<location_short>-<instance> |
| Storage account | st<workload><environment><location_short><instance>, lowercased, hyphens and other characters removed |
Storage account names are globally unique and limited to 3 to 24 characters; a longer derived name fails the compilation with a message. Set location_short to keep it short.
Output files
| File | Content |
|---|---|
providers.tf.json |
terraform block with required_providers, provider "azurerm" |
network-<key>.tf.json |
Resource group, virtual network, subnets, network security groups and associations; outputs <key>_resource_group_name, <key>_virtual_network_id, <key>_subnet_ids (map of subnet name to ID) |
storage-<key>.tf.json |
Storage account and containers; outputs <key>_storage_account_id, <key>_storage_account_name |
Example
parameters:
generators:
terraform-azurerm:
network:
shop:
workload: shop
environment: prod
location: westeurope
location_short: weu
address_space: 10.40.0.0/16
tags:
owner: shop-team
subnets:
web:
newbits: 8
security_rules:
- name: allow-https-inbound
priority: 100
direction: Inbound
access: Allow
protocol: Tcp
source_port_range: "*"
destination_port_range: "443"
source_address_prefix: Internet
destination_address_prefix: VirtualNetwork
app:
newbits: 8
endpoints:
prefix: 10.40.255.0/27
nsg: false
storage:
shop:
workload: shop
environment: prod
location: westeurope
location_short: weu
resource_group: shop
containers:
- invoices
- uploadsThis compiles to rg-shop-prod-weu-001, vnet-shop-prod-weu-001 with snet-web-shop-prod-weu-001 (10.40.0.0/24), snet-app-shop-prod-weu-001 (10.40.1.0/24) and snet-endpoints-shop-prod-weu-001 (10.40.255.0/27), network security groups for web and app, and the storage account stshopprodweu001 with two containers.
Defaults and guidance
The subnet defaults (private subnets, private_endpoint_network_policies = "Enabled"), the required security rule arguments and the storage account defaults (ZRS, no public network access, no Shared Key, no local users, HTTPS only, TLS 1.2, no anonymous nested access, no cross-tenant replication, firewall default Deny with the AzureServices bypass) mirror the Azure Verified Modules avm-res-network-virtualnetwork, avm-res-network-networksecuritygroup and avm-res-storage-storageaccount. Blob and container soft delete and Microsoft Entra ID authorization in the portal (default_to_oauth_authentication) follow Microsoft’s security recommendations for Blob storage. Blob versioning is this generator’s default.
- Private subnets: Microsoft recommends disabling default outbound access. Virtual machines in a private subnet need an explicit egress method to reach the internet, typically a NAT gateway; this version does not render one.
- No public network access: with
public_network_access: Disabledthe account is reachable only through a private endpoint or by trusted Azure services. This version renders no private endpoints. - Containers through Azure Resource Manager: containers reference the account by
storage_account_id, which the provider (5.10.0 source) creates, updates and deletes through the Resource Manager API instead of the storage data plane, so this should work while public network access is disabled. Not verified by an apply.
Terraform resources
Resource arguments follow the provider documentation (MPL-2.0); the examples here are written for this generator.
azurerm_resource_groupazurerm_virtual_networkazurerm_subnetazurerm_network_security_groupazurerm_subnet_network_security_group_associationazurerm_storage_accountazurerm_storage_container
Subnets are standalone azurerm_subnet resources; the virtual network never carries inline subnet blocks, which would conflict with them.
Versions
Add a version's inventory entry, then compile with the consumer workflow, which verifies the artifact and runs Kapitan in the sandbox.
Free of charge, as is and on a best-effort basis: use at your own risk, and review the compiled output before you apply it. Terms
This catalog was built from index serial 47. Set index_serial: 47 in .kapitan-sandbox.yaml and the consumer workflow refuses any older index, so a rolled-back index cannot bring back a yanked version.
Checks find known patterns; they do not prove a generator safe. What a listing covers
| Version | Built for (schema-checked) |
|---|---|
| 0.1.2 | hashicorp/azurerm 5.10.0 |
| 0.1.1 | hashicorp/azurerm 5.9.0 |
| 0.1.0 | not recorded |
0.1.2#
Inventory
parameters:
kapitan:
dependencies:
- type: oci
source: ghcr.io/kadet-hub/terraform-azurerm:0.1.2@sha256:56872ea323acec6e7e2ac0e2946774666bcd26f6352563dc0e1b0e10134682b7
output_path: lib/terraform-azurerm
Verify
gh attestation verify \
oci://ghcr.io/kadet-hub/terraform-azurerm@sha256:56872ea323acec6e7e2ac0e2946774666bcd26f6352563dc0e1b0e10134682b7 \
--owner kadet-hub \
--cert-identity https://github.com/kadet-hub/registry/.github/workflows/release.yml@refs/heads/main
Transparency log: Rekor entry 3275158100, in Sigstore's public, append-only log, so the attestation stays checkable independent of this site.
- Kapitan declared
- >=0.36.3,<0.37
- Kapitan checked
- 0.36.3
- Backends checked
- reclass-rs, omegaconf
- With --cache
- passed
- krab
- compatible
- Built for (schema-checked)
- hashicorp/azurerm 5.10.0
- Source
- terraform-azurerm-v0.1.2 ·
885d980712c735656e9e632582bd66f13e0afc75· terraform-azurerm - Binaries
- none
- Output capabilities
- none
- Digest
sha256:56872ea323acec6e7e2ac0e2946774666bcd26f6352563dc0e1b0e10134682b7
Checks
Checked by the release run on , gate at 27448d11deef.
- Secrets gitleaks 8.30.1
No secret matched the marketplace's gitleaks rules. - Malware ClamAV 1.5.4
No file matched a ClamAV signature. - Malicious package heuristics GuardDog 3.2.0
No GuardDog threat rule matched. - Dangerous code Semgrep 1.180.0
No marketplace Semgrep rule matched, such as eval, subprocess or network calls. - Python errors Ruff 0.17.0
No syntax error or undefined name (Ruff, error rules only). - File tree tree_check.py
No symlink, executable or banned file; imports within the allowlist. - Sandboxed compile gVisor 20261005, Kapitan 0.36.3
The fixture compiled without network, with decoy credentials; no undeclared program ran, no decoy was read. - Output capabilities Conftest 0.71.1
The compiled output uses only the capabilities the manifest declares. - CI detection Kapitan 0.36.3
The output is the same with CI variables set.
Output diff
Fixture output against 0.1.1: 2 files, 2 hunks.
--- a/compiled/complete/terraform/providers.tf.json
+++ b/compiled/complete/terraform/providers.tf.json
@@ -9,7 +9,7 @@
"required_providers": {
"azurerm": {
"source": "hashicorp/azurerm",
- "version": "5.9.0"
+ "version": "5.10.0"
}
},
"required_version": ">= 1.5.0"
--- a/compiled/minimal/terraform/providers.tf.json
+++ b/compiled/minimal/terraform/providers.tf.json
@@ -9,7 +9,7 @@
"required_providers": {
"azurerm": {
"source": "hashicorp/azurerm",
- "version": "5.9.0"
+ "version": "5.10.0"
}
},
"required_version": ">= 1.5.0"
0.1.1#
Inventory
parameters:
kapitan:
dependencies:
- type: oci
source: ghcr.io/kadet-hub/terraform-azurerm:0.1.1@sha256:220bb47a5c1e6c8112260c7ae218cee8204632586d929787cbc23e73b08a2d71
output_path: lib/terraform-azurerm
Verify
gh attestation verify \
oci://ghcr.io/kadet-hub/terraform-azurerm@sha256:220bb47a5c1e6c8112260c7ae218cee8204632586d929787cbc23e73b08a2d71 \
--owner kadet-hub \
--cert-identity https://github.com/kadet-hub/registry/.github/workflows/release.yml@refs/heads/main
Transparency log: Rekor entry 3207891307, in Sigstore's public, append-only log, so the attestation stays checkable independent of this site.
- Kapitan declared
- >=0.36.3,<0.37
- Kapitan checked
- 0.36.3
- Backends checked
- not recorded
- With --cache
- not recorded
- krab
- compatible
- Built for (schema-checked)
- hashicorp/azurerm 5.9.0
- Source
- terraform-azurerm-v0.1.1 ·
90a1da0e1a83651901e7ad2e7d53ad45d0076416· terraform-azurerm - Binaries
- none
- Output capabilities
- none
- Digest
sha256:220bb47a5c1e6c8112260c7ae218cee8204632586d929787cbc23e73b08a2d71
Checks
Checked by the release run on , gate at 13da9613a3b1.
- Secrets gitleaks 8.30.1
No secret matched the marketplace's gitleaks rules. - Malware ClamAV 1.5.4
No file matched a ClamAV signature. - Malicious package heuristics GuardDog 3.2.0
No GuardDog threat rule matched. - Dangerous code Semgrep 1.180.0
No marketplace Semgrep rule matched, such as eval, subprocess or network calls. - Python errors Ruff 0.17.0
No syntax error or undefined name (Ruff, error rules only). - File tree tree_check.py
No symlink, executable or banned file; imports within the allowlist. - Sandboxed compile gVisor 20261005, Kapitan 0.36.3
The fixture compiled without network, with decoy credentials; no undeclared program ran, no decoy was read. - Output capabilities Conftest 0.71.1
The compiled output uses only the capabilities the manifest declares. - CI detection Kapitan 0.36.3
The output is the same with CI variables set.
Output diff
No output diff recorded: this version was published before the release run recorded one.
0.1.0#
Inventory
parameters:
kapitan:
dependencies:
- type: oci
source: ghcr.io/kadet-hub/terraform-azurerm:0.1.0@sha256:3b9a0d0feaaa1a2409ad39bf7523bbd2b92b7a1558d812672c0aeae29e14e9ae
output_path: lib/terraform-azurerm
Verify
gh attestation verify \
oci://ghcr.io/kadet-hub/terraform-azurerm@sha256:3b9a0d0feaaa1a2409ad39bf7523bbd2b92b7a1558d812672c0aeae29e14e9ae \
--owner kadet-hub \
--cert-identity https://github.com/kadet-hub/registry/.github/workflows/release.yml@refs/heads/main
Transparency log: Rekor entry 3207181997, in Sigstore's public, append-only log, so the attestation stays checkable independent of this site.
- Kapitan declared
- >=0.36.3,<0.37
- Kapitan checked
- 0.36.3
- Backends checked
- not recorded
- With --cache
- not recorded
- krab
- compatible
- Built for (schema-checked)
- not recorded
- Source
- terraform-azurerm-v0.1.0 ·
3ec7a80b223e8561ba752c469c23efd664e767fc· terraform-azurerm - Binaries
- none
- Output capabilities
- none
- Digest
sha256:3b9a0d0feaaa1a2409ad39bf7523bbd2b92b7a1558d812672c0aeae29e14e9ae
Checks
Checked by the release run on , gate at bebc31fd7b85.
- Secrets gitleaks 8.30.1
No secret matched the marketplace's gitleaks rules. - Malware ClamAV 1.5.4
No file matched a ClamAV signature. - Malicious package heuristics GuardDog 3.2.0
No GuardDog threat rule matched. - Dangerous code Semgrep 1.180.0
No marketplace Semgrep rule matched, such as eval, subprocess or network calls. - Python errors Ruff 0.17.0
No syntax error or undefined name (Ruff, error rules only). - File tree tree_check.py
No symlink, executable or banned file; imports within the allowlist. - Sandboxed compile gVisor 20261005, Kapitan 0.36.3
The fixture compiled without network, with decoy credentials; no undeclared program ran, no decoy was read. - Output capabilities Conftest 0.71.1
The compiled output uses only the capabilities the manifest declares. - CI detection Kapitan 0.36.3
The output is the same with CI variables set.
Output diff
No output diff recorded: this version was published before the release run recorded one.