I have an yaml file as given below
sites:
- name: site1
counter: "001"
keyvaults:
- name: "KV1"
role_id: "0023"
access_policies:
SP1:
object_id: "0000-0000-0000-00000"
tenant_id: "xxxx-xxxx-xxxx-xxxx"
certificate_permissions: ["Get"]
key_permissions: []
storage_permissions: []
secret_permissions: ["Get"]
But terraform code for reading this is
locals {
sites = yamldecode(file("${path.module}/sites.yaml"))["sites"]
keyvaults = merge(flatten([
for site in local.sites : {
for keyvault in site.keyvaults : "${site.name}-${keyvault.name}" => {
keyvault_name = keyvault.name
keyvault_role_id = keyvault.role_id
counter = site.counter
access_policies = keyvault.access_policies
}
}
])...)
}
But , when i execute "terraform plan" it is failing saying:
Error: Unsupported attribute
│
│ on appservice_env.tf line 66, in locals:
│ 66: for policy_name, policy in tomap(keyvault.access_policies) :
policy_name => {
│
│ This object does not have an attribute named "access_policies".
TL;DR your problem is probably caused by elements in your yaml file that don't have an access_policies
property.
Instead of:
for policy_name, policy in keyvault.access_policies
Try:
for policy_name, policy in try(keyvault.access_policies, [])
Consider the following file - sites.yaml:
sites:
- name: site1
counter: "001"
keyvaults:
- name: "KV1"
role_id: "0023"
access_policies:
SP1:
object_id: "0000-0000-0000-00000"
tenant_id: "xxxx-xxxx-xxxx-xxxx"
certificate_permissions: ["Get"]
key_permissions: []
storage_permissions: []
secret_permissions: ["Get"]
- name: site2
counter: "002"
keyvaults:
- name: "KV2"
role_id: "0024"
Adding an output variable to your original code:
locals {
sites = yamldecode(file("${path.module}/sites.yaml"))["sites"]
keyvaults = merge(flatten([
for site in local.sites : {
for keyvault in site.keyvaults : "${site.name}-${keyvault.name}" => {
keyvault_name = keyvault.name
keyvault_role_id = keyvault.role_id
counter = site.counter
access_policies = {
for policy_name, policy in keyvault.access_policies : policy_name => {
tenant_id = policy.tenant_id
object_id = policy.object_id
key_permissions = policy.key_permissions
secret_permissions = policy.secret_permissions
certificate_permissions = policy.certificate_permissions
storage_permissions = policy.storage_permissions
}
}
}
}
])...)
}
output "keyvaults" {
value = local.keyvaults
}
Output of terraform plan
:
Error: Unsupported attribute
on main.tf line 11, in locals:
11: for policy_name, policy in keyvault.access_policies : policy_name => {
This object does not have an attribute named "access_policies".
locals {
sites = yamldecode(file("${path.module}/sites.yaml"))["sites"]
keyvaults = merge(flatten([
for site in local.sites : {
for keyvault in site.keyvaults : "${site.name}-${keyvault.name}" => {
keyvault_name = keyvault.name
keyvault_role_id = keyvault.role_id
counter = site.counter
access_policies = {
for policy_name, policy in try(keyvault.access_policies, []) : policy_name => {
tenant_id = policy.tenant_id
object_id = policy.object_id
key_permissions = policy.key_permissions
secret_permissions = policy.secret_permissions
certificate_permissions = policy.certificate_permissions
storage_permissions = policy.storage_permissions
}
}
}
}
])...)
}
output "keyvaults" {
value = local.keyvaults
}
Output of terraform plan
:
Changes to Outputs:
+ keyvaults = {
+ site1-KV1 = {
+ access_policies = {
+ SP1 = {
+ certificate_permissions = [
+ "Get",
]
+ key_permissions = []
+ object_id = "0000-0000-0000-00000"
+ secret_permissions = [
+ "Get",
]
+ storage_permissions = []
+ tenant_id = "xxxx-xxxx-xxxx-xxxx"
}
}
+ counter = "001"
+ keyvault_name = "KV1"
+ keyvault_role_id = "0023"
}
+ site2-KV2 = {
+ access_policies = {}
+ counter = "002"
+ keyvault_name = "KV2"
+ keyvault_role_id = "0024"
}
}