azureterraformterraform-provider-azure

How do I get the Principal ID of a Azure Storage Sync in Terraform


azurerm_storage_sync does not return the Principal ID (GUID), but instead returns the standard ID (8 key); however, I need to grant this new Storage Sync Owner access to the Storage Account. How do I do this within the Terraform code?

resource "azurerm_storage_sync" "ena_sync" {
  name                = "Citrix-File-Sync-${var.environment.short}"
  resource_group_name = var.azurerm_vars.azurerm_resource_group
  location            = var.azurerm_vars.azurerm_location
}

resource "azurerm_role_assignment" "ena_sync" {
  scope                = $var.storage_account
  role_definition_name = "Owner"
  principal_id         = azurerm_storage_sync.ena_sync.id
  principal_type       = "ServicePrincipal"
}

The above code doesn't work, because principal_id has to be a GUID, but azurerm_storage_sync.ena_sync.id returns a 8key ID.

╷
│ Error: unexpected status 400 (400 Bad Request) with error: InvalidPrincipalId: The Principal ID '/subscriptions/.../resourceGroups/.../providers/Microsoft.StorageSync/storageSyncServices/Citrix-File-Sync-Prod' is not valid. Principal ID must be a GUID.
│
│   with azurerm_role_assignment.ena_sync,
│   on sync_group.tf line 7, in resource "azurerm_role_assignment" "ena_sync":
│    7: resource "azurerm_role_assignment" "ena_sync" {
│
╵

According to the docs only id, incoming_traffic_policy, location & tags are returns by this command, and not much more is returned by using a data point instead of the resource, so I'm wondering if there is another method I can use to get the Principal ID.

Or, is there some other way I need to add permissions to the Storage Account for the new Sync?


Solution

  • Or, is there some other way I need to add permissions to the Storage Account for the new Sync?

    Yes, the azurerm_storage_sync resource does not represent a service principal and thus doesn't expose a principal_id (GUID), because Azure File Sync doesn’t use a user-assigned managed identity by default, and you can't assign RBAC to the storage sync resource directly using a principal_id.

    You can use the code below to add managed identity to storage sync and assign the role to the storage account using Terraform and PowerShell.

    Code:

    provider "azurerm" {
     features {}
     subscription_id = "xxxxxx"
    }
    
    variable "environment" {
     default = {
       short = "prod"
     }
    }
    
    variable "azurerm_vars" {
     default = {
       azurerm_location       = "eastus"
       azurerm_resource_group = "xxxxxx"
     }
    }
    
    # Create Resource Group
    resource "azurerm_resource_group" "main" {
     name     = var.azurerm_vars.azurerm_resource_group
     location = var.azurerm_vars.azurerm_location
    }
    
    # Create Storage Account
    resource "azurerm_storage_account" "my_storage" {
     name                     = "mystorage${var.environment.short}"
     resource_group_name      = azurerm_resource_group.main.name
     location                 = azurerm_resource_group.main.location
     account_tier             = "Standard"
     account_replication_type = "LRS"
    }
    
    # Create Azure File Sync Service
    resource "azurerm_storage_sync" "ena_sync" {
     name                = "Citrix-File-Sync-${var.environment.short}"
     resource_group_name = azurerm_resource_group.main.name
     location            = azurerm_resource_group.main.location
    }
    
    # Run PowerShell commands after Storage Sync creation to enable system-assigned identity and assign role
    resource "null_resource" "enable_identity_and_role" {
     depends_on = [
       azurerm_storage_sync.ena_sync,
       azurerm_storage_account.my_storage
     ]
    
     provisioner "local-exec" {
       command = <<-EOT
    
         # Enable system-assigned identity on the Storage Sync service
         $syncService = Set-AzStorageSyncService -ResourceGroupName '${var.azurerm_vars.azurerm_resource_group}' -Name 'Citrix-File-Sync-${var.environment.short}' -IdentityType 'SystemAssigned'
    
         # Get the principal ID of the managed identity
         $principalId = $syncService.Identity.PrincipalId
         Write-Host "Storage Sync Service Identity PrincipalId: $principalId"
    
         # Assign the role to the managed identity on the storage account
         New-AzRoleAssignment -ObjectId $principalId -RoleDefinitionName 'Storage File Data SMB Share Contributor' -Scope '/subscriptions/xxxxxxxx/resourceGroups/${var.azurerm_vars.azurerm_resource_group}/providers/Microsoft.Storage/storageAccounts/mystorage${var.environment.short}'
    
         Write-Host 'Role assignment complete!'
       EOT
    
       interpreter = ["pwsh", "-Command"]
     }
    }
    

    Output:

    Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
    

    enter image description here

    enter image description here Reference: Set-AzStorageSyncService (Az.StorageSync) | Microsoft Learn