Skip to content

saif-resources / storage

Blob storage module. Wraps iac-azure-modules storageaccount with private endpoint and App Registration SP RBAC.

Usage

module "storage" {
  source  = "app.terraform.io/SAIFCorp/resources/saif//modules/storage"
  version = "~> 3.5.0"

  context  = module.environment.context
  identity = module.identity.identity

  resource_group_name     = module.resource_group.resource_group_name
  resource_group_location = module.resource_group.location

  containers             = ["documents", "uploads"]
  connection_string_name = "storage"
}

# Compose app_settings
module "api" {
  app_settings = merge(
    module.storage.app_settings,
    # ...
  )
}

Inputs

Name Description Required
context Platform context from environment module yes
identity Identity bundle from identity module yes
resource_group_name Resource group for the storage account yes
resource_group_location Azure region yes
containers List of blob container names to create no
connection_string_name App settings key suffix (default: storage) no
account_replication_type Replication type (default: LRS) no

Outputs

Name Description
account_name Storage account name
account_id Storage account resource ID
primary_blob_endpoint Primary blob endpoint URL
container_names Names of created containers
app_settings { "ConnectionStrings__{name}" = endpoint }

What it creates

  • Storage account (Standard LRS, shared key disabled, OAuth default)
  • Blob containers (private access)
  • Private endpoint (services subnet, blob sub-resource)
  • RBAC: Storage Blob Data Contributor → App Registration SP (runtime data-plane blob access)

RBAC notes

The App Registration service principal receives Storage Blob Data Contributor to enable data-plane operations (no connection strings, no SAS tokens). At runtime the platform pins DefaultAzureCredential to EnvironmentCredential (AZURE_TOKEN_CREDENTIALS=environmentcredential, AZURE_CLIENT_ID = app registration), so the SP — not the UAMI — is the identity making blob calls. The UAMI covers platform concerns only (ACR pull, Key Vault reference resolution). This matches the cosmosdb module, which grants its data-plane role to the SP.

Contributor rather than Owner follows least privilege and matches Aspire's default role assignment for AddAzureStorage (StorageBlobDataContributor); Owner only adds ADLS Gen2 POSIX ACL operations, which Forge apps don't use.

Providers

No providers.

Inputs

Name Description Type Default Required
account_replication_type Storage account replication type (LRS, ZRS, GRS, etc.) string "LRS" no
connection_string_name Key suffix for the app_settings connection string: ConnectionStrings__{name} string "storage" no
containers List of blob container names to create list(string) [] no
context Platform context from the environment module any n/a yes
deployer_principal_ids Map of identity keys to principal IDs granted Blob Data Contributor for CI/CD deployments map(string) {} no
enable_static_website Enable static website hosting on the storage account bool false no
identity Identity bundle from the identity module. Required when enable_static_website is false (blob access via the App Registration SP). any null no
name Override storage account name (bypasses namer). Use for migrations where the existing name differs from the namer convention. string null no
network_rules_enabled Enable storage account network rules (deny by default) bool true no
network_rules_ip_rules Additional public IP ranges to allow through the storage firewall. SAIF corporate/colocation ranges are always included. list(string) [] no
private_endpoint_enabled Create a private endpoint for blob access. Disable for static websites where FD Private Link provides connectivity. bool true no
resource_group_location The Azure region for the storage account string n/a yes
resource_group_name The resource group for the storage account string n/a yes

Outputs

Name Description
account_id The storage account resource ID
account_name The storage account name
app_settings App settings map for web app configuration
container_names Names of the created containers
primary_blob_endpoint The primary blob endpoint URL
static_website_host The primary web host for the static website (null when static website is disabled)

Resources


View source on GitHub