Skip to content

Azure Telemetry Module

This OpenTofu module provisions an OpenTelemetry collector as a container app inside an existing Container App Environment. When Grafana Cloud is enabled it also provisions the Azure Monitor data source and the subscription-scoped role assignment, and points the collector's OTLP exporter at the stack.

Features

  • OpenTelemetry collector container app deployed into an existing ACA environment (internal gRPC/HTTP OTLP ingress).
  • Grafana Cloud logs, metrics, and traces pipelines via an access policy token — gated by enable_grafana.
  • Grafana Azure Monitor data source provisioned through the Grafana provider.
  • Optional subscription-scoped Monitoring Reader role assignment for the Grafana service principal (create_subscription_role_assignment).
  • Grafana-optional: with enable_grafana = false the collector still deploys (exporting to debug) and no Grafana credentials or provider are required — every grafana_* and service_principal_* input becomes optional.
  • Fail-fast: when enable_grafana = true, a missing credential aborts the plan up front via a terraform_data precondition rather than surfacing as a provider 401 during refresh.
  • Configurable workload profile and collector image for FIPS builds.

Requirements

Name Version
azapi 2.7.0
azuread ~> 3.0
azurerm ~> 4.0
grafana ~> 4.0

Providers

Name Version
azurerm 4.81.0
grafana 4.45.2
terraform n/a

Modules

No modules.

Resources

Name Type
azurerm_container_app.otel_gateway resource
azurerm_role_assignment.grafana_monitoring_reader resource
grafana_data_source.azure_monitor resource
terraform_data.grafana_credentials_check resource
azurerm_subscription.current data source
grafana_cloud_stack.this data source

Inputs

Name Description Type Default Required
acr_login_server The login server URL of the ACR (e.g., myacr.azurecr.io) for pulling the OTel collector image string n/a yes
container_app_environment_id [d] The container app environment id to install the collector in string n/a yes
create_subscription_role_assignment Whether or not to create the grafana role assignment for this subscription bool true no
enable_grafana Whether to wire this environment to Grafana Cloud. When false the module
deploys only the OTel collector container app and reads no Grafana
credentials, so this subscription's telemetry stays in-environment.
When true (the default) every grafana_ and service_principal_ input is
required and the grafana provider must be configured by the caller.
bool true no
grafana_cloud_stack_slug Our grafana cloud stack name. Required when var.enable_grafana is true. string null no
grafana_cloud_token Grafana Cloud Access Policy Token (must have logs:write, metrics:write, traces:write). Required when var.enable_grafana is true. string null no
grafana_data_source_name The name of the grafana data source string "Azure Monitor" no
grafana_instance_id Grafana Cloud Instance ID. Required when var.enable_grafana is true. string null no
otel_collector_image The container image for the OpenTelemetry collector (defaults to the upstream contrib image) string "acrmerkalis2b65.azurecr.io/minimus/opentelemetry-collector-contrib-fips:0.156.0" no
registry_identity_id Resource ID of the user-assigned managed identity used for ACR authentication string n/a yes
resource_group_name [d] The name of the resource group the container app env is in string n/a yes
service_principal_client_id The grafana service principal's client id. Required when var.enable_grafana is true. string null no
service_principal_client_secret The grafana service principal's client secret. Required when var.enable_grafana is true. string null no
service_principal_id [d] The grafana service principal's id. Required when var.enable_grafana is true. string null no
subscription_id [d] The azure subscription id string n/a yes
tenant_id The grafana service principal's tenant id. Required when var.enable_grafana is true. string null no
workload_profile_name Workload profile name assigned to the OTel gateway container app string "Consumption" no

[d] Destructive: changing this input forces one or more resources to be destroyed and recreated (an OpenTofu/Terraform replacement) rather than updated in place.

Outputs

Name Description
grafana_datasource_uid UID of the Grafana Azure Monitor data source (null when var.enable_grafana is false)

Example Usage

With Grafana Cloud (default)

module "telemetry" {
  source = "oci://acrmerkalisdist0c66.azurecr.io/modules/azure/telemetry?tag=<module-version>"

  resource_group_name          = "rg-prod-observability"
  container_app_environment_id = module.compute.container_app_environment_id
  subscription_id              = data.azurerm_client_config.current.subscription_id
  tenant_id                    = var.grafana_tenant_id

  acr_login_server     = "myacr.azurecr.io"
  registry_identity_id = module.compute.identity_id

  otel_collector_image = "<hardened-opentelemetry-collector-image>"

  grafana_cloud_stack_slug = "my-stack"
  grafana_instance_id      = "123456"
  grafana_cloud_token      = "<access-policy-token>"

  service_principal_id            = "<sp-object-id>"
  service_principal_client_id     = "<sp-client-id>"
  service_principal_client_secret = "<sp-secret>"
}

Without Grafana credentials

Deploys only the collector; it exports to debug and never touches the Grafana provider. Set enable_grafana = false and omit every grafana_* and service_principal_* input:

module "telemetry" {
  source = "oci://acrmerkalisdist0c66.azurecr.io/modules/azure/telemetry?tag=<module-version>"

  resource_group_name          = "rg-dev-observability"
  container_app_environment_id = module.compute.container_app_environment_id
  subscription_id              = data.azurerm_client_config.current.subscription_id

  acr_login_server     = "myacr.azurecr.io"
  registry_identity_id = module.compute.identity_id

  otel_collector_image = "<hardened-opentelemetry-collector-contrib-image>"

  enable_grafana = false
}

Notes

1. grafana_cloud_token and service_principal_client_secret are sensitive and must never be committed to version control.

2. <hardened-opentelemetry-collector-contrib-image> can be pulled from various specialized providers and stored in your local Azure Container Registry.

Available versions

  • v0.9.1