Search code examples
terraformterraform-provider-azure

get terraform to randomly generate uuid ONE TIME ONLY, store in state and use for azuread_application_app_role


Problem

For terraform azuread v 3.0.1 azuread_application_app_role resource the role_id is both required and not auto generated. So, the plan or module must generate this id (which really seems so very wrong) - documentation for resource and version.

Therefore, I need to generate a random uuid which I do like so

  1. use random_uuid to generate a uuid for each role
  2. use the uuid result for azuread_application_app_role role_id
esource "random_uuid" "admin_role" {}
resource "random_uuid" "user_role" {}

resource "azuread_application" "app" {
  display_name = var.app_name
  identifier_uris = [local.app_identifier_uri]
}

...

resource "azuread_application_app_role" "admin_role" {
  role_id = random_uuid.admin_role.result
  application_id = azuread_application.app.id
  allowed_member_types = ["User"]
  description = "Admins can manage ${var.app_name}"
  display_name = "Admin-${var.app_name}"
  value = "Admin-${var.app_name}"
}

resource "azuread_application_app_role" "user_role" {
  role_id = random_uuid.user_role.result
  application_id = azuread_application.app.id
  allowed_member_types = ["User"]
  description = "User of  ${var.app_name} application"
  display_name = "User-${var.app_name}"
  value = "User-${var.app_name}"
}

I have remote state setup for the back. Upon each init, plan, apply I get a new set of uuids resulting in what looks like drift for every plan. I want to make the UUID one time and store it so it can be used.

How can I do this? I've tried using null resource

Null resource attempt

This didn't work. I continued to see the same issue

resource "random_uuid" "example_administrator" {}

resource "null_resource" "initialize_uuid" {
  triggers = {
    uuid = random_uuid.example_administrator.id
  }
}

resource "azuread_application_app_role" "example" {
  role_id = null_resource.initialize_uuid.triggers["uuid"]
  ...
}

time

I have yet to test this option

provider "time" {}

resource "time_static" "admin_role" {
  triggers = {
    # Any attribute here will generate the UUID only once
    role = "admin"
  }
}

resource "time_static" "user_role" {
  triggers = {
    # Any attribute here will generate the UUID only once
    role = "user"
  }
}

Solution

  • Part 1: Stable uuids

    The keeper set to constant string ensures once and only once for uuid generation.

    1. use the keeper block
    2. use the .id for role_id

    random provider doc on uuid

    resource "random_uuid" "admin_role" {
        keepers = {
           # ensure that uuid is made one time only
           const = "persistent-uuid"
        }
    }
    resource "random_uuid" "user_role" {
      keepers = {
        # ensure that uuid is made one time only
        const = "persistent-uuid"
      }
    
    }
    
    resource "azuread_application" "app" {
      display_name = var.app_name
      identifier_uris = [local.app_identifier_uri]
    }
    
    ...
    
    resource "azuread_application_app_role" "admin_role" {
      role_id = random_uuid.admin_role.id
      application_id = azuread_application.app.id
      allowed_member_types = ["User"]
      description = "Admins can manage ${var.app_name}"
      display_name = "Admin-${var.app_name}"
      value = "Admin-${var.app_name}"
    }
    
    resource "azuread_application_app_role" "user_role" {
      role_id = random_uuid.user_role.id
      application_id = azuread_application.app.id
      allowed_member_types = ["User"]
      description = "User of  ${var.app_name} application"
      display_name = "User-${var.app_name}"
      value = "User-${var.app_name}"
    }