Closed cgravill closed 1 year ago
This may already work and you just need to assign the ACRPull role to the the resource you want to access the container registry. What type of resource are you trying to access from?
That would be great.
It's a VM currently. Would we need create a service principal on the container registry? Doing this with Farmer is very new to me (but pleasant) so any direction is very welcome.
I tried things out and you can do this now. I'll work up an end to end walkthrough, but these are the pieces you need.
Prerequisite - you have an existing container registry.
az login --identity
az acr login -n <your-registry-name>
docker pull <image>
I assume you have a container registry already, so you can just reference the one you've got when creating a role assignment. Those are a little complicated just because they have to be named as a GUID that is both globally unique and deterministic so that if you redeploy, you'll use the same one.
// Define a VM and enable the system identity - this creates a managed identity for the VM that you will use to authenticate to the container registry.
let myVm =
vm {
name "my-server"
username "azureuser"
system_identity
vm_size Vm.Standard_B1ms
operating_system Vm.UbuntuServer_1804LTS
diagnostics_support
disable_password_authentication true
add_authorized_key "/home/azureuser/.ssh/authorized_keys" mySshPubKey
}
// The scope on the role assignment should be the container registry itself. Since you have an existing one, we can just use the ARM resource Id of that.
let containerRegistryResourceId =
{ Farmer.Arm.ContainerRegistry.registries.resourceId "your-registry"
with ResourceGroup = Some "resource-group-for-registry" }
// Now we need to define the role assignment. The hardest part about this is creating a globally unique and deterministic name for the role, and for now, I would just hardcode one.
let roleAssignment : Farmer.Arm.RoleAssignment.RoleAssignment =
{
Name = ResourceName "59126A57-255F-4E56-A5F2-F1909BA55436"
RoleDefinitionId = Roles.AcrPull
PrincipalId = myVm.SystemIdentity.PrincipalId
PrincipalType = Arm.RoleAssignment.PrincipalType.ServicePrincipal
Scope = Arm.RoleAssignment.SpecificResource containerRegistryResourceId
Dependencies = Set.singleton (myVm :> IBuilder).ResourceId
}
// Add the VM and the role assignment to a deployment and when you connect to the VM, you can login with `az login --identity` and it will use the system assign identity.
arm {
add_resource roleAssignment
add_resource myVm
}
Thanks @ninjarobot that's incredibly helpful - particularly the roleAssignment. That should remove the need for my generated PowerShell. Will try and let you know how it goes.
We're already creating unique ids as part of the deployment so no issue with that.
I've now integrated this general approach into our deployment, it's working great, thanks @ninjarobot
I've now integrated this general approach into our deployment, it's working great, thanks @ninjarobot
I'm really glad to hear it's working for you. Thanks for reaching out about it!
Cam this be closed?
The original request was skipped in favour of a more general approach. For my own needs I'm happy for it to be closed, and thanks gain @ninjarobot
I'd like to use system managed identity to access a container registry we're creating with Farmer. Something to similar to what's possible with key vaults: https://compositionalit.github.io/farmer/api-overview/resources/managed-identity/#example-system-identity
I'm currently achieving this with a post processing PowerShell script to grant the access but it would be far better directly in Farmer. I'm willing to have a go at creating a PR if it's a feature that would be welcome? I might need some pointers.