My goal is to use a list of Azure policy display names to populate an Azure policyset. I have most of the code working, but am having an issue flattening out my list used to look up the policy ID using the data source terraform type. I am getting the following error
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
Error: Invalid for_each argument
on variables.tf line 40, in data "azurerm_policy_definition" "security_policyset_definitions":
40: for_each = local.security_flat
The given "for_each" argument value is unsuitable: the "for_each" argument
must be a map, or set of strings, and you have provided a value of type tuple.
Here are my variables. The issue is with calling [[[data “azurerm_policy_definition”]]], the for_each data type is not correct.
variable "policyset_definition_category" {
type = string
description = "The category to use for all PolicySet defintions"
default = "Custom"
}
locals {
/* security_flat = flatten([
for pol in var.security_policyset_definitions : {
policy_name = pol.policy
}
])
*/
security_flat = flatten([
for pol in var.security_policyset_definitions : {
policy_name = pol.policy
}
])
}
data "azurerm_policy_definition" "security_policyset_definitions" {
for_each = local.security_flat
display_name = each.value
## display_name = "Internet-facing virtual machines should be protected with network security groups"
}
variable "security_policyset_definitions" {
type = any
/*
type = map(object({
policy = string
effect = string
}))
*/
description = "List of policy definitions (display names) for the security_governance policyset"
default = [
{
policy = "Internet-facing virtual machines should be protected with network security groups"
effect = "AuditIfNotExists"
},
{
policy = "Subnets should be associated with a Network Security Group"
effect = "AuditIfNotExists"
},
{
policy = "Gateway subnets should not be configured with a network security group"
effect = "AuditIfNotExists"
},
{
policy = "Storage accounts should restrict network access"
effect = "AuditIfNotExists"
},
{
policy = "Secure transfer to storage accounts should be enabled"
effect = "AuditIfNotExists"
},
{
policy = "Access through Internet facing endpoint should be restricted"
effect = "AuditIfNotExists"
},
{
policy = "Storage accounts should allow access from trusted Microsoft services"
effect = "AuditIfNotExists"
},
{
policy = "RDP access from the Internet should be blocked"
effect = "AuditIfNotExists"
},
{
policy = "SSH access from the Internet should be blocked"
effect = "AuditIfNotExists"
},
{
policy = "Disk encryption should be applied on virtual machines"
effect = "AuditIfNotExists"
},
{
policy = "Automation account variables should be encrypted"
effect = "AuditIfNotExists"
},
{
policy = "Azure subscriptions should have a log profile for Activity Log"
effect = "AuditIfNotExists"
},
{
policy = "Email notification to subscription owner for high severity alerts should be enabled"
effect = "AuditIfNotExists"
},
{
policy = "A security contact email address should be provided for your subscription"
effect = "AuditIfNotExists"
},
{
policy = "Enable Azure Security Center on your subscription"
effect = "AuditIfNotExists"
}
]
}
variable "iam_policyset_definitions" {
type = list
description = "List of policy definitions (display names) for the iam_governance policyset"
default = [
"Audit usage of custom RBAC rules",
"Custom subscription owner roles should not exist",
"Deprecated accounts should be removed from your subscription",
"Deprecated accounts with owner permissions should be removed from your subscription",
"External accounts with write permissions should be removed from your subscription",
"External accounts with read permissions should be removed from your subscription",
"External accounts with owner permissions should be removed from your subscription",
"MFA should be enabled accounts with write permissions on your subscription",
"MFA should be enabled on accounts with owner permissions on your subscription",
"MFA should be enabled on accounts with read permissions on your subscription",
"There should be more than one owner assigned to your subscription"
]
}
variable "data_protection_policyset_definitions" {
type = list
description = "List of policy definitions (display names) for the data_protection_governance policyset"
default = [
"Azure Backup should be enabled for Virtual Machines",
"Long-term geo-redundant backup should be enabled for Azure SQL Databases",
"Audit virtual machines without disaster recovery configured",
"Key Vault objects should be recoverable"
]
}
Here is the main.tf:
terraform {
required_version = ">= 0.12.21"
}
provider "azurerm" {
version = "~> 2.25.0"
features {}
}
resource "azurerm_policy_set_definition" "sec_policy_set" {
name = "a"
policy_type = "Custom"
display_name = "c"
description = "d"
metadata = < y }
content {
#policy_definition_id = policy_definition_reference.value.policy
#policy_definition_id = policy_definition_reference.value["policy"]
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
parameters = {
Effect = policy_definition_reference.value["effect"]
}
/*
policy_definition_id = policy_definition_reference.value["policy_description"]
parameters = {
Effect = policy_definition_reference.value["effect"]
}
*/
}
}
}
I have hard-coded a valid policy_definition_id in the azurerm_policy_set_definition resource and if I change the “display_name” property of the data lookup function “azurerm_policy_definition” for now to validate that that resource works properly. Showing the change below:
data "azurerm_policy_definition" "security_policyset_definitions" {
#for_each = local.security_flat
#display_name = each.value
display_name = "Internet-facing virtual machines should be protected with network security groups"
}
After making these minor changes, my plan executes, but is using the static value for “policy_definition_id”. I need to be able to look up the policy_definition_id, by using the data source type:
Ref: https://www.terraform.io/docs/providers/azurerm/d/policy_set_definition.html
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
data.azurerm_policy_definition.security_policyset_definitions: Refreshing state...
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_policy_set_definition.sec_policy_set will be created
+ resource "azurerm_policy_set_definition" "sec_policy_set" {
+ description = "d"
+ display_name = "c"
+ id = (known after apply)
+ management_group_id = (known after apply)
+ management_group_name = (known after apply)
+ metadata = jsonencode(
{
+ category = "Custom"
}
)
+ name = "a"
+ policy_definitions = (known after apply)
+ policy_type = "Custom"
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
+ policy_definition_reference {
+ parameters = {
+ "Effect" = "AuditIfNotExists"
}
+ policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/b821191b-3a12-44bc-9c38-212138a29ff3"
+ reference_id = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Thank You for any help you can provide to get me over this hump!