Provisions a single Azure Application Insights availability WebTest (
azurerm_application_insights_web_test) that probes an HTTP(S) endpoint from one or more Azure regions and reports availability into an Application Insights component. Targetshashicorp/azurerm ~> 4.0.
- 🎯 Creates one Application Insights availability WebTest that repeatedly probes an endpoint and records success/failure and response time.
- 🌍 Runs the probe from multiple Azure geo-locations for global coverage, so a single-region blip does not read as an outage.
- ✅ Ships active by default (
enabled = true) with retries on (retry_enabled = true) at a 5-minute cadence (frequency = 300). - 🧪 Supports both
ping(single-request) andmultisteptest kinds;pingis the default and recommended shape. - 🏷️ Carries the universal
tagstail and an operationaltimeoutsblock.
💡 Why it matters: A synthetic availability test is the earliest signal that a public endpoint has gone dark or slow — often before a single user complains. Provisioning it as code keeps the probe cadence, region coverage, and alert-feeding metric consistent across every service in the estate, and keeps a disabled (silent) test from slipping into production unnoticed.
If this module saves you time, please consider supporting its continued development:
- ⭐ Star the repository — it helps others discover the work.
- 🤝 Connect on LinkedIn: linkedin.com/in/microsoftexpert
- ☕ Buy me a coffee: buymeacoffee.com/microsoftexpert
graph TD
rg["terraform-azurerm-resource-group"]
ai["terraform-azurerm-application-insights"]
wt["terraform-azurerm-application-insights-web-test"]
ag["terraform-azurerm-monitor-action-group"]
rg -->|"resource_group_name"| wt
ai -->|"application_insights_id"| wt
wt -->|"availability results"| ai
wt -->|"failure metric"| ag
classDef me fill:#0078D4,stroke:#004578,color:#ffffff;
classDef target fill:#004578,stroke:#002a44,color:#ffffff;
classDef sib fill:#eef3f8,stroke:#b9c7d6,color:#1b2733;
class wt me;
class ai target;
class rg,ag sib;
The WebTest depends on an existing resource group and an Application Insights component; its results surface as availability data in that component, and a metric alert can route failures to a monitor action group.
graph LR
subgraph inputs["Inputs"]
v1["name / location"]
v2["resource_group_name"]
v3["application_insights_id"]
v4["kind / geo_locations / frequency"]
v5["configuration (XML)"]
end
res["azurerm_application_insights_web_test.this"]
subgraph outputs["Outputs"]
o1["id"]
o2["name"]
o3["synthetic_monitor_id"]
end
v1 -->|"identity"| res
v2 -->|"placement"| res
v3 -->|"parent component"| res
v4 -->|"test definition"| res
v5 -->|"probe spec"| res
res -->|"emits"| o1
res -->|"emits"| o2
res -->|"emits"| o3
classDef me fill:#0078D4,stroke:#004578,color:#ffffff;
classDef io fill:#eef3f8,stroke:#b9c7d6,color:#1b2733;
class res me;
class v1,v2,v3,v4,v5,o1,o2,o3 io;
Resource inventory
| Resource | Count | Role |
|---|---|---|
azurerm_application_insights_web_test.this |
1 | The keystone availability WebTest, with an optional timeouts block. |
| Requirement | Value |
|---|---|
| Terraform | >= 1.12.0 |
hashicorp/azurerm |
~> 4.0 |
| Provider block | None in this module — the caller configures provider "azurerm", its auth, and the mandatory features {} block. |
Schema notes that bite (verified against the live provider schema):
- Force-new fields — changing any of
name,resource_group_name,location,application_insights_id, orkinddestroys and recreates the WebTest. locationmust correlate with the parent Application Insights component's region; a mismatch is rejected by the platform.frequencyaccepts only300,600,900seconds;kindaccepts onlypingormultistep.- The provider's
timeoutargument (the test's own response timeout in seconds) is surfaced here as thetest_timeoutvariable to avoid confusion with the operationaltimeoutsCRUD block. - This Terraform resource maps to the Azure "Application Insights Classic Web Test"; the Terraform name is kept for backward compatibility.
- Monitoring Contributor at the target resource group (or a narrower scope granting
Microsoft.Insights/webtests/*). This is the least-privilege built-in role that can create, read, update, and delete WebTests. Contributor also works but is broader than necessary.
- An existing resource group in a supported US Azure region.
- An existing Application Insights component — its resource ID is a required input; the WebTest's
locationmust correlate with the component's region. - The
Microsoft.Insightsresource provider registered on the target subscription (API version2022-06-15). - The caller configures the
provider "azurerm" { features {} }block, auth, and subscription; this module declares none of these.
terraform-azurerm-application-insights-web-test/
├── providers.tf # required_version >= 1.12.0; azurerm ~> 4.0; no provider block
├── variables.tf # deeply-typed inputs; secure defaults; universal tags + timeouts tail
├── main.tf # the keystone azurerm_application_insights_web_test.this renderer
├── outputs.tf # id first, then name, synthetic_monitor_id, application_insights_id
├── README.md # this document
├── SCOPE.md # the cross-module contract
├── LICENSE # MIT
└── .gitignore # canonical library ignore set
provider "azurerm" {
features {}
}
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-storefront-home"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-observability/providers/Microsoft.Insights/components/appi-storefront"
geo_locations = ["us-tx-sn1-azr", "us-il-ch1-azr", "us-va-ash-azr"]
configuration = <<-XML
<WebTest Name="storefront-home" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://www.contoso.com/" ExpectedHttpStatusCode="200" ParseDependentRequests="False" FollowRedirects="True" />
</Items>
</WebTest>
XML
}ℹ️ The caller owns provider configuration, authentication, and the mandatory
features {}block. Pin the module with?ref=v1.0.0— never a branch.
Consumes
| Input | Type | Typical source |
|---|---|---|
resource_group_name |
string |
terraform-azurerm-resource-group (name) |
location |
string |
caller / parent component region |
application_insights_id |
string |
terraform-azurerm-application-insights (id) |
Emits
| Output | Description |
|---|---|
id |
WebTest Resource ID (emitted first). |
name |
WebTest name. |
synthetic_monitor_id |
Synthetic monitor ID correlating availability results. |
application_insights_id |
Parent Application Insights component ID. |
Values these examples reference but do not create are declared inputs:
variable "workspace_id" {
description = "workspace id of an existing resource these examples reference."
type = string
}1 · Minimal active ping test
The smallest real call. Everything else takes a secure default: enabled = true, retry_enabled = true, kind = "ping", frequency = 300, test_timeout = 30.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-home"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-il-ch1-azr", "us-va-ash-azr"]
configuration = <<-XML
<WebTest Name="home" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://www.contoso.com/" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
}🔒 The probe targets an
https://URL so the test exercises the encrypted path.
2 · HTTPS endpoint asserting a 200 response
A ping test that explicitly asserts the healthy status code and follows redirects.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-api-health"
resource_group_name = "rg-observability"
location = "eastus2"
application_insights_id = var.appinsights_id
geo_locations = ["us-ca-sjc-azr", "us-va-ash-azr"]
configuration = <<-XML
<WebTest Name="api-health" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://api.contoso.com/healthz" ExpectedHttpStatusCode="200" FollowRedirects="True" ParseDependentRequests="False" />
</Items>
</WebTest>
XML
}💡
ParseDependentRequests="False"keeps the probe focused on the endpoint itself rather than its downstream assets.
3 · Broad multi-region coverage
Five geo-locations reduce false alerts from a single-region network event.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-home-global"
resource_group_name = "rg-observability"
location = "centralus"
application_insights_id = var.appinsights_id
geo_locations = [
"us-tx-sn1-azr",
"us-il-ch1-azr",
"us-va-ash-azr",
"us-ca-sjc-azr",
"us-fl-mia-edge",
]
configuration = <<-XML
<WebTest Name="home-global" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://www.contoso.com/" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
}💡 Availability alert rules commonly fire when X of N locations fail; more locations gives a sturdier signal.
4 · Slower cadence for a low-churn endpoint
frequency accepts only 300, 600, or 900 seconds.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-marketing"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-va-ash-azr"]
frequency = 900
configuration = <<-XML
<WebTest Name="marketing" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://marketing.contoso.com/" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
}
⚠️ Passing any value other than300,600, or900fails the input validation before any API call.
5 · Custom per-run response timeout
test_timeout maps to the provider's timeout argument — the seconds the probe waits for a response.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-slow-report"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-va-ash-azr"]
test_timeout = 60
configuration = <<-XML
<WebTest Name="slow-report" Enabled="True" Timeout="60" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://reports.contoso.com/daily" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
}ℹ️ Keep the XML
Timeoutattribute aligned withtest_timeoutso the definition and the resource agree.
6 · Staged test (disabled until cutover)
Provision the test but hold it inactive until the endpoint is live.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-preprod"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr"]
enabled = false
configuration = <<-XML
<WebTest Name="preprod" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://preprod.contoso.com/" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
}
⚠️ A disabled test is a silent monitoring gap.enableddefaults totrue; setting itfalseis a deliberate opt-out you should track.
7 · First-failure alerting (retries off)
Turn retries off when you want the very first failure to raise the metric immediately.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-payments-critical"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-il-ch1-azr", "us-va-ash-azr"]
retry_enabled = false
configuration = <<-XML
<WebTest Name="payments-critical" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://payments.contoso.com/status" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
}💡
retry_enableddefaults totrueto suppress transient blips; disable it only for endpoints where any failure is worth an immediate page.
8 · Description and tags for governance
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-home-tagged"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-va-ash-azr"]
description = "Storefront home page availability, owned by the platform team."
tags = {
environment = "prod"
owner = "platform"
cost_center = "1234"
}
configuration = <<-XML
<WebTest Name="home-tagged" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://www.contoso.com/" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
}9 · Asserting a non-200 status code
An auth-gated endpoint that should return 401 when reached anonymously is still "up" if it answers with 401.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-admin-gate"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-va-ash-azr"]
configuration = <<-XML
<WebTest Name="admin-gate" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://admin.contoso.com/" ExpectedHttpStatusCode="401" />
</Items>
</WebTest>
XML
}🔒 Never embed credentials in the WebTest XML — assert the challenge response instead of authenticating.
10 · Content match on the response body
A ping test can validate a marker string in the response using a validation rule.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-content-match"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-va-ash-azr"]
configuration = <<-XML
<WebTest Name="content-match" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://www.contoso.com/status" ExpectedHttpStatusCode="200">
<ValidationRules>
<ValidationRule Classname="Microsoft.VisualStudio.TestTools.WebTesting.Rules.ValidationRuleFindText, Microsoft.VisualStudio.QualityTools.WebTestFramework" DisplayName="Find Text" Description="Verifies the presence of the specified text in the response." Level="High" ExecutionOrder="BeforeDependents">
<RuleParameters>
<RuleParameter Name="FindText" Value="OK" />
<RuleParameter Name="IgnoreCase" Value="False" />
<RuleParameter Name="UseRegularExpression" Value="False" />
<RuleParameter Name="PassIfTextFound" Value="True" />
</RuleParameters>
</ValidationRule>
</ValidationRules>
</Request>
</Items>
</WebTest>
XML
}💡 A content match catches a "200 but wrong page" failure that a bare status-code assertion misses.
11 · Custom CRUD timeouts
The universal timeouts block tunes how long Terraform waits on each operation — unrelated to test_timeout.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-home-timeouts"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr"]
configuration = <<-XML
<WebTest Name="home-timeouts" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://www.contoso.com/" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
timeouts = {
create = "30m"
read = "5m"
update = "30m"
delete = "30m"
}
}12 · Multistep test kind
Set kind = "multistep" for a legacy multi-request test. kind is force-new.
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-checkout-flow"
resource_group_name = "rg-observability"
location = "eastus"
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-va-ash-azr"]
kind = "multistep"
configuration = var.multistep_webtest_xml
}ℹ️
pingis the recommended shape for new tests;multistepis retained for backward compatibility. Changingkindafter creation replaces the resource.
13 · A fleet of tests with for_each
Drive many endpoints from one keyed map. Stable keys keep additions from re-indexing the rest.
variable "endpoints" {
type = map(object({
url = string
location = string
}))
}
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
for_each = var.endpoints
name = "wt-${each.key}"
resource_group_name = "rg-observability"
location = each.value.location
application_insights_id = var.appinsights_id
geo_locations = ["us-tx-sn1-azr", "us-va-ash-azr"]
configuration = <<-XML
<WebTest Name="${each.key}" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="${each.value.url}" ExpectedHttpStatusCode="200" />
</Items>
</WebTest>
XML
tags = { managed_by = "platform" }
}💡 Keying on a stable name (not a list index) means removing one endpoint never disturbs the others' state.
14 · 🏗️ End-to-end composition
Wire the sibling resource-group and Application Insights modules into this one, feeding the component's id output straight into application_insights_id.
provider "azurerm" {
features {}
}
module "resource_group" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-resource-group.git?ref=v1.0.0"
name = "rg-observability"
location = "eastus"
}
module "application_insights" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights.git?ref=v1.0.0"
workspace_id = var.workspace_id
name = "appi-storefront"
resource_group_name = module.resource_group.name
location = module.resource_group.location
application_type = "web"
}
module "web_test" {
source = "git::https://github.com/microsoftexpert/terraform-azurerm-application-insights-web-test.git?ref=v1.0.0"
name = "wt-storefront-home"
resource_group_name = module.resource_group.name
location = module.resource_group.location
application_insights_id = module.application_insights.id
geo_locations = ["us-tx-sn1-azr", "us-il-ch1-azr", "us-va-ash-azr"]
configuration = <<-XML
<WebTest Name="storefront-home" Enabled="True" Timeout="30" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Items>
<Request Method="GET" Url="https://www.contoso.com/" ExpectedHttpStatusCode="200" FollowRedirects="True" />
</Items>
</WebTest>
XML
tags = {
environment = "prod"
owner = "platform"
}
}💡
locationis taken from the resource group so it correlates with the Application Insights component's region — a mismatch would be rejected by the platform.
Identity (all force-new) — name, resource_group_name, location, application_insights_id.
Test definition — geo_locations (required list), configuration (required XML), kind (default ping).
Behaviour — frequency (default 300), test_timeout (default 30), enabled (default true), retry_enabled (default true), description.
Universal tail — tags, timeouts.
Full input schemas
| Name | Type | Default | Required | Notes |
|---|---|---|---|---|
name |
string |
— | yes | Force-new. |
resource_group_name |
string |
— | yes | Existing RG; force-new. |
location |
string |
— | yes | Force-new; must match parent component region. |
application_insights_id |
string |
— | yes | Parent component ID; force-new. |
geo_locations |
list(string) |
— | yes | At least one population tag (validated). |
configuration |
string |
— | yes | XML WebTest definition. |
kind |
string |
"ping" |
no | One of ping, multistep (validated); force-new. |
frequency |
number |
300 |
no | One of 300, 600, 900 (validated). |
test_timeout |
number |
30 |
no | A whole number of seconds greater than zero. Maps to the provider's timeout. The provider applies no ValidateFunc to this field and publishes no upper bound, so only the shape is checked here — an earlier version of this module refused anything above 120, which rejected values the provider accepts. |
enabled |
bool |
true |
no | Active by default. |
retry_enabled |
bool |
true |
no | Retries on by default. |
description |
string |
null |
no | Free-text description. |
tags |
map(string) |
{} |
no | Resource tags. |
timeouts |
object({ create, read, update, delete }) |
null |
no | Operational CRUD timeouts, each optional(string). |
variable "timeouts" {
type = object({
create = optional(string)
read = optional(string)
update = optional(string)
delete = optional(string)
})
default = null
}| Output | Description | Kind |
|---|---|---|
id |
Resource ID of the Application Insights WebTest | Passthrough |
name |
Name of the Application Insights WebTest | Passthrough |
location |
Azure region the resource is deployed in, in the canonical form Azure uses | Passthrough |
synthetic_monitor_id |
The synthetic monitor ID of the WebTest, used to correlate availability results in Application Insights | Passthrough |
application_insights_id |
Resource ID of the Application Insights component this WebTest reports into | Passthrough |
kind |
The kind of test: "ping" or "multistep", lower-case | Passthrough |
geo_locations |
The population tags the test runs from, as stored | Passthrough |
geo_location_count |
How many locations the test runs from | Passthrough |
frequency |
Interval in seconds between runs: 300, 600 or 900 | Passthrough |
test_timeout |
Seconds until a run is marked failed | Passthrough |
enabled |
Whether the test is actively running | Passthrough |
timeout_exceeds_run_interval |
True when test_timeout is greater than or equal to frequency — a configuration in which a slow run can still be in flight when the next one is due, so runs overlap |
Passthrough |
runs_from_fewer_than_five_locations |
True when the test probes from fewer than five geo-locations | Passthrough |
collects_nothing_while_disabled |
Always true, and worth stating because the failure is silent | Constant |
location_must_match_the_parent_component |
Always true, and unverifiable from here | Constant |
configuration_is_unvalidated_xml |
Always true | Constant |
every_identifying_argument_is_force_new |
Always true | Constant |
No secret is emitted; the resource carries no secret-bearing attribute.
- Force-new identity.
name,resource_group_name,location,application_insights_id, andkindare immutable — Terraform replaces the WebTest if any changes. Treat them as the resource's fixed identity and plan renames as create/destroy. - Region correlation. The WebTest
locationmust correlate with the parent Application Insights component's region. Sourcinglocationfrom the same value that built the component (as in the end-to-end example) avoids a platform rejection. - Two different "timeouts". The provider exposes a scalar
timeout(the test's own response timeout) and atimeoutsCRUD block. This module names the formertest_timeoutand keeps the latter as the universaltimeoutstail, rendered through adynamicblock withtry(..., null)on each field so an unset block adds nothing to the plan. configurationis the probe. The XML defines the request, expected status code, and any validation rules. It is not a secret and must never carry credentials; assert challenge responses (e.g.401) instead of authenticating.- Classic Web Test. This maps to the Azure "Application Insights Classic Web Test". Newer standard availability tests are a separate resource type; if you need that shape, do not expect this resource to model it.
for_eachkey stability. When fanning the module out over a map of endpoints, key on a stable name so removing one entry never re-indexes the others.
| Concern | Secure/sensible default (empty call) | Opt-out (caller must type it) |
|---|---|---|
| Test activation | enabled = true — the test is actively monitored |
set enabled = false |
| Failure resilience | retry_enabled = true — a failed run is retried before alerting |
set retry_enabled = false |
| Probe transport | examples target https:// endpoints |
point configuration at an http:// URL |
| Credentials in the probe | none — assert challenge responses | (not supported; do not embed secrets) |
| Test shape | kind = "ping" — the recommended availability probe |
set kind = "multistep" |
| Cadence | frequency = 300 (5 minutes) |
set 600 or 900 |
Rules of thumb: a boolean that gates monitoring defaults to the active/resilient value; an enum defaults to the recommended member and is enforced with a validation {} block naming the legal values.
terraform init -backend=false
terraform validate
terraform fmt -check- Pin the module with
?ref=v1.0.0insource— never a branch. - This library is plan-only: a human applies from CI after review. Do not run
terraform applyas part of authoring.
The offline proof gate is what this module guarantees without touching a cloud:
| Check | Command | What it proves |
|---|---|---|
| Parse + type | terraform validate |
The typed inputs, validation {} blocks, and resource references are internally consistent — a malformed call fails here, before any API call. |
| Formatting | terraform fmt -check |
Canonical HCL formatting. |
| Provider resolution | terraform init -backend=false |
The azurerm ~> 4.0 pin resolves and the schema loads. |
What only terraform plan/apply against a real subscription can exercise: region correlation with the parent component, the Microsoft.Insights provider registration, and RBAC on the target scope.
$ terraform output
id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-observability/providers/Microsoft.Insights/webtests/wt-storefront-home"
name = "wt-storefront-home"
synthetic_monitor_id = "wt-storefront-home"
application_insights_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-observability/providers/Microsoft.Insights/components/appi-storefront"| Symptom | Cause | Fix |
|---|---|---|
| Plan shows the WebTest being destroyed and recreated after a small edit | A force-new field (name, resource_group_name, location, application_insights_id, kind) changed |
Confirm the change is intended; if only renaming, expect replacement, or use terraform state mv for a pure rename that keeps the same Azure resource. |
frequency/kind rejected at plan time |
Value outside the allowed set | Use frequency ∈ {300, 600, 900} and kind ∈ {ping, multistep}. |
| Apply fails on a location mismatch | WebTest location differs from the parent component's region |
Set location to the same region as the Application Insights component. |
| Apply fails with an authorization error | Caller identity lacks WebTest write permission | Grant Monitoring Contributor at the target resource group scope. |
provider "azurerm" won't initialize |
Missing caller-side features {} block |
Add provider "azurerm" { features {} } to the root module. |
| Test reports failures for a healthy endpoint | Too few geo-locations, or retries off | Add more geo_locations, keep retry_enabled = true, and align the XML Timeout with test_timeout. |
azurerm_application_insights_web_test— provider resource reference.- Availability test location population tags — valid
geo_locationsvalues. - Sibling modules:
terraform-azurerm-application-insights,terraform-azurerm-resource-group,terraform-azurerm-monitor-action-group. - This module's
SCOPE.md— the cross-module contract.
💙 "Infrastructure as Code should be standardized, consistent, and secure."

