Skip to content

saif-resources / environment

Resolves the full platform context from foundation modules, Azure client configuration, networking constants, and naming conventions. No tfe_outputs remote-state reads remain (#845). All downstream saif-resources modules accept a context input produced by this module.

Usage

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

  environment       = var.environment
  tenant            = var.tenant
  owner             = var.owner
  project_id        = var.project_id
  is_production     = var.is_production
  resource_location = var.resource_location
  tags              = var.tags
}

Outputs

Name Description
context Structured object with all resolved platform references

Context Object Shape

context.environment / context.environment_short_name / context.tenant
context.organization_name / context.is_production / context.resource_location
context.tenant_id / context.subscription_id / context.caller_object_id
context.tags (merged common + custom)
context.diagnostic_settings_config (eventhub_name / eventhub_authorization_rule_id / log_analytics_workspace_id; iac-azure-modules v5 diagnostic settings destinations)
context.naming.resource_group_name / context.naming.internal_fd_hostname
context.team_services.service_plan_id
context.team_services.function_app_service_plan_id (null until the team enables the opt-in -functions plan; gate on != null before use)
context.org_services.apim_v2_name / context.org_services.ai_hub_id / ...
context.shared_services.acr_id / context.shared_services.key_vault_id / ...
context.networking.api_app_subnet_id / context.networking.services_subnet_id / ...
context.names (full naming module for downstream namers)

Required Providers

  • azurerm (>= 4.0, < 5.0) — plus a shared-services provider alias supplied by the caller (see below)
  • azuread (>= 3.0, < 4.0)
  • azapi (>= 2.0, < 3.0) — required for the Front Door origin-group/custom-domain existence pre-checks (see below)

azurerm.shared-services provider alias required

As of the #845 Track B decoupling, this module resolves platform coordinates via the published SAIFCorp/foundation/saif module (v1.2.0) instead of tfe_outputs remote-state reads or hand-rolled data sources: //modules/environment owns the org-scoped naming-convention lookups (APIM, Front Door, AI Hub/Search, Service Bus, org Log Analytics), //modules/team owns the team-scoped lookups (team resource group, App Service Plan, and the opt-in -functions Elastic Premium plan — surfaced on context.team_services.function_app_service_plan_id as null when the team hasn't enabled it, so consumers must gate on != null before use), and //modules/shared owns the shared-services singletons (ACR, Key Vault, App Configuration, the OTEL exporter contract). The shared-services reads run against the shared-services subscription, so callers declare a second, aliased azurerm provider themselves and pass it through — the same pattern saif-api-service has always used for its identity modules:

provider "azurerm" {
  alias           = "shared-services"
  subscription_id = "9a7b2f1c-ab7b-44b2-a254-817c6a75e958" # shared-services subscription
  features {}
}

provider "azapi" {}

module "environment" {
  source  = "app.terraform.io/SAIFCorp/resources/saif//modules/environment"
  version = "~> 0.0.0" # pin to the concrete release that ships the alias — not yet published

  providers = {
    azurerm.shared-services = azurerm.shared-services
    azapi                   = azapi
  }

  environment       = var.environment
  tenant            = var.tenant
  owner             = var.owner
  project_id        = var.project_id
  is_production     = var.is_production
  resource_location = var.resource_location
  tags              = var.tags
}

Terraform requires every instantiation of a module to satisfy its configuration_aliases — not just the callers that consume shared_services fields — so adopters add the providers = { azurerm.shared-services = azurerm.shared-services, azapi = azapi } map on their module "environment" call when they bump to the release that ships the alias. saif-api-service, saif-web-service, and saif-event-subscriber-service already declare an azurerm.shared-services alias for their identity/external-identity module calls, so they reuse the same root-level provider block; saif-event-service and saif-staticsite-service add it fresh. All five already pass a providers = { azurerm.shared-services = azurerm.shared-services } map to module "environment" ahead of the version bump — see the NOTE above each of those module blocks. That map is a no-op against the still-~> 3.8.0 registry pin (which doesn't declare the alias yet) and only exists so Forge CI's local-module swap, which resolves the source to this in-repo module for validation, has the alias configured; the map does not need — and must not add — entries for the default (unaliased) azurerm/azuread/azapi providers, which continue to be inherited implicitly. Concrete version pins are still bumped at release time, independent of this pre-wired map.

This is not a breaking change for anything pinned to a published version: the alias requirement ships in the next minor release, which existing ~> pins never resolve to. Existing workspaces keep planning against their current minor untouched; a consumer opts in at release time by bumping its pin and adding the two provider lines above at the same time. That bump also picks up the organization_services/team_services swaps, which land in the same release.

tfe_outputs elimination (#845)

As of this PR, this module has no data "tfe_outputs" reads. organization_services and team_services were the last two: every field that previously came from remote state now resolves via the SAIFCorp/foundation/saif module, a native azurerm_cdn_frontdoor_* data source (origin IDs are constructed as ${origin_group_id}/origins/${name}, since AzureRM exposes no origin data source), or — for the one field with no ARM-visible equivalent, ai_search_docs_index_name — a hardcoded literal matching both the producer's own hardcoded value and this repo's existing consumer default (see outputs.tf). custom_subdomains moved out of team_services entirely into a native per-slug lookup in the custom-subdomain module itself. shared_services was already fully native before this PR. See saif-resources/modules/external-identity/README.md for the equivalent note on okta_app.

Providers

Name Version
azapi >= 2.0, < 3.0
azuread >= 3.0, < 4.0
azurerm >= 4.0, < 5.0

Inputs

Name Description Type Default Required
environment The environment name (e.g. Test, QA, UAT, Prod) string n/a yes
environment_short_name Optional override for the environment short name. When set, takes precedence over the value derived from the naming module. string null no
is_production Whether this is a production environment bool false no
owner The team that owns the resources string n/a yes
project_id The project identifier used for resource naming string n/a yes
resource_location The Azure region for resource deployment string "westus2" no
tags Tags to apply to all resources (merged with common tags) map(string) {} no
tenant Deprecated — the Azure infra tenant is now fixed to Corporate (local.azure_tenant) for resource naming and workspace lookups. Accepted for backward compatibility with existing callers only; the value is ignored. string n/a yes

Outputs

Name Description
context Resolved platform context — environment, networking, naming, TFC outputs, and Azure client config

Resources

  • data source.azapi_resource_list.frontdoor_custom_domains (/terraform-docs/modules/environment/main.tf#126)
  • data source.azapi_resource_list.frontdoor_origin_groups (/terraform-docs/modules/environment/main.tf#120)
  • data source.azuread_client_config.current (/terraform-docs/modules/environment/main.tf#159)
  • data source.azuread_service_principal.apim_to_webapp (/terraform-docs/modules/environment/main.tf#172)
  • data source.azuread_service_principal.azuredevops (/terraform-docs/modules/environment/main.tf#178)
  • data source.azurerm_cdn_frontdoor_custom_domain.external_app (/terraform-docs/modules/environment/main.tf#148)
  • data source.azurerm_cdn_frontdoor_custom_domain.internal_app (/terraform-docs/modules/environment/main.tf#140)
  • data source.azurerm_cdn_frontdoor_origin_group.external_api_v2 (/terraform-docs/modules/environment/main.tf#132)
  • data source.azurerm_client_config.current (/terraform-docs/modules/environment/main.tf#158)

View source on GitHub