I faced an issue when I had to terraform import some role_assignment resources, specially regarding the APP CONFIG DATA READER role assignment, in terraform.
the problem I had to solve was due to an evolution of our iac to make the terraform plan more readable and explicit.
Here is the code for role assignment that changed :
module "my_role_assignment_slot_to_app_config" {
for_each = local.map_slot_app_config
source = "../../resourceModules/role_assignment"
scope = each.value.config_id
role_definition_names = ["Reader","App Configuration Data Reader"]
principal_id = each.value.slot_guid
}
with the following module for role assignments :
```hcl
resource "azurerm_role_assignment" "my_role_assignment" {
for_each = toset(var.role_definition_names)
scope = var.scope
role_definition_name = each.value
principal_id = var.principal_id
}
This code would plan the following, more readable :
But as you can see, the index for the azurerm_role_assignment.my_role_assignment
contains spaces.
This was preventing us to terraform import the role assignment (as it has been created manually before the iac was coded) using powershell script in an azureCli task on azure Devops :
- task: AzureCli@2
displayName: Runs tfImport.ps1
condition: and(succeeded(), eq(variables['toUpdate.scriptExists'], 'true')) # test script presence
name: tfImport.ps1
inputs:
azureSubscription: ${{ parameters.serviceConnection }}
scriptType: ps
scriptLocation: InlineScript
inlineScript: |
$Env:ARM_CLIENT_ID = "$Env:servicePrincipalId"
$Env:ARM_CLIENT_SECRET = "$Env:servicePrincipalKey"
$Env:ARM_TENANT_ID = "$Env:tenantId"
$Env:ARM_SUBSCRIPTION_ID = az account list --query "[?isDefault].id" -o tsv
$Env:TF_LOG = "${{ parameters.TF_LOG }}"
terraform init `
-migrate-state `
-backend-config="resource_group_name=${{ parameters.storageAccountResourceGroup }}"`
-backend-config="storage_account_name=${{ parameters.storageAccount}}" `
-backend-config="key=${{ parameters.storageContainer }}" `
-backend-config="container_name=${{ parameters.stateBlobContainer }}"
// runs my tfImport.ps1 script here
./tfImport.ps1
workingDirectory: $(pipeline_artefact_folder_extract)/
addSpnToEnvironment: true
failOnStderr: false
continueOnError: true
The script I used had the following terraform import line,
terraform import 'module.my_role_assignment_slot_to_app_config[\"sit03_z-adf-ftnd-shrd-npd-ew1-cfg01\"].azurerm_role_assignment.my_role_assignment[\"App Configuration Data Reader\"]' /subscriptions/**********/resourceGroups/*********/providers/Microsoft.AppConfiguration/configurationStores/z-adf-ftnd-shrd-npd-ew1-cfg01/providers/Microsoft.Authorization/roleAssignments/<role_assignment_id>
and so I've had the following error :
(id datas removed)
After some researches, I've found the following link that explains the why and give to me one start of solution :
https://github.com/hashicorp/terraform/issues/25116
But I had to go further and find a way to use my powershell script without the startProcess method.
And as I had also to get my role_assignment resourceId from its PrincipalId (as we can gets the PrincipalId of resources that have the 'App Configuration Data Reader' role on the app_config using the following)
# role assignment over a specific scope (such as app_config)
$rsRolesCfg = az role assignment list --scope /subscriptions/******/resourceGroups/*******/providers/Microsoft.AppConfiguration/configurationStores/******-cfg01 | ConvertFrom-Json
$myRole = $rsRolesCfg | Where-Object roleDefinitionName -eq 'App Configuration Data Reader' | Where-Object id -like "*<app_config_resourceId>"
## principalId is the id of the object that get the role over the scope !
# GetsresourceId from PrincipalId / ObjetcId (without the '<>' on body, off course :) ) :
$resourceId = (az rest --method POST --url 'https://graph.microsoft.com/v1.0/directoryObjects/getByIds' --headers 'Content-Type=application/json' --body '{\"ids\":[\"<PrincipalId>\"]}' | ConvertFrom-Json | Select-Object value).value.alternativeNames[1]
Solution from How to Get Azure AD Object by Object ID Using Azure CLI (thanks a lot !)
I had to test it locally in powershell terminal... So it did not work as expected.
So then, I change a little bit the script and got the solution (next post, as solution from my problem).