I looked at some similar posts, but couldn't find the right one.
I am looking at implementing azurerm_monitor_activity_log_alert using terraform, but it has to be across multiple subscriptions. Problem with it is, each activity log alert has to be in separate resource group, in separate subscription. My first thought was to just create a list of subscriptions, with some keys and use this list to deploy what I need.
Problem with this is, azurerm_monitor_activity_log_alert is not taking subscription ID where to put this resource. Also, Terraform is only applying actions to "current" subscription, and is struggling with working across entire tenant for example (at least I am not aware of a way of doing it).
What I have so far and what I thought it will work.
- List of subscriptions
- Action group
- Root code that will call module
- And module itself
Unfortunately, it is not working for me. It just created X resource groups under one subscriptions, and for everything else it gave us below error message:
Error: creating or updating Monitor Activity Log Alert (Subscription: "***" │ Resource Group Name: "rg-prod-uks-srv-hlth-001" │ Activity Log Alert Name: "sha-prod-uks-hlth-001"): unexpected status 400 (400 Bad Request) with response: {"code":"ScopeIsInvalid","message":"The resources in the scope must be in the same subscription as the rule. Activity ID: xyz."} │ with module.service_health_alerts["sub-id"].azurerm_monitor_activity_log_alert.service_health_alert, │
on .terraform/modules/service_health_alerts/modules/azurerm_monitor_activity_log_alert/1.0.0/main.tf line 15, in resource "azurerm_monitor_activity_log_alert" "service_health_alert": │ 15: resource "azurerm_monitor_activity_log_alert" "service_health_alert" {
Can anyone recommend something how I can implement this that won't be a headache to administrate? In the future, every single app is going to have separate subscription, so I could end up with having 10-30 subscriptions at some point, so trying to automate this somehow. Please keep in mind that I am beginner with terraform.
Code that I have got so far:
# Local Variables: Subscription Number Mapping
locals {
sub_number_map = {
"sub-id-1" = "001" # sub-dev-d
"sub-id-2" = "002" # sub-prod-c
"sub-id-3" = "003" # sub-prod-d
and so on...
}
}
module "service_health_alerts" {
for_each = local.sub_number_map
source = "git::/modules/azurerm_monitor_activity_log_alert/1.0.0"
subscription_id = each.key
subscription_number = each.value
resource_group_name = "rg-prod-${each.value}"
action_group_id = module.action-group.id
tags = module.tags.tags
depends_on = [xyz]
}
Module file:
resource "azurerm_resource_group" "resource_group" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_monitor_activity_log_alert" "service_health_alert" {
name = "sha-prod-uks-hlth-${var.subscription_number}"
resource_group_name = azurerm_resource_group.resource_group.name
location = "global"
scopes = ["/subscriptions/${var.subscription_id}"]
description = "Alerts when Azure Service Health reports an issue affecting our resources"
criteria {
category = "ServiceHealth"
operation_name = "Microsoft.ResourceHealth/healthevent/Activated/action"
service_health {
events = ["Incident", "Maintenance"]
locations = ["xyz", "zyx"]
}
}
action {
action_group_id = var.action_group_id
}
tags = var.tags
}
I looked at some similar posts, but couldn't find the right one.
I am looking at implementing azurerm_monitor_activity_log_alert using terraform, but it has to be across multiple subscriptions. Problem with it is, each activity log alert has to be in separate resource group, in separate subscription. My first thought was to just create a list of subscriptions, with some keys and use this list to deploy what I need.
Problem with this is, azurerm_monitor_activity_log_alert is not taking subscription ID where to put this resource. Also, Terraform is only applying actions to "current" subscription, and is struggling with working across entire tenant for example (at least I am not aware of a way of doing it).
What I have so far and what I thought it will work.
- List of subscriptions
- Action group
- Root code that will call module
- And module itself
Unfortunately, it is not working for me. It just created X resource groups under one subscriptions, and for everything else it gave us below error message:
Error: creating or updating Monitor Activity Log Alert (Subscription: "***" │ Resource Group Name: "rg-prod-uks-srv-hlth-001" │ Activity Log Alert Name: "sha-prod-uks-hlth-001"): unexpected status 400 (400 Bad Request) with response: {"code":"ScopeIsInvalid","message":"The resources in the scope must be in the same subscription as the rule. Activity ID: xyz."} │ with module.service_health_alerts["sub-id"].azurerm_monitor_activity_log_alert.service_health_alert, │
on .terraform/modules/service_health_alerts/modules/azurerm_monitor_activity_log_alert/1.0.0/main.tf line 15, in resource "azurerm_monitor_activity_log_alert" "service_health_alert": │ 15: resource "azurerm_monitor_activity_log_alert" "service_health_alert" {
Can anyone recommend something how I can implement this that won't be a headache to administrate? In the future, every single app is going to have separate subscription, so I could end up with having 10-30 subscriptions at some point, so trying to automate this somehow. Please keep in mind that I am beginner with terraform.
Code that I have got so far:
# Local Variables: Subscription Number Mapping
locals {
sub_number_map = {
"sub-id-1" = "001" # sub-dev-d
"sub-id-2" = "002" # sub-prod-c
"sub-id-3" = "003" # sub-prod-d
and so on...
}
}
module "service_health_alerts" {
for_each = local.sub_number_map
source = "git::/modules/azurerm_monitor_activity_log_alert/1.0.0"
subscription_id = each.key
subscription_number = each.value
resource_group_name = "rg-prod-${each.value}"
action_group_id = module.action-group.id
tags = module.tags.tags
depends_on = [xyz]
}
Module file:
resource "azurerm_resource_group" "resource_group" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_monitor_activity_log_alert" "service_health_alert" {
name = "sha-prod-uks-hlth-${var.subscription_number}"
resource_group_name = azurerm_resource_group.resource_group.name
location = "global"
scopes = ["/subscriptions/${var.subscription_id}"]
description = "Alerts when Azure Service Health reports an issue affecting our resources"
criteria {
category = "ServiceHealth"
operation_name = "Microsoft.ResourceHealth/healthevent/Activated/action"
service_health {
events = ["Incident", "Maintenance"]
locations = ["xyz", "zyx"]
}
}
action {
action_group_id = var.action_group_id
}
tags = var.tags
}
Share
Improve this question
edited Mar 10 at 16:07
Marko E
18.4k4 gold badges26 silver badges35 bronze badges
asked Mar 10 at 15:47
Daniel TDaniel T
12 bronze badges
2
- I'm not really an Azure expert, but do you have the subscriptions defined? It seems like that's the issue: registry.terraform.io/providers/hashicorp/azurerm/latest/docs/…. – Marko E Commented Mar 10 at 16:16
- Yes, we have entire Azure Landing Zone implemented for migration from on-prem. Problem is not with defining subscription here, but the fact that there is more than one, two, even five subscriptions - and it will be more. – Daniel T Commented Mar 10 at 16:53
1 Answer
Reset to default 1Follow the approach below to create resources in multiple subscriptions using Terraform. You can specify the subscription IDs in the provider file.
Note: Make sure you have access to all the subscriptions to deploy the resources.
Here is my folder structure.
providers.tf
provider "azurerm" {
alias = "sub1"
subscription_id = "8332bxxx507-d7e60e5f09a9"
features {}
}
provider "azurerm" {
alias = "sub2"
subscription_id = "98bccxxxx83d6-78dfd797ff89"
features {}
}
main.tf
module "monitoring_alerts_sub1" {
source = "./modules/monitoring_alert"
subscription_id = "8332xxxx-d7e60e5f09a9"
resource_group_name = "rg-monitoring-001"
location = "West Europe"
action_group_name = "action-group-001"
storage_account_name = "examplesa001"
providers = {
azurerm = azurerm.sub1
}
}
module "monitoring_alerts_sub2" {
source = "./modules/monitoring_alert"
subscription_id = "98bccxxx3d6-78dfd797ff89"
resource_group_name = "rg-monitoring-002"
location = "West Europe"
action_group_name = "action-group-002"
storage_account_name = "examplesa002"
providers = {
azurerm = azurerm.sub2
}
}
terraform.tfvars
location = "West Europe"
\modules\monitoring_alert
main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
}
}
resource "azurerm_resource_group" "example" {
name = var.resource_group_name
location = var.location
}
resource "azurerm_monitor_action_group" "main" {
name = var.action_group_name
resource_group_name = azurerm_resource_group.example.name
short_name = "p0action"
webhook_receiver {
name = "callmyapi"
service_uri = "http://example/alert"
}
}
resource "azurerm_storage_account" "to_monitor" {
name = var.storage_account_name
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "GRS"
}
resource "azurerm_monitor_activity_log_alert" "main" {
name = "example-activitylogalert-${var.subscription_id}"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
scopes = ["/subscriptions/${var.subscription_id}"]
description = "This alert monitors storage account updates."
criteria {
resource_id = azurerm_storage_account.to_monitor.id
operation_name = "Microsoft.Storage/storageAccounts/write"
category = "Recommendation"
}
action {
action_group_id = azurerm_monitor_action_group.main.id
webhook_properties = {
from = "terraform"
}
}
}
\modules\monitoring_alert
variables.tf
variable "subscription_id" {}
variable "resource_group_name" {}
variable "location" {}
variable "action_group_name" {}
variable "storage_account_name" {}
Terraform apply
Output: