-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use ARM VM assigned manage identity as SP to use Graph API [app role assignments] #459
Comments
Hi @melkikh, thanks for reaching out with your query. Assigning permissions to a service principal that's backing a managed identity is done a little differently. We don't actually support the entire workflow end-to-end at present - we are planning this for version 2.0 of the AzureAD provider (see microsoftgraph/microsoft-graph-docs#323 for context) - but you can get most of the way with Terraform and shim the last mile with some PowerShell or an Azure CLI command. In order to assign the managed identity to a VM in the first instance, you'll want to use the resource "azurerm_user_assigned_identity" "melkikh_vm" {
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
name = "melkikh-vm"
}
resource "azurerm_linux_virtual_machine" "melkikh_vm" {
# ...
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.melkikh_vm.id]
}
} You can obtain the underlying service principal's object ID via The last bit, assigning the permissions, is done via app role assignments on that service principal (which incidentally happens via Microsoft Graph). As above, we don't yet have support for this but plan to add it soon. In the meantime, this guide should give you all you need to do this in PowerShell or build an Azure CLI (or curl) command. I'm going to leave this issue open as a feature request for app role assignments, since it looks like we don't have one (although we are still tracking the feature on our backlog). I hope the above info helps you construct a workaround in the meantime! Related: microsoftgraph/microsoft-graph-docs#164 General note: If you're assigning API permissions to an app registration, you want the |
Additionally, I believe our documentation here on the specific interactions between managed identities, their principals and the resources that assume them, could be improved - although you can find lots of material in Azure docs we could probably put together a complete Terraform-specific example once we have full support in place. |
Hi, @manicminer ps. resource "azuread_application_app_role" "group_reader" {
display_name = "melkikh-test-app-role"
description = "Read Group information from Microsoft Graph"
application_object_id = azuread_application.melkikh_test_app.object_id
allowed_member_types = ["Application"]
enabled = true
value = "Melkikh.Group.Read.All"
}
resource "azurerm_user_assigned_identity" "melkikh_sp" {
name = "melkikh-sp"
resource_group_name = azurerm_resource_group.rg.name
location = var.location
} After, I tried to make rest api request with these parameters: az rest --method POST -uri https://graph.microsoft.com/v1.0/servicePrincipals/$resource_id/appRoleAssignedTo --body "{'appRoleId':'$app_role_id','principalId':'$principal_id','resourceId':'$resource_id'}" --headers 'Content-Type=application/json' and I see: |
Hi @melkikh, you'll want to assign roles published by Microsoft Graph rather than your own application. You should have a Microsoft Graph service principal in your tenant, you can query it to list the published roles. For example with Azure CLI: |
Hi, @manicminer ! provider "azurerm" {
features {}
}
provider "azuread" {
}
resource "azurerm_resource_group" "rg" {
name = "melkikh"
location = var.location
}
terraform {
required_version = ">= 0.12"
required_providers {
azuread = {
source = "hashicorp/azuread"
version = "~> 1.5.0"
}
}
}
resource "azurerm_user_assigned_identity" "melkikh_vm" {
name = "melkikh-vm"
resource_group_name = azurerm_resource_group.rg.name
location = var.location
}
resource "azurerm_linux_virtual_machine" "melkikh_vm" {
name = var.hostname
location = var.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.nic.id]
size = "Standard_B2s"
admin_username = var.admin_username
computer_name = var.hostname
disable_password_authentication = true
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.melkikh_vm.id]
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
os_disk {
storage_account_type = "Standard_LRS"
name = "${var.hostname}_os"
caching = "ReadWrite"
}
admin_ssh_key {
username = var.admin_username
public_key = file(var.public_key_file)
}
}
output "sp_principal_id" {
value = azurerm_user_assigned_identity.melkikh_vm.principal_id
}
output "sp_identity_id" {
value = azurerm_user_assigned_identity.melkikh_vm.id
} After applying this I got UUID for my managed identity: After I tried to use REST API and catched an error again: $ export resource_id="00000003-0000-0000-c000-000000000000" && export app_role_id="98830695-27a2-44f7-8c18-0c3ebc9698f6" && export principal_id="2fbfd36c-2cbd-48b1-a23b-76570c3f88fd" && az rest --method POST -uri https://graph.microsoft.com/v1.0/servicePrincipals/$resource_id/appRoleAssignedTo --body "{\"appRoleId\":\"$app_role_id\",\"principalId\":\"$principal_id\",\"resourceId\":\"$resource_id\"}" --headers 'Content-Type=application/json'
unrecognized arguments: https://graph.microsoft.com/v1.0/servicePrincipals/00000003-0000-0000-c000-000000000000/appRoleAssignedTo where: |
These look ok at first glance. Based on the error message and your code snippet, did you perhaps miss a dash on the |
(Cross-posting from microsoftgraph/microsoft-graph-docs-contrib#3377) @melkikh Because the appId of a service principal is also included in the "servicePrincipalNames" property, and $ export resource_id=$(az ad sp show --id "00000003-0000-0000-c000-000000000000" --query "objectId" -o tsv) Alternatively, you could also do this: $ export resource_id=$(az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query [].objectId -o tsv) Or even this: $ export resource_id=$(az rest --method GET --uri "https://graph.microsoft.com/v1.0/servicePrincipals?\$filter=appId eq '00000003-0000-0000-c000-000000000000'&\$select=id" --query "value[].id" -o tsv) |
This functionality has been released in v2.4.0 of the Terraform Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you! |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. |
Edit by @manicminer: This should be solved with support for app role assignments
Hello!
I want to use managed identity service principle to get data from Microsoft Graph API (with a specific role).
There is instruction, that says that this is possible:
I am trying to do this:
and get an error:
How can I use managed identity to work with Graph API?
If it works only with
SystemAssigned
managed identity, that's ok for me, but I don't understand, how I can useprincipalId
(likeazurerm_linux_virtual_machine.melkikh_vm.identity.0.principal_id
) assigned to VM, as application principal.Thanks.
The text was updated successfully, but these errors were encountered: