Terraform: Add Azure IAM Role
Description:
In this post, I will show how I create a custom Azure AD Role and assign it to a System Identity using Terraform. I actually didn’t use terraform to create the role like I should have but used powershell. I see now that I could have used role_definition but here is what I did for a role that can start/stop VMs, AKS clusters, and App Gateways:
To Resolve:
-
First I manually connected to Azure using powershell and created a custom role using a flow I use often:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
$SubIDList = [System.Collections.Generic.List[PSObject]]@() $Subs = Get-AzSubscription Foreach ( $Sub in $Subs) { $subId = $($Sub.Id) $subStr = "/subscriptions/" + $subId [void]$SubIDList.Add($subStr) } # Create custom role $role = Get-AzRoleDefinition "Reader" $role.Id = $null $role.Name = 'Custom_Start_Stop' $role.Description = 'Has access to start and stop various resources.' $role.Actions.Add('Microsoft.Compute/virtualMachines/start/action') $role.Actions.Add('Microsoft.Compute/virtualMachines/deallocate/action') $role.Actions.Add('Microsoft.Network/applicationGateways/start/action') $role.Actions.Add('Microsoft.Network/applicationGateways/stop/action') $role.Actions.Add('Microsoft.ContainerService/managedClusters/stop/action') $role.Actions.Add('Microsoft.ContainerService/managedClusters/start/action') $role.AssignableScopes.Clear() Foreach ( $Sub in $SubIDList) { $role.AssignableScopes.Add($Sub) } New-AzRoleDefinition -Role $role # Output: # > New-AzRoleDefinition -Role $role # Name : Custom_Start_Stop # Id : some-id # IsCustom : True # Description : Has access to start and stop various resources. # Actions : {*/read, Microsoft.Compute/virtualMachines/start/action, Microsoft.Compute/virtualMachines/deallocate/action, Microsoft.Network/applicationGateways/start/action...} # NotActions : {} # DataActions : {} # NotDataActions : {} # AssignableScopes : {/subscriptions/some-id, /subscriptions/some-id-2, ...}
- Note that the AssignableScopes needs the format (
/subscriptions/
+subscription id
) so I first created a list object and looped through all subscriptions to populate it. - Next I created the role based on built-in Reader as this is what I usually start with when creating a custom role
- Then I add the actions I think will be needed.
- Then I clear all Assignable Scopes and only add the ones I know the role can be used for. In many cases this list will be much smaller but this is just an example.
- Note that the AssignableScopes needs the format (
-
Now that the role exists, I can just add the role using Terraform just like usual using the
azurerm_role_assignment
resource:- You can see an example here where the role scope is at the subscription level by readg it in first:
1 2 3 4 5 6 7 8
data "azurerm_subscription" "primary" { } resource "azurerm_role_assignment" "example" { scope = data.azurerm_subscription.primary.id role_definition_name = "Reader" principal_id = azurerm_automation_account.aa.identity[0].principal_id }
- And then the principle_id is the identity of the Automation Account. This is a common pattern that you will use when using terraform.
Comments