Reputation: 21
Using Terraform, I want to deny the creation of savings plans outside of the singular Prod subscription and get an email whenever an attempt is made. We have more than 10 subscriptions in the tenant in different management groups.
Here's what I have in mind:
Here's what I have so far:
FYI I got the savings plan type from Azure Documentation. Not a 100% sure that it is correct, feel free to point out the correct one.
A custom policy to restrict Savings Plan creation:
resource "azurerm_policy_definition" "restrict_savings_plan" {
name = "restrict-savings-plan-creation"
policy_type = "Custom"
mode = "All"
display_name = "Restrict Savings Plan Creation to Prod Subscription"
policy_rule = <<POLICY
{
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Billing billingAccounts/savingsPlanOrders/savingsPlans"//Not sure if this is correct
},
{
"value": "[subscription().Id]", //Kinda iffy about this
"notEquals": "Prod-subscription-id"
}
]
},
"then": {
"effect": "deny"
}
}
POLICY
}
Diagnostic settings to capture Activity Logs in Non-Prod for testing:
resource "azurerm_monitor_diagnostic_setting" "Non_Prod_subscription" {
name = "Non_Prod-log-analytics"
target_resource_id = "/subscriptions/Non_Prod_subscription_id"
log_analytics_workspace_id = azurerm_log_analytics_workspace.example.id
logs {
category = "Administrative"
enabled = true
}
}
An Action Group for email notifications:
resource "azurerm_monitor_action_group" "Non_Prod_email_action_group" {
name = "email-action-group"
resource_group_name = "Non_Prod-resource-group"
short_name = "emailgroup"
email_receiver {
name = "AdminEmail"
email_address = "[email protected]"
use_common_alert_schema = true
}
}
Scheduled Query Alert to pull policy denials:
resource "azurerm_monitor_scheduled_query_rules_alert" "SavingsPlan_policy_violation_alert" {
name = "SavingsPlanPolicyViolationAlert"
resource_group_name = "Non_prodRG"
location = "eastus"
data_source_id = azurerm_monitor_diagnostic_setting.Non_Prod_subscription.log_analytics_workspace_id
description = "Alert for policy violations across all subscriptions"
enabled = true
query = <<-QUERY
AzureActivity
| where Category == "Policy"
| where OperationNameValue == "Microsoft.Authorization/policies/audit/action"
| where ActivityStatusValue == "Failed"
| where Properties contains "Request disallowed by policy"
| summarize Count = count() by SubscriptionId
QUERY
severity = 2
frequency = "60"
time_window = "60"
trigger {
operator = "GreaterThan"
threshold = 1
}
action {
action_group = [azurerm_monitor_action_group.Non_Prod_email_action_group.id]
email_subject = "Alert: Savings Plan Policy Violation Detected"
}
}
Currently, savings plan creations are not being denied nor am I getting emails. I would appreciate it if someone could provide feedback on this code.
Upvotes: 0
Views: 65
Reputation: 8018
The given terraform code and structure both looks good according to the requirement. Few adjustments are done to your code such as resource type for billing provider and also related to the monitor rule's as given below.
provider "azurerm"{
features{}
subscription_id = "b4xxxx14"
}
resource "azurerm_policy_definition" "restrict_savings_plan" {
name = "restrict-savings-plan-creation"
policy_type = "Custom"
mode = "All"
display_name = "Restrict Savings Plan Creation to Prod Subscription"
policy_rule = <<POLICY
{
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Billing/billingAccounts/savingsPlanOrders"
},
{
"value": "f7bxxxx32b014",
"notEquals": "Prod-subscription-id"
}
]
},
"then": {
"effect": "deny"
}
}
POLICY
}
data "azurerm_log_analytics_workspace" "example"{
name = "Customlogsws"
resource_group_name = "Jahnavi"
}
resource "azurerm_monitor_diagnostic_setting" "Non_Prod_subscription" {
name = "Non_Prod-log-analytics"
target_resource_id = "/subscriptions/xxxxx" #Provide Nonproduction subscriptionID here
log_analytics_workspace_id = data.azurerm_log_analytics_workspace.example.id
enabled_log {
category = "Administrative"
}
}
resource "azurerm_monitor_action_group" "Non_Prod_email_action_group" {
name = "email-action-group"
resource_group_name = "Jahnavi"
short_name = "emailgroup"
email_receiver {
name = "AdminEmail"
email_address = "[email protected]"
use_common_alert_schema = true
}
}
resource "azurerm_monitor_scheduled_query_rules_alert" "SavingsPlan_policy_violation_alert" {
name = "SavingsPlanPolicyViolationAlert"
resource_group_name = "Jahnavi"
location = "WestUS"
data_source_id = azurerm_monitor_diagnostic_setting.Non_Prod_subscription.log_analytics_workspace_id
description = "Alert for policy violations across all subscriptions"
enabled = true
query = <<-QUERY
AzureActivity
| where Category == "Policy"
| where OperationNameValue == "Microsoft.Authorization/policies/audit/action"
| where ActivityStatusValue == "Failed"
| where Properties contains "Request disallowed by policy"
| summarize Count = count() by SubscriptionId
QUERY
severity = 2
frequency = "60"
time_window = "60"
trigger {
operator = "GreaterThan"
threshold = 1
}
action {
action_group = [azurerm_monitor_action_group.Non_Prod_email_action_group.id]
email_subject = "Alert: Savings Plan Policy Violation Detected"
}
}
Output:
Upvotes: 0