Introduction
Problem
A user is using the azuread_group data source to get information about an AzureAD Group [a]. The AzureAD provider is configured to run under a Service Principal with Client Secret or Certificate [b]. The Terraform run fails with the following errors:
Error: No group found matching specified filter
GroupsClient.BaseClient.Get(): unexpected status 403 with OData error: Authorization_RequestDenied: Insufficient privileges to complete the operation.
Example Configuration
terraform {
required_providers {
azuread={
source = "hashicorp/azuread"
version = ">= 2.33.0, < 3.0.0"
}
}
}
provider "azuread" {
# Configure client_id, client_secret, and tenant_id or as environment variables [c]
}
data "azuread_group" "test" {
display_name = "test-group"
}
Cause
This error, returned from AzureAD, clearly states that your Service Principal does not have the correct permissions for the operation.
You can execute TF_LOG=TRACE terraform apply 2>&1 | tee apply.log
to get a verbose log. Search "AzureAD Provider access token claims" (see below and notice "roles": null and "scp": "").
Unsuccessful apply trace log
AzureAD Provider access token claims:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/REDACTED/",
"idp": "https://sts.windows.net/REDACTED/",
"oid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"roles": null,
"scp": "",
"sub": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenant_region_scope": "NA",
"tid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"ver": "1.0",
"app_displayname": "name-of-service-principal",
"appid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"idtyp": "app"
}
Troubleshooting
Go through each step in Configuring a User or Service Principal for managing Azure Active Directory and double check it was done correctly [d].
Step 1
In the Azure Portal, navigate to "Azure Active Directory", then click "App Registrations". Click your Service Principal (or create "New Registration").
Step 2
Under "Essentials", copy client_id and tenant_id.
- Application (client) ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- Directory (tenant) ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Step 3
- Create/Read Client Secret. Click "Client credentials: X certificate, X secret".
- Copy the secret VALUE.
- This is your client_secret: XXxxxXXxXxxXxxxxxxxxxXXxxxxXxxxxxxXxxxXxx
Step 4
Navigate to your configuration (e.g., main.tf). Pass your client_id, tenant_id, and client_secret credentials using environment variables OR configure the AzureAD provider to use them like this:
# sh
$ exportARM_CLIENT_ID="00000000-0000-0000-0000-000000000000"
$ exportARM_CLIENT_SECRET="MyCl1eNtSeCr3t"
$ exportARM_TENANT_ID="10000000-2000-3000-4000-500000000000"
OR
# PowerShell
$env:ARM_CLIENT_ID = "00000000-0000-0000-0000-000000000000"
$env:ARM_CLIENT_SECRET = "MyCl1eNtSeCr3t"
$env:ARM_TENANT_ID = "10000000-2000-3000-4000-500000000000"
OR
# If using this approach, we recommend configuring them as sensitive input variables and not plain text.
provider "azuread" {
client_id = "foo"
client_secret = "bar"
tenant_id = "baz"
}
Step 5
Navigate back to your Service Principal in the Azure Portal and click "API Permissions" . You want to see Group.Read.All
under Microsoft Graph.
If you do not see this permission you must add it by clicking "Add a permission", then "Microsoft Graph", "Application permissions", and search for "Group.Read.All" (see Azure Portal screen capture below).
Azure Portal screen capture
Step 6
Now you must grant consent. Just above the permission names, you will see a button "Grant Admin Consent for XXX", click that button and confirm (see Grant consent below).
Step 7
Execute terraform apply
and you should no longer see the 403 error.
AzureAD Provider access token claims:
{
"aud": "https://graph.microsoft.com",
"iss": "https://sts.windows.net/REDACTED/",
"idp": "https://sts.windows.net/REDACTED/",
"oid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"roles": [
"Group.Read.All"
],
"scp": "",
"sub": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"tenant_region_scope": "NA",
"tid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"ver": "1.0",
"app_displayname": "name-of-service-principal",
"appid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"idtyp": "app"
}