I am trying to create multiple role assignments using a typical variable given below where "permission {}" is a new variable I would like to introduce in the form of a type map, so I can perform multiple role assignments.
My TFVARS file
azure_vnets= {
prod= [
{
cidr = ["10.0.0.0/24"]
vnet_name = "vnet1"
dns = ["10.0.0.1"]
rg = "myrg1"
permission = {
Contributor = ["xxxxxxxxxxxx", "xxxxxxxxxxxxx"],
Reader = ["xxxxxxxxxxx", "xxxxxxxxxx"]
}
location = "eastus"
},
{
cidr = ["10.0.1.0/24"]
vnet_name = "vnet2"
dns = ["10.0.1.2"]
rg = "myrg2"
permission = {
Contributor = ["xxxxxxxxxxxx", "xxxxxxxxxxxxx"],
Reader = ["xxxxxxxxxxx", "xxxxxxxxxx"]
}
location = "westeurope"
}
],
nonprod = [
{
cidr = ["10.0.3.0/24"]
vnet_name = "vnet1"
dns = ["10.0.3.1"]
rg = "nonprodrg"
location = "eastus"
permission = {
Contributor = ["xxxxxxxxxxxx", "xxxxxxxxxxxxx"],
Reader = ["xxxxxxxxxxx", "xxxxxxxxxx"]
}
},
{
cidr = ["10.0.4.0/24"]
vnet_name = "nonprod-vnet2"
dns = ["10.0.4.2"]
sub = "nonProd"
rg = "mynonprodrg"
permission = {
Contributor = ["xxxxxxxxxxxx", "xxxxxxxxxxxxx"],
Reader = ["xxxxxxxxxxx", "xxxxxxxxxx"]
}
location = "westeurope"
}
]
}
My resource creation file I have a local defined here which helps me use the above variable in a for_each loop given below in the role assignment creation. I would like to know how to get the Rolename as Key and ObjectID as value in the below for_each role_assignment creation from the above TFvar variable
locals {
flat_azure_vnets = merge([
for env_name, env_vn_list in var.azure_vnets:
{
for idx, env_vn in env_vn_list:
"${env_name}-${idx}" => env_vn
}
]...)
}
resource "azurerm_role_assignment" "role_assignment" {
for_each = { for k, v in local.flat_azure_vnets : k => v }
scope = azurerm_resource_group.this.id
role_definition_name = each.xxx
principal_id = each.key
}
CodePudding user response:
To iterate over your new permission
attribute, you have to further flatten your flat_azure_vnets
. So you can introduce flat_azure_vnets2
:
locals {
flat_azure_vnets = merge([
for env_name, env_vn_list in var.azure_vnets:
{
for idx, env_vn in env_vn_list:
"${env_name}-${idx}" => env_vn
}
]...)
flat_azure_vnets2 = merge([
for key, env in local.flat_azure_vnets:
{
for cidx, contrinutor in env["permission"]["Contributor"]:
"${key}-${cidx}" => merge(
env, {
"contrinutor" = contrinutor,
"reader" = env["permission"]["Reader"][cidx]
}
)
}
]...)
}
which produces flat_azure_vnets2
in the form of (notice new contrinutor
and reader
attributes):
test = {
"nonprod-0-0" = {
"cidr" = [
"10.0.3.0/24",
]
"contrinutor" = "xxxxxxxxxxxx"
"dns" = [
"10.0.3.1",
]
"location" = "eastus"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxxx"
"rg" = "nonprodrg"
"vnet_name" = "vnet1"
}
"nonprod-0-1" = {
"cidr" = [
"10.0.3.0/24",
]
"contrinutor" = "xxxxxxxxxxxxx"
"dns" = [
"10.0.3.1",
]
"location" = "eastus"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxx"
"rg" = "nonprodrg"
"vnet_name" = "vnet1"
}
"nonprod-1-0" = {
"cidr" = [
"10.0.4.0/24",
]
"contrinutor" = "xxxxxxxxxxxx"
"dns" = [
"10.0.4.2",
]
"location" = "westeurope"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxxx"
"rg" = "mynonprodrg"
"sub" = "nonProd"
"vnet_name" = "nonprod-vnet2"
}
"nonprod-1-1" = {
"cidr" = [
"10.0.4.0/24",
]
"contrinutor" = "xxxxxxxxxxxxx"
"dns" = [
"10.0.4.2",
]
"location" = "westeurope"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxx"
"rg" = "mynonprodrg"
"sub" = "nonProd"
"vnet_name" = "nonprod-vnet2"
}
"prod-0-0" = {
"cidr" = [
"10.0.0.0/24",
]
"contrinutor" = "xxxxxxxxxxxx"
"dns" = [
"10.0.0.1",
]
"location" = "eastus"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxxx"
"rg" = "myrg1"
"vnet_name" = "vnet1"
}
"prod-0-1" = {
"cidr" = [
"10.0.0.0/24",
]
"contrinutor" = "xxxxxxxxxxxxx"
"dns" = [
"10.0.0.1",
]
"location" = "eastus"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxx"
"rg" = "myrg1"
"vnet_name" = "vnet1"
}
"prod-1-0" = {
"cidr" = [
"10.0.1.0/24",
]
"contrinutor" = "xxxxxxxxxxxx"
"dns" = [
"10.0.1.2",
]
"location" = "westeurope"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxxx"
"rg" = "myrg2"
"vnet_name" = "vnet2"
}
"prod-1-1" = {
"cidr" = [
"10.0.1.0/24",
]
"contrinutor" = "xxxxxxxxxxxxx"
"dns" = [
"10.0.1.2",
]
"location" = "westeurope"
"permission" = {
"Contributor" = [
"xxxxxxxxxxxx",
"xxxxxxxxxxxxx",
]
"Reader" = [
"xxxxxxxxxxx",
"xxxxxxxxxx",
]
}
"reader" = "xxxxxxxxxx"
"rg" = "myrg2"
"vnet_name" = "vnet2"
}
}
CodePudding user response:
You can use the below example which I have tested in my environment:
provider "azurerm"{
features{}
}
locals {
flat_azure_vnets = merge([
for env_name, env_vn_list in var.azure_vnets:
{
for idx, env_vn in env_vn_list:
"${env_name}-${idx}" => env_vn
}
]...)
flat_rbac = {for i,r in local.flat_azure_vnets : "role-${i}"=>"${r.permission}"}
}
variable "azure_vnets" {}
output "rbac" {
value = local.flat_rbac
}
module "Contributor_roleAssignment" {
for_each = zipmap(keys(local.flat_rbac), values(local.flat_rbac)[*].Contributor)
source = "./modules/roleAssignment"
role_definition_name = "Contributor"
scope_id = "/subscriptions/948d4068-cee2-492b-8f82-e00a844e059b/resourceGroups/ansumantest"
principal_ids = each.value
}
module "Reader_roleAssignment" {
for_each = zipmap(keys(local.flat_rbac), values(local.flat_rbac)[*].Reader)
source = "./modules/roleAssignment"
role_definition_name = "Reader"
scope_id = "/subscriptions/948d4068-cee2-492b-8f82-e00a844e059b/resourceGroups/ansumantest"
principal_ids = each.value
}
Role assignment module i.e. "./modules/roleAssignment"
main.tf
locals {
principals = toset(var.principal_ids)
}
resource "azurerm_role_assignment" "role_assignment" {
for_each = local.principals
scope = var.scope_id
role_definition_name = var.role_definition_name
principal_id = each.key
}
variables.tf
:
variable "role_definition_name" {
type = any
description = "The name of the Role to assign to the chosen Scope."
}
variable "scope_id" {
type = string
description = "The Id of the scope where the role should be assigned."
}
variable "principal_ids" {
type = list(string)
description = "The ID of the principal that is to be assigned the role at the given scope. Can be User, Group or SPN."
}
Output: