azureazure-devopsterraform-provider-azureazure-cost-calculation

Azure Cost Management - Budget Alert Script


I have a request to setup budget alert on our resource groups located in different subscriptions. I am trying to decide if it make sense to do it thru PowerShell or Terraform to automate this process. My thinking is that management would update a .csv file quarterly with the budget amount and alert threshold for each of the RGs they want to set alerts form. The .csv will have the following fields/columns:

SubscriptionName, SubscriptionId, ResourcegGropu, StartDate, EndDate,TimeGrain,ContactEmails,Contact,BudgetAmount,budgetName, alertLevels

Any suggests? Thanks


Solution

  • Using Terraform to perform the same operation on different Subscriptions will be difficult as for_each is not supported in provider blocks as shown in below image , so you will have to manually set up the provider blocks for all the subscriptions.

    locals{
        budget=csvdecode(file("C:/Users/xxxxx/terraform/budgetalert/Budget.csv"))
    }
    provider "azurerm"{
        for_each ={ for i , user in local.budget : i => budget }
        features{}
        subscription_id = each.value.SubscriptionId
        alias = each.value.SubscriptionName
    }
    

    enter image description here

    As a solution to do this from terraform you can create different .csv files for different subscriptions and call them in different resource provider blocks like below :

    provider "azurerm"{
        features {}
        subscription_id = "b83-----xxxxxxxxxxx-xxxx-xxxxx----23f"
    }
    provider "azurerm" {
        features {}
      subscription_id = "948--------x--xxxxxxxxxxxxx-xxxxxxx-59b"
      alias = "Subscription2"
    }
    
    locals{
        budgetsub1=csvdecode(file("C:/Users/xxxx/terraform/budgetalert/Budget.csv"))
        budgetsub2=csvdecode(file("C:/Users/xxxx/terraform/budgetalert/budgetsub2.csv"))
    }
    output "local" {
      value=local.budgetsub1
    }
    output "local1" {
      value = local.budgetsub2
    }
    
    data "azurerm_resource_group" "rg_subscription1"{
        for_each = { for i , budget in local.budgetsub1 : i => budget }
        name= each.value.ResourceGroup
    }
    data "azurerm_resource_group" "rg_subscription2"{
        provider = azurerm.Subscription2
        for_each = { for i , budget in local.budgetsub2 : i => budget }
        name= each.value.ResourceGroup
    }
    
    resource "azurerm_consumption_budget_resource_group" "rg_budget_subscription1" {
        for_each = { for i , budget in local.budgetsub1 : i => budget }
      name       = each.value.budgetName
      amount     = each.value.BudgetAmount
      time_grain = each.value.TimeGrain
      time_period {
        start_date = each.value.StartDate
        end_date  = each.value.EndDate
      }
      resource_group_id = data.azurerm_resource_group.rg_subscription1[each.key].id
      notification {
          enabled = true
        threshold      = 80
        operator       = "GreaterThanOrEqualTo"
        contact_emails = ["${each.value.ContactEmails}"]
      }
      lifecycle {
        ignore_changes = [
          time_period
        ]
      }
    }
    resource "azurerm_consumption_budget_resource_group" "rg_budget_subscription2" {
        provider = azurerm.Subscription2
        for_each = { for i , budget in local.budgetsub2 : i => budget }
      name       = each.value.budgetName
      amount     = each.value.BudgetAmount
      time_grain = each.value.TimeGrain
      time_period {
        start_date = each.value.StartDate
        end_date  = each.value.EndDate
      }
      resource_group_id = data.azurerm_resource_group.rg_subscription2[each.key].id
      notification {
          enabled = true
        threshold      = 80
        operator       = "GreaterThanOrEqualTo"
        contact_emails = ["${each.value.ContactEmails}"]
      }
      lifecycle {
        ignore_changes = [
          time_period
        ]
      }
    }
    

    Output:

    enter image description here

    enter image description here enter image description here