I am trying to use terraform to manage policy assigned to a subscription. I am getting an error but I don't understand what the problem is. I appreciate any help or hint. Thank you.
policy.tf
provider "azurerm" {
features {}
subscription_id = "00000000-a0b0-0000-0a00-0f000000000"
}
resource "azurerm_policy_definition" "vm_sku_policy" {
name = "OnlyAllowHostingCROSImages"
policy_type = "Custom"
mode = "All"
display_name = "Limit allowed VM SKUs"
description = "This policy restricts the VM SKUs that can be deployed in the subscription."
policy_rule = <<POLICY_RULE
{
"if": {
"allOf": [
{
"field": "type",
"in": [
"Microsoft.Compute/virtualMachines",
"Microsoft.Compute/virtualMachineScaleSets"
]
},
{
"not": {
"anyOf": [
{
"field": "Microsoft.Compute/imageSku",
"like": "*-Datacenter-gs"
},
{
"field": "Microsoft.Compute/imageSku",
"like": "2022-Datacenter*"
},
{
"allOf": [
{
"field": "Microsoft.Compute/imagePublisher",
"equals": "Canonical"
},
{
"field": "Microsoft.Compute/imageOffer",
"in": [
"0001-com-ubuntu-server-focal",
"0001-com-ubuntu-server-jammy",
"UbuntuServer"
]
},
{
"field": "Microsoft.Compute/imageSku",
"in": [
"20_04-lts-gen2",
"20_04-lts-cvm",
"22_04-lts-cvm",
"20_04-lts",
"22_04-lts"
]
}
]
}
]
}
}
]
},
"then": {
"effect": "deny"
}
}
POLICY_RULE
}
resource "azurerm_resource_group" "vm_sku_policy" {
name = "test-resources"
location = "West Europe"
}
resource "azurerm_policy_assignment" "vm_sku_policy" {
name = "limit-vm-sku-assignment"
policy_definition_id = azurerm_policy_definition.vm_sku_policy.id
scope = "/subscriptions/00000000-a0b0-0000-0a00-0f000000000"
display_name = azurerm_policy_definition.vm_sku_policy.display_name
description = azurerm_policy_definition.vm_sku_policy.description
}
error:
PS C:\WindowsFabric\policy> terraform plan
╷
│ Error: Invalid resource type
│
│ on amir.tf line 105, in resource "azurerm_policy_assignment" "vm_sku_policy":
│ 105: resource "azurerm_policy_assignment" "vm_sku_policy" {
│
│ The provider hashicorp/azurerm does not support resource type "azurerm_policy_assignment".
│
│ Did you intend to use the data source "azurerm_policy_assignment"? If so, declare this using a "data" block instead of a "resource" block.
The azurerm_policy_assignment
is deprecated. You should use the azurerm_subscription_policy_assignment
to assign the policy at subscription level. For more information, refer to the GitHub page.
Here are are the supported blocks to assign the policy assignments on different scope, follow the Terraform Doc for more details
When I tried your code, I encountered the same error as follows
To create a policy definition
and assign it at the subscription, you can use the updated code below.
provider "azurerm" {
features {}
subscription_id = "158b8345-c359-4d98-95c5-f21815dd048f"
}
resource "azurerm_policy_definition" "vm_sku_policy" {
name = "OnlyAllowHostingCROSImages"
policy_type = "Custom"
mode = "All"
display_name = "Limit allowed VM SKUs"
description = "This policy restricts the VM SKUs that can be deployed in the subscription."
policy_rule = <<POLICY_RULE
{
"if": {
"allOf": [
{
"field": "type",
"in": [
"Microsoft.Compute/virtualMachines",
"Microsoft.Compute/virtualMachineScaleSets"
]
},
{
"not": {
"anyOf": [
{
"field": "Microsoft.Compute/imageSku",
"like": "*-Datacenter-gs"
},
{
"field": "Microsoft.Compute/imageSku",
"like": "2022-Datacenter*"
},
{
"allOf": [
{
"field": "Microsoft.Compute/imagePublisher",
"equals": "Canonical"
},
{
"field": "Microsoft.Compute/imageOffer",
"in": [
"0001-com-ubuntu-server-focal",
"0001-com-ubuntu-server-jammy",
"UbuntuServer"
]
},
{
"field": "Microsoft.Compute/imageSku",
"in": [
"20_04-lts-gen2",
"20_04-lts-cvm",
"22_04-lts-cvm",
"20_04-lts",
"22_04-lts"
]
}
]
}
]
}
}
]
},
"then": {
"effect": "deny"
}
}
POLICY_RULE
}
data "azurerm_subscription" "current" {}
resource "azurerm_resource_group" "vm_sku_policy" {
name = "test-resources"
location = "West Europe"
}
resource "azurerm_subscription_policy_assignment" "example" {
name = "exlimit-vm-sku-assignmentample"
policy_definition_id = azurerm_policy_definition.vm_sku_policy.id
subscription_id = data.azurerm_subscription.current.id
}
Terraform apply
After executing the terraform script, the policy definition has been created and assigned at subscription level.