I am trying to create an azure policy with terraform to add tags to resources. I want all the resources to inherit the resource group tags.
I've been following documentations and examples here and there but I can't figure out how to have the tags being assigned on the resources.
I think I am close, I do not want to write the tags in every single resources this is not sustainable.
My code is separated in 3 different files:
main.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.37.0"
}
azuread = {
source = "hashicorp/azuread"
version = "2.31.0"
}
}
}
provider "azurerm" {
subscription_id = var.azure_subscription_id
tenant_id = var.azure_tenant_id
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
#create azure resource group
resource "azurerm_resource_group" "rg" {
name = var.azure_rg_name
location = var.azure_resource_group_location
tags = {
costcenter = var.azure_costcenter
projectcode = var.azure_project_code
environment = var.azure_env_code
client = var.azure_client_code
}
}
#Create azure storage account
resource "azurerm_storage_account" "sa" {
name = lower("${var.azure_project_code}${var.azure_env_code}sa01")
resource_group_name = azurerm_resource_group.rg.name
location = var.azure_resource_group_location
account_tier = "Standard"
account_replication_type = "LRS"
}
#Create container in previously created sa
resource "azurerm_storage_container" "ctnr2" {
name = lower("${var.azure_project_code}${var.azure_env_code}tfstate01")
storage_account_name = azurerm_storage_account.sa.name
container_access_type = "private"
}
#create azure policy definition
resource "azurerm_policy_definition" "az_pol_def" {
name = "Append a tag and its value to resources"
policy_type = "Custom"
mode = "Indexed"
display_name = "Append a tag and its value to resources"
metadata = jsonencode({
"version" : "1.0.1",
"category" : "Tags "
}
)
policy_rule = jsonencode({
"if": {
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
},
"then": {
"effect": "append",
"details": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"value": "[parameters('tagValue')]"
}
]
}
})
}
#assign azure policy created previously
resource "azurerm_resource_group_policy_assignment" "az_pol_assign" {
name = "Append a tag and its value to resources"
resource_group_id = azurerm_resource_group.rg.id
policy_definition_id = azurerm_policy_definition.az_pol_def.id
parameters = jsonencode({
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag Name",
"description": "Name of the tag, such as 'environment'"
}
},
"tagValue": {
"type": "String",
"metadata": {
"displayName": "Tag Value",
"description": "Value of the tag, such as 'production'"
}
}
},
})
}
variable.tf
variable "azure_resource_group_location" {
default = "west europe"
description = "Location of the resource group."
}
variable "azure_subscription_id" {
type = string
description = "Azure Subscription Id"
}
variable "azure_tenant_id" {
type = string
description = "Azure Tenant Id"
}
variable "azure_rg_name" {
type = string
description = "Azure Resource Group Name"
}
variable "azure_costcenter" {
type = string
description = "Azure Tag Cost Center"
}
variable "azure_client_code" {
type = string
description = "Azure Tag Client"
}
variable "azure_project_code" {
type = string
description = "Azure Tag Project Code"
}
variable "azure_env_code" {
type = string
description = "Azure Tag Environment Code"
}
resource_group_name.tfvars
#Azure tenant id
azure_tenant_id ="********-****-****-****-************"
#Azure subscription
azure_subscription_id = "********-****-****-****-************"
#Azure resource group location
azure_resource_group_location = "west europe"
#Azure RG name
azure_rg_name = "resource_group_name"
#Azure tag
azure_costcenter = "missions"
#Azure tag project code
azure_project_code = "test_project"
#Azure tag client code
azure_client_code = "leanne"
#Environement tag code :
azure_env_code="dev"
I understand that "parameter_values" should be used for my tags, but I'm not sure how?
Here's an error message which might help.
Any help would be much appreciated.
Thanks in advance !
You declared the policy parameters in the policy assignment (az_pol_assign
).
Instead you should declare the parameters in the policy definition (az_pol_def
).
In your policy assignment you can then set the values that you want to pass as parameters:
#assign azure policy created previously
resource "azurerm_resource_group_policy_assignment" "az_pol_assign" {
name = "Append a tag and its value to resources"
resource_group_id = azurerm_resource_group.rg.id
policy_definition_id = azurerm_policy_definition.az_pol_def.id
parameters = jsonencode({
tagName = {
value = "environment"
},
tagValue = {
value = "production"
}
})
}
NOTE When you use jsonencode()
you don't need to use plain JSON, you can use the simpler HashiCorp configuration language (HCL) syntax as I did in my example.