Reputation: 43
I want to import an azurerm_role_assignment
(Azure) in Terraform dependent on my environment (dev, test, prod) by using an import block such as
import {
to = azurerm_role_assignment.test_role_assignment
id = "<scope>/.../<GUID>"
}
At the moment I use
az role assignment list --assignee ... --all
which returns a list of role assignments and now based on matching roleDefinitionName
I copy the related id
manually into the import block and it works. But it is different for the other environments. I want to avoid copying a lot of IDs manually.
So I was thinking within the scope I can use a variable "env" in order to import from the correct environment. But the changing GUID is required - for example:
import {
to = azurerm_role_assignment.test_role_assignment
id = "/subscriptions/.../resourcegroups/$(var.env)-rg/$(data.<something>.id)"
}
Is there a way to get the GUID in a data block or similar so that I can put the GUID in the id of the import block? I don't want to manually import all role assignments for all environments manually. Thank you!
Upvotes: 0
Views: 820
Reputation: 14729
You can accomplish this by using the AzAPI provider. This provider offers all the capabilities of the azure rest api. And may be useful if resources or data sources are not yet readily available in the AzureRM provider. However, since this provider is less abstract it might require more in depth knowledge about the underlying rest objects and responses.
The azapi_resource_list data source can be used to list all role assignments for a particular assignee. In this case I assume that the assignee is a user, but it can also be another entity. Make sure that you correctly specify the filter in the resource type field. More filters for role assignments can be found in the official documentation. And don't forget to set enable_hcl_output_for_data_source
on the AzAPI provider, so that you can easily use data source outputs in hcl format.
provider "azurerm" {
features {}
}
provider "azapi" {
enable_hcl_output_for_data_source = true
}
data "azuread_user" "assignee" {
user_principal_name = "[email protected]"
}
data "azurerm_subscription" "current" {}
data "azapi_resource_list" "role_assignments" {
parent_id = "/subscriptions/${data.azurerm_subscription.id}"
type = join("", [
"Microsoft.Authorization/roleAssignments@2022-04-01",
"$filter=atScope()+and+assignedTo('${data.azuread_user.assignee.object_id}')"
])
response_export_values = ["*"]
}
locals {
role_assignments = {
for item in data.azapi_resource_list.role_assignment.output.value : item.id => item
}
}
resource "azurerm_role_assignment" "example" {
for_each = local.role_assignments
scope = each.value.properties.scope
role_definition_id = each.value.properties.roleDefinitionId
principal_id = each.value.properties.principalId
}
import {
for_each = local.role_assignments
to = azurerm_role_assignment.role_assignment.example[each.key]
id = each.value.id
}
Finally, if you want to deploy this to multiple environments (i.e. subscriptions), you can set a different value for the environment variable ARM_SUBSCRIPTION_ID
before running your terraform commands.
Note: I did not fully test this, because I don’t have an active Azure account. Feel free to correct me or provide additional information.
Upvotes: 0
Reputation: 605
For this answer I'll go with: You have a role definition name you can match with, and you require the GUID for the role assignment to be returned to you as a value so you can use it for your imports.
Probably in this case, if it must be az cli, I would try the az rest
command.
az rest --method get --url "https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/roleAssignments?api-version=2022-04-01&$filter=atScope()+and+assignedTo('{objectId}')"
With this you can go over the subscriptions, and get the GUID for the role assignment. Read docs here.
Perhaps, if your logic is something like:
for each subscription:
az account list --query '[].id' -o tsv
role_definition_name="roledefinitionname"
for subscription in $(az account list --query '[].id' -o tsv); do
az account set --subscription $subscription
role_definition_id=$(az role definition list --name $role_definition_name --query '[0].id' -o tsv)
if [ -n "$role_definition_id" ]; then
echo "Role definition ID for $role_definition_name: $role_definition_id"
az role assignment list --query "[?roleDefinitionId=='$role_definition_id'].{assignmentId:id}" -o tsv
else
echo "Role definition $role_definition_name not found in subscription $subscription"
fi
done
Granted this is written for Windows. But the az commands are there for your personal fine-tuning. Hope it helps.
Upvotes: 1