Setup resource health alert for multiple storage accounts - terraform

So the idea is to create resource health alert for multiple storage accounts using terraform. It's fairly simple for one storage account as one would pass the value
output "id" {
description = "Id of the storage account created."
value = azurerm_storage_account.storage.id
}
to the resource_id or hardcode the resource id with the resource actual id. But my ask here is how I can setup one single alert block for all the storage accounts provisioned by the terraform. I have been trying to use the above data block but the name variable would take only strings. Please provide a sample example as to how you would do it.
locals {
activity_log_alerts = {
resource_health_alerts= {
environment = var.environment
resource_group_name = var.rgp
enabled = "true"
** scopes = module.main.storage_account_name["storage_name"] **
alert_name = “Resource health alert for storage accounts”
description = format(“The state of the azure resource is unknown”}
category = "ResourceHealth"
level = "Critical"
operation_name = null
resource_health = [
{
current = ["Unknown"]
previous = ["Available"]
reason = ["PlatformInitiated"]
}
]
The error I received is this: Error: Null value found in list
scopes = tolist([var.resource_id])
UPDATE: Another Approach With this approach I was hoping to get all the resource under the same RG and subscription but got the same error
data "azurerm_subscription" "current" {
subscription_id = var.subscription_id
}
locals {
activity_log_alerts = {
resource_health_alerts= {
environment = var.environment
resource_group_name = var.rgp
enabled = "true"
scopes = [data.azurerm_subscription.current.id]
alert_name = “Resource health alert for storage accounts”
description = format(“The state of the azure resource is unknown”}
category = "ResourceHealth"
level = "Critical"
operation_name = null
resource_health = [
{
current = ["Unknown"]
previous = ["Available"]
reason = ["PlatformInitiated"]
}
]
The error I received is this: Error: Null value found in list
scopes = tolist([var.resource_id])

Related

Azure - restore CosmosDB account using Terraform

I am trying to create a new Azure CosmosDB account in terraform account using:
create_mode = "Restore"
Basically I am trying to restore from an existing DB, and the code needs another input attribute, of the source DB:
"source_cosmosdb_account_id" = "/subscriptions/33f91226-e87e-4cdf67a1dae4e/providers/Microsoft.DocumentDB/locations/westeu/restorableDatabaseAccounts/test-source-db-name"
I am following the format indicated by the docs:
The example is /subscriptions/{subscriptionId}/providers/Microsoft.DocumentDB/locations/{location}/restorableDatabaseAccounts/{restorableDatabaseAccountName}
However when I apply the code, I get the following error:
Code="BadRequest" Message="Failed to parse uri
/subscriptions/33f91226-e87e-4ca1dae4e/providers/Microsoft.DocumentDB/locations/westeu/restorableDatabaseAccounts/test-source-db-name
The issue seems to be the way I write the location inside the source ID, but I can't find any relevant info on how is the correct way.
I would really appreciate an example of source_cosmosdb_account_id if anyone did this successfully in terraform.
Thanks
Configuration used:
backup = [
{
type = "Continuous"
interval_in_minutes = null
retention_in_hours = null
storage_redundancy = null
}
]
restore = [
{
"source_cosmosdb_account_id" = "/subscriptions/33f6-e87e-4cdf-9480-7b1dae/providers/Microsoft.DocumentDB/locations/westeu/restorableDatabaseAccounts/test-source-db-name"
"restore_timestamp_in_utc" = "2022-11-18T14:00:00.00Z"
"database" = []
}
]
I've recently faced same issue and discovered that terraform documentation is outdated.
You need to have create_mode = "Restore"
Backup should be configured like this
backup = [
{
type = "Continuous"
interval_in_minutes = 0
retention_in_hours = 0
storage_redundancy = "Geo"
}
]
Format /subscriptions/{subscriptionId}/providers/Microsoft.DocumentDB/locations/{location}/restorableDatabaseAccounts/{restorableDatabaseAccountName}
is not correct
Try with /subscriptions/{subscriptionId}/providers/Microsoft.DocumentDB/locations/{location}/restorableDatabaseAccounts/{**instanceId**}
You can find cosmos instanceId in json view
I tried to reproduce the issue in my environment.
I got the same error , Failed to parse uri /subscriptions/xxxx/providers/Microsoft.DocumentDB/locations/westeu/restorableDatabaseAccounts/test-source-db-name
with:
resource "azurerm_cosmosdb_account" "db" {
name = "tfex-cosmos-db-31960"
location = "westus2"
resource_group_name = data.azurerm_resource_group.example.name
offer_type = "Standard"
kind = "MongoDB"
create_mode = "Restore"
restore { source_cosmosdb_account_id=data.azurerm_cosmosdb_restorable_database_accounts.example.id
source_cosmosdb_account_id="/subscriptions/xxxxx/providers/Microsoft.DocumentDB/locations/westeurope/restorableDatabaseAccounts/tfex-cosmos-db-31960?api-version=2022-05-15"
restore_timestamp_in_utc="2022-11-25T22:06:00Z"
}
...
}
If I tried with westeu as the location you gave , in my case I am getting below error , as it must be westeurope as supported by azure .
Also please check
Note from cosmosdb_account | terraform registry: Database account
with Continuous type (or deleted account in last 30 days) are the
restorable accounts and there cannot be Create/Update/Delete
operations on the restorable database accounts. They can only be read and be retrieved by azurerm_cosmosdb_restorable_database_accounts.
Restore the cosmos db account is supported in azure portal , powershell,Azure CLI , ARM template as in restore-account-continuous-backup | Microsoft Learn
With azurerm provider , i can only read it through below with continuous backup type :
resource "azurerm_cosmosdb_account" "db" {
name = "tfex-cosmos-db-31960"
location = "westus2"
resource_group_name = data.azurerm_resource_group.example.name
offer_type = "Standard"
kind = "MongoDB"
enable_automatic_failover = true
capabilities {
name = "EnableAggregationPipeline"
}
capabilities {
name = "mongoEnableDocLevelTTL"
}
capabilities {
name = "MongoDBv3.4"
}
capabilities {
name = "EnableMongo"
}
consistency_policy {
consistency_level = "BoundedStaleness"
max_interval_in_seconds = 300
max_staleness_prefix = 100000
}
geo_location {
location = "eastus"
failover_priority = 0
}
backup{
type = "Continuous"
//interval_in_minutes=60
}
data "azurerm_cosmosdb_restorable_database_accounts" "example" {
name = azurerm_cosmosdb_account.db.name
location = "West Europe"
}
output "name" {
value=data.azurerm_cosmosdb_restorable_database_accounts.example.name
}
output "id" {
value = data.azurerm_cosmosdb_restorable_database_accounts.example.id
}
Output:
Try checking the same with azapi_resource block in terraform :
as it requires parameters like api version , source account id which has to come from cosmosdb_restorable_database_accounts
list and must form uri like https://management.azure.com/subscriptions/subid/providers/Microsoft.DocumentDB/locations/West US/restorableDatabaseAccounts/d9b2xxx10d?api-version=2022-05-15 which is compatible in api resource.

Azure Activity Log Alerts are not working

I have created an Activity Log Alert in Azure using the following Terraform Code
// We need to define the action group for Security Alerts
resource "azurerm_monitor_action_group" "monitor_action_group_soc" {
name = "sec-alert"
resource_group_name = data.azurerm_resource_group.tenant-global.name
short_name = "sec-alert"
email_receiver {
name = "sendtoAdmin"
email_address = var.email_address
use_common_alert_schema = true
}
}
data "azurerm_monitor_action_group" "monitor_action_group_soc" {
name = "sec-alert"
resource_group_name = var.tenant-global-rg
depends_on = [
azurerm_monitor_action_group.monitor_action_group_soc
]
}
// Monitor Activity Log and Alert
resource "azurerm_monitor_activity_log_alert" "activity_log_alert_cu_security_group" {
name = "Activity Log Alert for Create or Update Security Group"
resource_group_name = data.azurerm_resource_group.ipz12-dat-np-mgmt-rg.name
scopes = [data.azurerm_subscription.current.id]
description = "Monitoring for Create or Update Network Security Group events gives insight into network access changes and may reduce the time it takes to detect suspicious activity"
criteria {
category = "Security"
operation_name = "Microsoft.Network/networkSecurityGroups/write"
}
action {
action_group_id = data.azurerm_monitor_action_group.monitor_action_group_soc.id
}
}
I have created the Network Security Group, added a Rule, deleted the Rule and finally deleted the Network Security Group but I didn't receive any Alerts.
Azure Activity Log Alerts are not working:
These are the modifications I made to your code to achieve the expected result.
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "<resourcegroup>"{
name = "<resourcegroup>"
location = "Central US"
}
resource "azurerm_monitor_action_group" "<actiongroup>" {
name = "sec-alert"
resource_group_name = "<resourcegroup>"
short_name = "sec-alert"
email_receiver {
name = "xxxxx"
email_address = "xxxxxxx#gmail.com"
use_common_alert_schema = true
}
}
data "azurerm_monitor_action_group" "<actiongroup>" {
name = "sec-alert"
resource_group_name = "<resourcegroup>"
depends_on = [
azurerm_monitor_action_group.<actiongroup>
]
}
resource "azurerm_monitor_activity_log_alert" "azurerm_monitor_activity_log_alert_securitygroup" {
name = "Activity Log Alert for Create or Update Security Group"
resource_group_name = "<resourcegroup>"
scopes = [data.azurerm_subscription.current.id] #My scope is /subscriptions/<subscriptionID>/resourceGroups/<resourcegroup>/providers/Microsoft.Network/networkSecurityGroups/<NetworkSecurityGroup>
description = "Monitoring for Create or Update Network Security Group events gives insight into network access changes and may reduce the time it takes to detect suspicious activity"
criteria {
category = "Security"
operation_name = "Microsoft.Network/networkSecurityGroups/write"
}
action {
action_group_id = data.azurerm_monitor_action_group.<actiongroup>.id
}
}
Created Security alert by running "terraform apply" in AzCLI :
Received a mail once it is added to the Network Security Group:

Unable to declare resource_type variable and event status in Terraform for azure resource health alert.showing conflicting error Msg

Trying to add the Event status in Resource health block (not accepting it)
Tried adding the resource_type variable as mentioned in terraform documentation to
select the resource types to get this alert apply on.but its omitting
conflicting error msg is
"criteria.. resource health": conflicts with criteria.o.resource type
resource "azurerm_monitor_activity_log_alert" "reshealthalert" {
name = "resourceHealthFromMain "
resource_group_name = azurerm_resource_group.rg.name
scopes = ["/subscriptions/${data.azurerm_subscription.current.subscription_id}"]
description = var.monitor_activity_log_alert_description
criteria {
category = var.criteria_resource_health
# resource_type = "Storage account"
resource_health {
current = var.current_resource_status
previous = var.previous_resource_status
# events = var.resource_health_events
reason = var.reason_type
#event_status = var.resource_health_events
} }
action {
action_group_id = azurerm_monitor_action_group.email_alert.id } }
Please check the below terraform code.
Please make sure to give resource_type before category and give resourceId
format of storage account in the form resource_type= "Microsoft.Storage/storageAccounts"
main.tf
resource "azurerm_monitor_activity_log_alert" "reshealthalert" {
name = "ka-resource-Health "
resource_group_name = azurerm_resource_group.example.name
scopes = ["/subscriptions/xxxxxxxxxx"]
description = "This alert will monitor a specific storage account updates."
resource_type= "Microsoft.Storage/storageAccounts"
#resource_type = "Storage account"
criteria {
category = var.criteria_resource_health
...
}
Reference:
azurerm_monitor_activity_log_alert | Resources | hashicorp/azurerm | Terraform Registry

Terraform order of ip filter rules for IoT Hub

I want to deploy multiple azure cloud resources with terraform. My problem is with the terraform script for an azure IoT Hub, exspecially the ip restriction rules. According to the documentation I can do something like this
resource "azurerm_iothub" "iothubname" {
name = "somename"
resource_group_name = azurerm_resource_group.someresourcegroup
location = azurerm_resource_group.somelocation
sku {
name = "B2"
capacity = "2"
}
fallback_route {
enabled = true
}
ip_filter_rule {
action = "Accept"
ip_mask ="some_ip_range_1"
name = "some_name_1"
}
ip_filter_rule {
action = "Accept"
ip_mask ="some_ip_range_2"
name = "some_name_2" }
ip_filter_rule {
action = "Accept"
ip_mask ="some_ip_range_3"
name = "some_name_3"
}
ip_filter_rule {
action = "Reject"
ip_mask ="0.0.0.0/0"
name = "everything_else"
}
}
Everything works fine, ecept that the ordering of the ip rules is not the same as above and in my case I definitely want the last rule to be the the one with the lowest priority on azure. Azure IoT hub applies the filter rules in order.
How can I enforce a certain ordering of ip filter?
You can try to use dynamic blocks
https://www.terraform.io/docs/configuration/expressions/dynamic-blocks.html
File main.tf
resource "azurerm_iothub" "iothubname" {
name = "somename"
resource_group_name = azurerm_resource_group.someresourcegroup
location = azurerm_resource_group.somelocation
sku {
name = "B2"
capacity = "2"
}
fallback_route {
enabled = true
}
dynamic "ip_filter_rule" {
for_each = var.ip_filter_rule_list
content {
action = ip_filter_rule.value.action
ip_mask = ip_filter_rule.value.ip_mask
name = ip_filter_rule.value.name
}
}
}
File variables.tf
variable "ip_filter_rule_list" {
type = list
default = []
}
Update
Bug is fixed in terraform provider azurerm v2.57.0
https://github.com/terraform-providers/terraform-provider-azurerm/pull/11390

How to skip/ignore specific module in terraform if var is null or empty

Is there any way to skip the terraform block/file if defined variable is empty or null. Instead of throwing error.
I have created tow terraform script for azure.
For azure automation creation, runbook creation.
For event grid creation.
After executing the first step I have to generate a webhook URL manually (there no such automation support for webhook generation). after generating of webhook URL I need to define it in second resource. If I defined empty/null or invalid URL then terraform throw the error.
below is the terraform code.
data "local_file" "runbook_script" {
filename = "${path.module}/envent-grid-runbook.ps1"
}
resource "azurerm_automation_runbook" "runbook" {
name = "event-gird-notification"
location = var.location
resource_group_name = var.resource_group_name
automation_account_name = azurerm_automation_account.CreateAutomation.name
log_verbose = true
log_progress = true
description = "This runbook is creted for event grid notification"
runbook_type = "PowerShell"
content = data.local_file.runbook_script.content
publish_content_link {
uri = ""
}
}
resource "azurerm_eventgrid_event_subscription" "key-vault" {
name = "test"
scope = "/subscriptions/xxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxx/name"
topic_name = "/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxx/vault"
webhook_endpoint {
url = var.webhook_url
}
included_event_types = [
"Microsoft.KeyVault.SecretNewVersionCreated",
"Microsoft.KeyVault.SecretNearExpiry",
"Microsoft.KeyVault.SecretExpired"
]
event_delivery_schema = "EventGridSchema"
}
If I defined null/empty var for webhook ULR variable. then getting below error.
Error: "webhook_endpoint.0.url": required field is not set
I have created a Jenkins job, where all terraform code to run in a single job. if the code fails, then entire job is getting failed. That's why looking for a solution to skip the specific block/file if var is empty or null.
I assume that you want to make entire azurerm_eventgrid_event_subscription resource optional, based on var.webhook_url you can use count.
For example:
resource "azurerm_eventgrid_event_subscription" "key-vault" {
count = var.webhook_url == "" ? 0 : 1
name = "test"
scope = "/subscriptions/xxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxx/name"
topic_name = "/subscriptions/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxx/vault"
webhook_endpoint" {
url = var.webhook_url
}
included_event_types = [
"Microsoft.KeyVault.SecretNewVersionCreated",
"Microsoft.KeyVault.SecretNearExpiry",
"Microsoft.KeyVault.SecretExpired"
]
event_delivery_schema = "EventGridSchema"
}
In the above example, you may need to adjust the condition based on what values var.webhook_url can actually have to be consider correct or incorrect.

Resources