Skip to content

Terraform plan fails: network_rules_default_action is null

One-sentence summary: Setting blob_storage_settings.contributor_group_id to a data.azuread_group lookup instead of a literal object ID fails the Organization Policy Check and cascades into null-value errors deep in the storage account module.


🚨 Symptom

Enabling the blob storage feature flag on the saif-appservices module and running terraform plan (locally or in the Deploy pipeline) fails with:

╷
│ Error: Invalid function argument
│
│   on .terraform/modules/saif-appservices.storage.storageaccount/modules/storageaccount/variables.tf line 199, in variable "network_rules_default_action":
│  199:   condition = contains(["Allow", "Deny"], var.network_rules_default_action)
│     ├────────────────
│     │ while calling contains(list, value)
│     │ var.network_rules_default_action is null
│
│ Invalid value for "value" parameter: argument must not be null.
╵
╷
│ Error: Iteration over null value
│
│   on .terraform/modules/saif-appservices.storage.storageaccount/modules/storageaccount/variables.tf line 211, in variable "network_rules_bypass":
│  210:   condition = alltrue([
│  211:     for service in var.network_rules_bypass : contains(["AzureServices", "Logging", "Metrics", "None"], service)
│  212:   ])
│     ├────────────────
│     │ var.network_rules_bypass is null
│
│ A null value cannot be used as the collection in a 'for' expression.
╵
Operation failed: failed running terraform plan (exit 1)

This shows up in the Deploy pipeline's terraform plan/terraform apply step, or locally when running Terraform against infra/api/app.generated.tf.


📌 Applies to

Aspect Value
Component Terraform — saif-apiservice module, blob storage feature flag
Forge versions saif-apiservice module >= 3.0.0, < 4.0.0
Related versions Check the version compatibility matrix

🧠 Cause

blob_storage_settings.contributor_group_id was set by looking up an Entra ID group at plan time, e.g.:

contributor_group_id = data.azuread_group.customer_team.object_id

Data-source lookups aren't allowed in this position — the Organization Policy Check rejects plans that resolve group membership this way. When that lookup can't be evaluated, the module's other feature-flag-conditional inputs (including network_rules_default_action and network_rules_bypass) can't be computed either, so they come through as null and Terraform fails deep inside the storageaccount submodule with the errors above.


✅ Fix

  1. Look up your team's Entra ID group object ID once, instead of resolving it in Terraform:

    az ad group show --group "<display name>" --query id -o tsv
    
  2. Replace the data.azuread_group reference with the literal GUID in blob_storage_settings:

    feature_flags = {
      enable_blob_storage = true
      blob_storage_settings = {
        containers            = ["documents", "uploads", "archives"]
        contributor_group_id  = "12345678-1234-1234-1234-123456789abc" # hardcoded, not a data source
      }
    }
    
  3. Remove the now-unused data "azuread_group" block from app.generated.tf.


🔬 Verify

terraform plan completes without the Invalid function argument / Iteration over null value errors, and shows the expected storage account, container, and RBAC role assignment resources to add.