goodworkaround / terraform-az-rbac-pim-assignment

8 stars 13 forks source link

Can't use resource groups managed from Terraform maps/lookups with Resource Group PIM assignment #2

Open MohnJadden opened 2 years ago

MohnJadden commented 2 years ago

I am trying to use the PIM Assignment - Resource Group module with for_each and lookups in TF. The use case is so that we can set a security group as a variable, then have that security group be granted RBAC roles, and in this case, the PIM assignment as well.

I am using the branch linked in issue #1.

When I run terraform plan, I receive the following error output:


│ Error: Invalid value for module argument
│
│   on testVDI.tf line 59, in module "pim_assignment_2":
│   59:   resource_group_name  = azurerm_resource_group.test-vdi-rg[each.key]
│
│ The given value is not suitable for child module variable "resource_group_name" defined at PIM Assignment - Resource Group\main.tf:24,1-31: string required.

I tried changing the Resource Group PIM assignment main.tf resource_group name to a map as follows:

variable "resource_group_name" {
  type = string
}

After doing this and saving, I get the following error:

│ Error: Incorrect attribute value type
│
│   on PIM Assignment - Resource Group\main.tf line 44, in resource "random_uuid" "eligible_schedule_request_id":
│   44:   keepers = {
│   45:     principalId         = var.principal_id
│   46:     roleDefinitionId    = data.azurerm_role_definition.role.id
│   47:     requestType         = var.request_type
│   48:     startDateTime       = "${formatdate("YYYY-MM-DD", time_rotating.eligible_schedule_request_start_date.id)}T${formatdate("HH:mm:ss.0000000+02:00", time_rotating.eligible_schedule_request_start_date.id)}"
│   49:     duration            = "P${tostring(var.assignment_days)}D"
│   50:     resource_group_name = var.resource_group_name
│   51:   }
│     ├────────────────
│     │ data.azurerm_role_definition.role.id will be known only after apply
│     │ time_rotating.eligible_schedule_request_start_date.id will be known only after apply
│     │ var.assignment_days is a number, known only after apply
│     │ var.principal_id is a string, known only after apply
│     │ var.request_type is a string, known only after apply
│     │ var.resource_group_name is a map of dynamic, known only after apply
│
│ Inappropriate value for attribute "keepers": element "resource_group_name": string required.

I'm defining resource groups in the root main.tf as follows:

resource "azurerm_resource_group" "test-vdi-rg" {
  for_each = var.team_name
  name     = "${each.value}-VDI"
  location = var.location
  tags = {
    Owner            = lookup(var.Owner, each.key)
    TechnicalContact = lookup(var.TechnicalContact, each.key)
    Location         = lookup(var.City, each.key)
    DepartmentName   = lookup(var.DepartmentName, each.key)
  }
}
mariussm commented 2 years ago

You need to do this instead:

resource_group_name  = azurerm_resource_group.test-vdi-rg[each.key].name

You forgot to refer to the name property of the resource group :)

MohnJadden commented 2 years ago

You need to do this instead:

resource_group_name  = azurerm_resource_group.test-vdi-rg[each.key].name

You forgot to refer to the name property of the resource group :)

I replaced line 50 in the PIM Assignment main.tf with this content, and am now receiving the following error:

│ Error: Reference to undeclared resource
│
│   on PIM Assignment - Resource Group\main.tf line 50, in resource "random_uuid" "eligible_schedule_request_id":
│   50:     resource_group_name = azurerm_resource_group.test-vdi-rg[each.key].name
│
│ A managed resource "azurerm_resource_group" "test-vdi-rg" has not been declared in module.pim_assignment_2.

Since I'm declaring the resource groups in the original TF file which then calls the module, do I need to do something to pass the mapped name value to the main.tf for PIM assignment? I did also try replacing all references of var.resource_group_namein main.tf with azurerm_resource_group.test-vdi-rg[each.key].name, no luck.

MohnJadden commented 2 years ago

Issue resolved - I changed resource_group_name in main.tf to var.resource_group_name. I also corrected the name of the module to "pim_assignment" instead of "pim_assignment_2" as displayed in the walkthrough. I also changed the resource_group_name variable to a string instead of a map in the PIM Assignment - Resource Group module.

After doing these I was able to use the mapped SecurityGroup variable successfully with the module.

If it helps, here's the text of the assignment in my source TF module:

module "pim_assignment" {

  source               = "./PIM Assignment - Resource Group"
  for_each             = var.team_name
  resource_group_name  = azurerm_resource_group.test-vdi-rg.name
  principal_id         = lookup(var.SecurityGroup, each.key)
  role_definition_name = "Virtual Machine Administrator Login"
}

PIM Assignment - Resource Group/main.tf is now as follows:

variable "principal_id" {
  type = string
}

variable "role_definition_name" {
  type = string
}

variable "request_type" {
  type    = string
  default = "AdminUpdate"
}

variable "deployment_name" {
  type    = string
  default = null
}

variable "assignment_days" {
  type    = number
  default = 365
}

variable "resource_group_name" {
  type = string
}

provider "azurerm" {
  features {}
}

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 2"
    }
  }
}

// Get role from data resource, instead of hard coding
data "azurerm_role_definition" "role" {
  name = var.role_definition_name
}

// Generate a new guid for the eligible schedule request whever principalId, roleDefinitionId or requestType changes
resource "random_uuid" "eligible_schedule_request_id" {
  keepers = {
    principalId         = var.principal_id
    roleDefinitionId    = data.azurerm_role_definition.role.id
    requestType         = var.request_type
    startDateTime       = "${formatdate("YYYY-MM-DD", time_rotating.eligible_schedule_request_start_date.id)}T${formatdate("HH:mm:ss.0000000+02:00", time_rotating.eligible_schedule_request_start_date.id)}"
    duration            = "P${tostring(var.assignment_days)}D"
    resource_group_name = var.resource_group_name
  }
}

// Used to a) support short life time assignments automatically re-assigned and b) support a single start date that does not change
resource "time_rotating" "eligible_schedule_request_start_date" {
  rotation_days = floor(var.assignment_days / 2)
}

// Deploy the eligible schedule request using ARM template
resource "azurerm_resource_group_template_deployment" "eligible_schedule_request" {
  name                = var.deployment_name == null ? random_uuid.eligible_schedule_request_id.id : var.deployment_name
  resource_group_name = var.resource_group_name
  deployment_mode     = "Incremental"
  template_content    = file("${path.module}/pim_assignment.json")

  // Send parameters to ARM template
  parameters_content = jsonencode({
    "principalId" = {
      value = var.principal_id
    },
    "roleDefinitionId" = {
      value = data.azurerm_role_definition.role.id
    },
    "requestType" = {
      value = var.request_type
    },
    "id" = {
      value = random_uuid.eligible_schedule_request_id.id
    }
    "startDateTime" = {
      value = "${formatdate("YYYY-MM-DD", time_rotating.eligible_schedule_request_start_date.id)}T${formatdate("HH:mm:ss.0000000+02:00", time_rotating.eligible_schedule_request_start_date.id)}"
    }
    "duration" = {
      value = "P${tostring(var.assignment_days)}D"
    }
  })
}
MohnJadden commented 2 years ago

Gotta reopen. Unfortunately this didn't carry over from my test environment into prod. When I run plan or apply with the changes I put in, I get the following error:

The given value is not suitable for child module variable "resource_group_name" defined at PIM Assignment - Resource Group\main.tf:24,1-31: string required.

It seems like the module is back to the original behavior of being unable to work with environments using mapped resource groups.

MohnJadden commented 2 years ago

@mariussm Any chance of this getting looked at anytime soon?