1.6.13.1. ModTM Provider: Terraform Module Telemetry Provider

In large organizations or communities, a series of reusable Terraform modules is often maintained. However, as the number of modules and the scale of their usage expand, module governance faces numerous challenges. Team leads and module maintainers often struggle to answer questions such as: Which modules are widely used? Which versions are still in production? Are there modules that are no longer in use and can be deprecated? Without effective data support, these decisions can only rely on guesswork or manual statistics, which are neither accurate nor timely. A lack of visibility into module usage leads to duplicated efforts, delayed upgrades, and even security compliance risks.

In promoting best practices such as Azure Verified Modules (AVM), Azure has profoundly recognized the importance of "telemetry" for module governance. Maintainers can only make fact-based decisions by collecting and analyzing module usage data. This necessity gave birth to the Terraform Module Telemetry Provider: ModTM. ModTM is a Terraform plugin provided by Azure, designed to solve the usage tracking problem in large-scale module governance.

1.6.13.1.1. Introduction to ModTM: What Is It?

ModTM (Terraform Module TeleMetry) is a Terraform Provider plugin specifically designed to collect usage data for Terraform modules. It introduces a custom resource type, modtm_telemetry. When you include this resource in a module, ModTM sends pre-defined tag data within the module to a specified telemetry endpoint via an HTTP POST request whenever lifecycle operations (Create, Update, Delete, etc.) occur. Simply put, ModTM adds telemetry capabilities to Terraform modules, allowing the module to "report itself" regarding its usage and lifecycle events.

The goal of ModTM is to enhance visibility into the module lifecycle, helping to understand usage patterns: which modules are frequently deployed, which versions are most popular, which modules may no longer be in use, and in which regions users are deploying them. This data is invaluable for module governance, enabling the identification of widely popular modules (to prioritize maintenance) and long-unused modules (to consider for retirement or refactoring). At the same time, ModTM emphasizes data privacy and control; it only collects tags defined by the user and a UUID for the module instance to identify it, without collecting any other environmental or resource-sensitive information. By allowing users to explicitly specify what data to report, ModTM hands the initiative of telemetry over to the user.

It is worth noting that ModTM is a lightweight, non-intrusive solution. It does not affect the infrastructure itself, nor does it rely on cloud resource deployments. It merely sends HTTP requests during the plan execution via the Terraform Provider mechanism. Its implementation ensures no obstruction to the Terraform deployment process; even in environments with no network or restricted networks, a telemetry failure will not cause Terraform execution to error out or interrupt (at most causing a delay of a few seconds and logging the event). Because of this, using ModTM does not affect the normal deployment and operation of existing infrastructure, balancing data collection with system stability.

1.6.13.1.2. Core Principles: How Telemetry Data Is Collected and Transmitted

The working principle of ModTM can be divided into two parts: the module side and the server side.

  • Client (Terraform Provider): When you configure the modtm_telemetry resource in a module, the ModTM Provider intercepts the module's lifecycle events when Terraform executes apply. During module Create, Update, or Delete, the ModTM Provider sends a set of pre-defined tags as a JSON payload via HTTP POST to a specified telemetry server URL. These tags typically include: the module's name or source, version number, deployment environment information, etc., which are specified by the user within the module.

  • Server (Telemetry Collection Service): Azure provides a corresponding telemetry receiver service implementation. For example, in the Azure Verified Modules scenario, ModTM defaults to sending data to an Azure-hosted web service, which then forwards and stores the telemetry data in Azure Application Insights (Azure's cloud application monitoring service). Application Insights is used to centrally record and analyze these telemetry logs, allowing maintainers to query module usage. For instance, one can count usage by module name/version, summarize module deployments by Subscription ID, or track the lifecycle of module instances (when they were created and when they were destroyed).

Why not send data directly to Application Insights? Because ModTM aims to be a platform-agnostic, neutral solution. It avoids binding itself to the Azure platform, hence the use of HTTP for data transmission. Any user wishing to deploy a private telemetry collection service can implement their own HTTP server and save the collected data in their preferred manner.

Azure officially describes ModTM as a "lightweight telemetry provider that sends telemetry data to Azure Application Insights via an HTTP POST frontend service." This architecture ensures that no sensitive Telemetry keys are directly embedded in the module code. The module simply sends data to a public endpoint URL, while the actual Azure monitoring credentials are kept solely on the server side. For enterprise users who do not wish to send telemetry data to Microsoft-hosted services, ModTM also supports custom sending endpoints and filtering rules. For example, you can specify your own receiver service URL in the Provider configuration and limit collection to data from specific module sources. By default, the ModTM provided by Azure comes built-in with the official telemetry service URL and allowlists, ensuring an out-of-the-box experience for users of Azure Verified Modules.

Regarding Data Content and Privacy Control, ModTM adopts a fully user-defined tags mechanism. You can choose which data to collect as key-value pairs, such as module identifiers, versions, the Azure Subscription or Tenant where it resides, deployment regions, etc. In official examples, it typically collects the Azure environment's Subscription ID, Tenant ID, as well as the module's source and version, plus a random UUID to identify each module instance. For example, a module might define tags as follows:

tags = {
  subscription_id = one(data.azurerm_client_config.telemetry).subscription_id
  tenant_id       = one(data.azurerm_client_config.telemetry).tenant_id
  module_source   = one(data.modtm_module_source.telemetry).module_source
  module_version  = one(data.modtm_module_source.telemetry).module_version
  random_id       = one(random_uuid.telemetry).result
  location        = var.location
}

In the tags above, subscription_id and tenant_id indicate the Azure environment where the module is deployed. module_source and module_version are automatically extracted by ModTM to identify the current module's source address and version number (via the modtm_module_source data source or Provider built-in functions). random_id is the generated UUID for the module instance, which remains constant across deployments, while location is a region parameter provided by the module user. You can also add more business-related tags (e.g., environment type, user team, etc.) as needed to enrich the telemetry information. ModTM does not actively collect any undeclared data; only these user-provided tags and the UUID are packaged and sent. If users do not want to report certain information due to privacy concerns, they can choose not to include it as a tag or completely disable telemetry.

1.6.13.1.3. Using ModTM: Integrating Telemetry into Modules

ModTM is designed to be easily integrated into Terraform modules. Here are the basic steps and examples for using ModTM:

  1. Declare the ModTM Provider in the Module Ensure that the ModTM provider is required in the module's terraform configuration. For example, add the following to the module's terraform.tf file: ```hcl terraform { required_providers { modtm = { source = "Azure/modtm" version = "~> 0.3" } } }

This causes Terraform to download the Azure-provided modtm plugin (version 0.3.x). Azure's official module specifications mandate the inclusion of this configuration, checking that ModTM is correctly declared even during module code linting.
2. **Add a Telemetry Configuration Toggle**
It is generally recommended that modules provide a boolean variable (e.g., `enable_telemetry`) to allow users to control whether telemetry is enabled. In Azure modules, this variable defaults to `true` (enabled), and documentation clearly states that setting it to false will result in no telemetry collection. This respects user choice and facilitates turning off unnecessary network communication in certain environments (such as offline environments).
3. **Define ModTM Resources in the Module**
Create a `main.telemetry.tf` or equivalent Terraform configuration file, and use ModTM data sources and resources within it. For example:
```hcl
data "azurerm_client_config" "telemetry" {
  count = var.enable_telemetry ? 1 : 0
}

data "modtm_module_source" "telemetry" {
  count       = var.enable_telemetry ? 1 : 0
  module_path = path.module
}

resource "random_uuid" "telemetry" {
  count = var.enable_telemetry ? 1 : 0
}

resource "modtm_telemetry" "telemetry" {
  count = var.enable_telemetry ? 1 : 0
  tags = {
    subscription_id = one(data.azurerm_client_config.telemetry).subscription_id
    tenant_id       = one(data.azurerm_client_config.telemetry).tenant_id
    module_source   = one(data.modtm_module_source.telemetry).module_source
    module_version  = one(data.modtm_module_source.telemetry).module_version
    random_id       = one(random_uuid.telemetry).result
    location        = var.location
  }
}

The code above uses the conditional count technique: when enable_telemetry is false, the count for these data sources and resources is 0, effectively creating nothing, thus achieving a one-switch disablement of telemetry. Conversely, when enabled, ModTM performs the following during the module deployment: calls azurerm_client_config to get Subscription and Tenant IDs; uses data.modtm_module_source to automatically read the module's source and version attributes; creates a random_uuid to generate a unique module instance identifier; and finally executes the modtm_telemetry resource. Whenever this module instance is created, updated, or destroyed, modtm_telemetry.telemetry sends an HTTP request containing the aforementioned tags to the preset endpoint, thereby recording a telemetry log. It is specifically worth noting that data.modtm_module_source.telemetry obtains the current path of the module at deployment time by reading path.module at runtime. From this path, it searches upwards layer by layer for the .terraform/modules/modules.json file, matching its own source and version information based on the path and returning it to the caller. This information can be used not only with the modtm Provider but also for other telemetry data purposes. For instance, in AzAPI, one can set data such as create_headers. We can define an azapi_resource block like this:

resource "azapi_resource" "example" {
  type      = "Microsoft.ContainerRegistry/registries@2020-11-01-preview"
  name      = "registry1"
  parent_id = azurerm_resource_group.example.id

  location = azurerm_resource_group.example.location
  identity {
    type         = "SystemAssigned, UserAssigned"
    identity_ids = [azurerm_user_assigned_identity.example.id]
  }

  body = {
    sku = {
      name = "Standard"
    }
    properties = {
      adminUserEnabled = true
    }
  }

  tags = {
    "Key" = "Value"
  }
  create_headers = {
   User-Agents = "module_source=${one(data.modtm_module_source.telemetry).module_source},module_version=${one(data.modtm_module_source.telemetry).module_version}"
  }
  update_headers = {
   User-Agents = "module_source=${one(data.modtm_module_source.telemetry).module_source},module_version=${one(data.modtm_module_source.telemetry).module_version}"
  }
  read_headers = {
   User-Agents = "module_source=${one(data.modtm_module_source.telemetry).module_source},module_version=${one(data.modtm_module_source.telemetry).module_version}"
  }
  delete_headers = {
   User-Agents = "module_source=${one(data.modtm_module_source.telemetry).module_source},module_version=${one(data.modtm_module_source.telemetry).module_version}"
  }

  response_export_values = ["properties.loginServer", "properties.policies.quarantinePolicy.status"]
}

In this way, when using this module, the Create/Read/Update/Delete methods issued through azapi_resource.example will include the module name and version information in the User-Agents. This helps Microsoft confirm in the backend which API calls originate from AVM modules, exactly which modules they originate from, version distribution, and other highly useful information. For new features in Terraform 1.5+, one can also omit the data source and directly call functions provided by the ModTM Provider to get the module source and version. For example, official support exists for syntax like provider::modtm::module_source(path.module). Regardless of the method used, module usage information will ultimately be sent out without affecting the deployment of primary resources.

  1. Verification and Execution After publishing and applying the module, you can verify if the telemetry data was successfully received by checking Azure Application Insights (if using the official endpoint) or the logs of your self-hosted telemetry service. Since ModTM is non-blocking, it will not print obvious success/failure messages in the Terraform output—unless a network error occurs, in which case a log hint will be recorded. typically, you can see records similar to "Received telemetry for module X version Y, Subscription ID=..., Time=..." on the log server side, proving that ModTM is working correctly.

With the above steps, module authors can enable a "telemetry eye" for their modules without writing any complex code. All resources introduced by ModTM (data sources and random UUIDs) are local in nature; they do not create extra resources in the cloud, nor do they affect the module's primary infrastructure functions. For the end-user utilizing the module, aside from a very small HTTP request traffic generated during Terraform execution, the deployment process and results are virtually unaffected.

1.6.13.1.4. The Value of Module Governance: Data-Driven Decision Making and Optimization

Before the introduction of ModTM, module maintainers often lacked reliable data to improve and manage modules. Now, telemetry data collected via ModTM can significantly enhance the scientific nature and efficiency of module governance:

  • Usage Pattern Analysis: Maintenance teams can use tools like Application Insights to analyze collected logs. For example, counting how many times a module is deployed daily/monthly, or how many module instances currently exist in various subscriptions. This data helps determine the popularity and usage trends of a module. High-frequency modules can receive more resources for continuous optimization, while modules with low or zero usage may indicate redundant functionality or insufficient documentation, warranting further investigation.
  • Version and Upgrade Governance: Since ModTM captures module version information, maintainers can see which old versions users are still utilizing. For instance, if a large number of instances are found on an old version that hasn't been upgraded, the team can evaluate the reasons (perhaps upgrade resistance or compatibility issues) and formulate appropriate strategies. Conversely, if telemetry shows that most users have migrated to a new version, retiring old versions or features can be considered. In this way, version iteration and lifecycle management of large-scale module libraries become more evidence-based.
  • Module Compliance and Standardization Promotion: In internal enterprise deployments, architecture teams often mandate the use of certified standard modules. ModTM can help track the adoption of these standard modules. For example, by collecting the module_source tag, one can distinguish whether teams are using the company-provided module source. If some teams have forked the module themselves, corresponding records will not appear in the telemetry. This is because when teams fork a module, they might include private data in the module's source path, so strict restrictions must be placed on source to avoid collecting data that shouldn't be collected. Although ModTM itself cannot directly detect "unused modules," it provides a quantitative basis for the scope of adopted standard modules, promoting compliance from a lateral perspective.
  • Anomaly and Issue Tracking (Indirect Benefits): Although ModTM primarily collects usage volume data, when combined with time-series analysis, it can also indirectly reveal certain anomalies. For example, if Create/Destroy events for a module show abnormal spikes, it might suggest resource churn (frequent deployment and destruction) or an automation process endlessly retrying. Maintainers can then investigate whether there are design issues or usage misconceptions with the module. Such insights depend on in-depth analysis of telemetry data, but once established, they are very helpful for improving module quality and stability.
  • Decision Transparency and Communication: With data support, module evolution decisions can be communicated more transparently to stakeholders. For example, when proposing to deprecate a module, maintainers can cite telemetry statistics proving "zero new deployments and zero instances for this module in the past 6 months," making the decision easier to accept. Similarly, when demonstrating DevOps improvement results to management, metrics like increased module adoption rates can be used to quantify value.

In summary, ModTM introduces a critical telemetry feedback loop to the Terraform module ecosystem. Modules are no longer "black boxes" that leave no trace after being put into use; maintainers can continuously monitor "user behavior" data of modules just like product managers treat software applications, thereby driving data-driven improvements. This is especially crucial in large-scale module governance scenarios—when there are numerous modules and scattered users, only automated telemetry collection can provide a comprehensive grasp of the global situation.

It is worth mentioning that Azure officially integrates ModTM by default in its Azure Verified Modules templates and enables telemetry collection by default. Users of these modules, while following open-source licenses, also help the module maintenance team collect valuable anonymous usage data (though users have the right to disable this at any time via variable configuration). The module code repositories also clearly contain data collection statements and privacy notices to ensure compliance. For the vast number of Terraform module developers, even if not in an Azure environment, the ModTM model holds reference value—by using a lightweight telemetry tool, communities and enterprises can build a measurement system for module usage, enhancing the level of module governance.

1.6.13.1.5. Summary

The emergence of ModTM (Terraform Module TeleMetry) fills a gap in Terraform module governance. It solves the challenge of module usage data acquisition in a concise manner, helping large organizations realize module-level telemetry within their DevOps toolchains. Through ModTM, we can better understand module usage dynamics in the "Infrastructure as Code" world, which has significant value for optimizing modules, improving architecture, and promoting standardization. For developers, ModTM is easy to use, has zero interference with normal deployments, and offers a high degree of autonomy and privacy control, making it a trustworthy tool in large-scale module governance. As stated in the official documentation, ModTM empowers Terraform modules with data insight capabilities, enabling us to make smarter decisions while guaranteeing privacy and stability. With ModTM, the management of large Terraform module libraries is moving towards a more visualized and intelligent future.

results matching ""

    No results matching ""