Skip to main content
Configure the proper Azure service principal permissions to enable Cloudgeni’s comprehensive Terraform validation, drift detection, and infrastructure analysis. Different validation scenarios require different permission levels.

Prerequisites

  • Azure subscription with administrative access
  • Existing Cloudgeni service principal (from Azure Defender setup)
  • Terraform infrastructure in Azure
  • Time estimate: 5-10 minutes

Permission Levels Overview

Cloudgeni requires different permission levels based on your Terraform infrastructure complexity:📖 Reader Access (Basic):
  • Read resource configurations and metadata
  • Validate most Terraform resources
  • Detect configuration drift
  • Limitation: Cannot access secrets, state files, or manage RBAC
✏️ Contributor Access (Enhanced):
  • All Reader permissions
  • Access Key Vault secrets for variable validation
  • Read Terraform state from storage accounts
  • Validate complex resource dependencies
  • Limitation: Cannot manage user access and RBAC
👑 User Access Administrator (Complete):
  • All Contributor permissions
  • Validate RBAC assignments and role definitions
  • Analyze user permissions and access patterns
  • Complete infrastructure validation coverage
Start with Reader access and upgrade permissions based on your validation needs.

Step 1: Basic Reader Access

Reader access enables basic Terraform validation for most resources:
# Grant Reader role to existing service principal
az role assignment create \
  --assignee {service-principal-id} \
  --role "Reader" \
  --scope "/subscriptions/{subscription-id}"
What this enables:
  • Virtual machines, networks, and storage validation
  • Resource group and subscription-level analysis
  • Basic configuration drift detection
  • Cost optimization recommendations
Terraform resources validated:
# These resources work with Reader access
resource "azurerm_virtual_network" "main" {
  name                = "vnet-production"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
}

resource "azurerm_virtual_machine" "web" {
  name                = "vm-web-server"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  # ... configuration
}

Step 2: Enhanced Contributor Access

Contributor access enables validation of secrets, state files, and complex dependencies:
# Grant Contributor role for enhanced validation
az role assignment create \
  --assignee {service-principal-id} \
  --role "Contributor" \
  --scope "/subscriptions/{subscription-id}"

# Alternative: Scope to specific resource groups
az role assignment create \
  --assignee {service-principal-id} \
  --role "Contributor" \
  --scope "/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}"
Additional capabilities:
  • Access Key Vault secrets for variable validation
  • Read Terraform state from storage accounts
  • Validate encrypted storage and databases
  • Analyze network security configurations
Terraform scenarios requiring Contributor:

Key Vault Variable Access

# Requires Contributor to access secrets
data "azurerm_key_vault" "main" {
  name                = "kv-production-secrets"
  resource_group_name = "rg-security"
}

data "azurerm_key_vault_secret" "db_password" {
  name         = "database-password"
  key_vault_id = data.azurerm_key_vault.main.id
}

resource "azurerm_sql_server" "main" {
  administrator_login_password = data.azurerm_key_vault_secret.db_password.value
  # ... other configuration
}

Remote State Access

# Backend configuration requiring storage account access
terraform {
  backend "azurerm" {
    resource_group_name  = "rg-terraform-state"
    storage_account_name = "tfstateproduction"
    container_name       = "tfstate"
    key                  = "production.terraform.tfstate"
  }
}

Private Endpoint Validation

# Complex networking requiring enhanced permissions
resource "azurerm_private_endpoint" "sql" {
  name                = "pe-sql-production"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  subnet_id           = azurerm_subnet.private.id
  
  private_service_connection {
    name                           = "psc-sql"
    private_connection_resource_id = azurerm_sql_server.main.id
    subresource_names              = ["sqlServer"]
    is_manual_connection           = false
  }
}

Step 3: Complete RBAC Access

User Access Administrator enables complete RBAC validation when you manage user permissions in Terraform:
# Grant User Access Administrator for RBAC validation
az role assignment create \
  --assignee {service-principal-id} \
  --role "User Access Administrator" \
  --scope "/subscriptions/{subscription-id}"

# Alternative: Management Group scope for multi-subscription
az role assignment create \
  --assignee {service-principal-id} \
  --role "User Access Administrator" \
  --scope "/providers/Microsoft.Management/managementGroups/{management-group-id}"
Complete validation capabilities:
  • RBAC role assignments and definitions
  • User and group permission analysis
  • Service principal access validation
  • Complete security posture assessment
RBAC Terraform scenarios:

Custom Role Definitions

# Requires User Access Administrator to validate
resource "azurerm_role_definition" "custom_reader" {
  name        = "Custom Storage Reader"
  scope       = data.azurerm_subscription.primary.id
  description = "Can read storage accounts and containers"
  
  permissions {
    actions = [
      "Microsoft.Storage/storageAccounts/read",
      "Microsoft.Storage/storageAccounts/listKeys/action",
      "Microsoft.Storage/storageAccounts/blobServices/containers/read"
    ]
    not_actions = []
  }
  
  assignable_scopes = [
    data.azurerm_subscription.primary.id,
  ]
}

Role Assignments

# User and group role assignments
resource "azurerm_role_assignment" "developer_access" {
  scope                = azurerm_resource_group.development.id
  role_definition_name = "Contributor"
  principal_id         = data.azuread_group.developers.object_id
}

resource "azurerm_role_assignment" "app_identity" {
  scope                = azurerm_key_vault.main.id
  role_definition_name = "Key Vault Secrets User"
  principal_id         = azurerm_user_assigned_identity.app.principal_id
}

Managed Identity Validation

# Service principal and managed identity permissions
resource "azurerm_user_assigned_identity" "aks_identity" {
  name                = "id-aks-production"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
}

resource "azurerm_role_assignment" "aks_network" {
  scope                = azurerm_virtual_network.main.id
  role_definition_name = "Network Contributor"
  principal_id         = azurerm_user_assigned_identity.aks_identity.principal_id
}

Verification and Testing

Test your service principal permissions to ensure proper Terraform validation:

Check Current Permissions

# List current role assignments
az role assignment list \
  --assignee {service-principal-id} \
  --subscription {subscription-id} \
  --output table

# Check specific resource access
az keyvault secret show \
  --vault-name {key-vault-name} \
  --name {secret-name} \
  --query "value" \
  --output tsv

Cloudgeni Validation Test

  1. Go to “Remediation” in Cloudgeni dashboard
  2. Select your Azure subscription/project
  3. Run “Generate Fixes” to trigger validation
  4. Check validation status indicators:
    • 🟢 Green validation - All permissions working correctly
    • 🔴 Red validation - Basic access issues
Validation Success Indicators:
  • Complete resource inventory and drift detection
  • Variable validation from Key Vault secrets
  • State file analysis and consistency checks
  • RBAC permission analysis and recommendations
  • AI-generated remediation suggestions

Permission Scoping Best Practices

Configure minimal required permissions for your specific use case:

Resource Group Scoping

# Limit Contributor access to specific resource groups
az role assignment create \
  --assignee {service-principal-id} \
  --role "Contributor" \
  --scope "/subscriptions/{subscription-id}/resourceGroups/rg-terraform-managed"

# Keep Reader at subscription level
az role assignment create \
  --assignee {service-principal-id} \
  --role "Reader" \
  --scope "/subscriptions/{subscription-id}"

Key Vault Specific Access

# Grant specific Key Vault permissions instead of full Contributor
az keyvault set-policy \
  --name {key-vault-name} \
  --spn {service-principal-id} \
  --secret-permissions get list

Time-Bounded Access

# Use Azure PIM for time-limited elevated access
az ad signed-in-user show --query objectId

# Configure Just-In-Time access for sensitive operations
# (Requires Azure AD Premium P2)
Recommended Permission Matrix:
Terraform ScenarioReaderContributorUser Access Admin
Basic resources
Key Vault secrets
Remote state
RBAC management
Custom roles
Complete validation

Troubleshooting

Validation Incomplete:
  • Check service principal has sufficient permissions
  • Verify scope of role assignments
  • Ensure Key Vault access policies are configured
State File Access Denied:
  • Grant Contributor access to storage account resource group
  • Check storage account firewall settings
  • Verify Terraform backend configuration
RBAC Validation Fails:
  • Ensure User Access Administrator role is assigned
  • Check if custom roles exist in correct scope
  • Verify managed identity permissions
Key Vault Secrets Unavailable:
  • Check Key Vault access policies
  • Verify service principal has get and list secret permissions
  • Ensure Key Vault is not behind private endpoint without access
Permission Denied Errors:
# Debug permission issues
az role assignment list \
  --assignee {service-principal-id} \
  --all \
  --include-inherited \
  --output table

# Check effective permissions
az role assignment list \
  --assignee {service-principal-id} \
  --scope {resource-scope} \
  --include-inherited

What’s Next?

Need Help?

Having Issues?

I