The Microsoft Azure cloud and Juju

List of supported clouds > Microsoft Azure

This document describes details specific to using your existing Microsoft Azure cloud with Juju.

See more: Microsoft Azure

When using the Microsoft Azure cloud with Juju, it is important to keep in mind that it is a (1) machine cloud and (2) not some other cloud.

See more: Cloud differences in Juju

As the differences related to (1) are already documented generically in our Tutorial, How-to guides, and Reference docs, here we record just those that follow from (2).

Juju points of variation Notes for the Microsoft Azure cloud
setup (chronological order):
CLOUD
supported versions:
requirements: If you’re in a locked-down environment:
Permissions:

- Microsoft.Compute/skus (read)

- Microsoft.Resources/subscriptions/resourceGroups (read, write, delete)

- Microsoft.Resources/deployments/ (write/read/delete/cancel/validate)

- Microsoft.Network/networkSecurityGroups (write, read, delete, other - join)

- Microsoft.Network/virtualNetworks/ (write, read, delete)

- Microsoft.Compute/virtualMachineScaleSets/ (write, read, delete, other - start action, other - deallocate action, other - restart action, other powerOff action)

- Microsoft.Network/virtualNetworks/subnets/ (read, write, delete, other - join)

- Microsoft.Compute/availabilitySets (write, read, delete)

- Microsoft.Network/publicIPAddresses (write, read, delete, other - join - optional for public services)

- Microsoft.Network/networkInterfaces (write, read, delete, other - join)

- Microsoft.Compute/virtualMachines (write, read, delete, other - start, power off, restart, deallocate)

- Microsoft.Compute/disks (write, read, delete)

definition: :information_source: Juju automatically defines a cloud of this type.
- name: azure or user-defined
- type: azure
- authentication types: [interactive, service-principal-secret, managed-identity] (managed-identity only starting with Juju 3.6)
- regions: [TO BE ADDED]
- cloud-specific model configuration keys: load-balancer-sku-name (string)
Mirrors the LoadBalancerSkuName type in the Azure SDK.

network (string)
If set, uses the specified virtual network for all model machines instead of creating one.

resource-group-name (string)
If set, uses the specified resource group for all model artefacts instead of creating one based on the model UUID.

CREDENTIAL
definition: auth-type: interactive, service-principal-secret, (starting with Juju 3.6) managed-identity.

:warning: If your credential stops working: Credentials for the azure cloud have been reported to occasionally stop working over time. If this happens, try juju update-credential (passing as an argument the same credential) or juju add-credential (passing as an argument a new credential) + juju default-credential.

CONTROLLER
notes on bootstrap: Starting with Juju 3.6, you can authenticate the controller with the cloud using managed identities. There are 3 possible workflows:

(1) (credentialless bootstrap, recommended) Create the managed identity yourself, then add a credential type managed-identity, then bootstrap as usual. Requirements: The managed identity and the Juju resources must be created on the same subscription. You’ll also need to run all the steps from either the Azure Cloud Shell^ or a jump host running in Azure in order to allow the cloud metadata endpoint to be reached.

(2) Create the managed identity yourself, create a regular credential type service-principal-secret and use it to bootstrap, during bootstrap use the instance-role constraint to pass the path to the managed identity.

(3) Create a service-principal-secret type credential and use it to boostrap but, during bootstrap, use the instance-role constraint with the auto value – that will cause Juju to set up a managed identity for you that the controller can then use).

If you want your controller to be in the same resource group as the one used for the managed identity, during bootstrap also specify --config resource-group-name=<theresourcegroup>.

> See more: Appendix: Example managed identity workflows.

other (alphabetical order:)
CONSTRAINT
conflicting: [instance-type] vs [arch, cores, mem]
supported?
- allocate-public-ip :white_check_mark:
- arch :white_check_mark:
Valid values: amd64.
- container :white_check_mark:
- cores :white_check_mark:
- cpu-power :x:
- image-id :x:
- instance-role Starting with Juju 3.6: :white_check_mark:

Valid values: auto or a managed identity^ name in one of the following formats:

- If the managed identity is created in a resource group on the same subscription:
<resource group>/<identity name>

- If the managed identity is created in a resource group on a different subscription:
<subscription>/<resource group>/<identity name>

- If the managed identity is created in a resource group and that resource group is used to host the controller model:
<identity name>
e.g., juju bootstrap azure --config resource-group-name=<resource group> --constraints instance-role=<identity name>

> See more: Appendix: Example managed identity workflows.

- instance-type :white_check_mark:
Valid values: See cloud provider.
- mem :white_check_mark:
- root-disk :white_check_mark:
- root-disk-source :white_check_mark:
Represents the juju storage pool for the root disk. By specifying a storage pool, the root disk can be configured to use encryption.
- spaces :x:
- tags :x:
- virt-type :x:
- zones :white_check_mark:
PLACEMENT DIRECTIVE
<machine> TBA
subnet=... :white_check_mark:
system-id=... :x:
zone=... TBA
MACHINE
RESOURCE (cloud)

Consistent naming, tagging, and the ability to add user-controlled tags to created instances.

:x:

Appendix: Example managed identity workflows

User-created managed identity

1. Create the managed identity

To create a managed identity for Juju to use, you will need to use the Azure CLI and be logged in to your account. This is a set up step that can be done ahead of time by an administrator.

The 4 values below need to be filled in according to your requirements.

$ export group=someresourcegroup
$ export location=someregion
$ export role=myrolename
$ export identityname=myidentity
$ export subscription=mysubscription_id

The role definition and role assignment can be scoped to either the subscription or a particular resource group. If scoped to a resource group, this group needs to be provided to Juju when bootstrapping so that the controller resources are also created in that group.

For a subscription scoped managed identity:

$ az group create --name "${group}" --location "${location}"
$ az identity create --resource-group "${group}" --name "${identityname}"
$ mid=$(az identity show --resource-group "${group}" --name "${identityname}" --query principalId --output tsv)
$ az role definition create --role-definition "{
  	\"Name\": \"${role}\",
  	\"Description\": \"Role definition for a Juju controller\",
  	\"Actions\": [
            	\"Microsoft.Compute/*\",
            	\"Microsoft.KeyVault/*\",
            	\"Microsoft.Network/*\",
            	\"Microsoft.Resources/*\",
            	\"Microsoft.Storage/*\",
            	\"Microsoft.ManagedIdentity/userAssignedIdentities/*\"
  	],
  	\"AssignableScopes\": [
        	\"/subscriptions/${subscription}\"
  	]
  }"
$ az role assignment create --assignee-object-id "${mid}" --assignee-principal-type "ServicePrincipal" --role "${role}" --scope "/subscriptions/${subscription}"

A resource scoped managed identity is similar except:

  • the role definition assignable scopes becomes
      \"AssignableScopes\": [
            \"/subscriptions/${subscription}/resourcegroups/${group}\"
      ]
  • the role assignment scope becomes

--scope "/subscriptions/${subscription}/resourcegroups/${group}"

2a. Add a credential type managed identity, then bootstrap as usual

Recommended.

Requirements: You’ll need to do this from either the Azure Cloud Shell (https://shell.azure.com/) or a jump host running in Azure in order to allow the cloud metadata endpoint to be reached.

# Create a managed identity credential:

$ juju add-credential azure --client
Enter credential name: test
Regions
  centralus
  eastus
  eastus2
  ...
  polandcentral

Select region [any region, credential is not region specific]:
Auth Types
  interactive
  service-principal-secret
  managed-identity

Select auth type [interactive]: managed-identity
Enter managed-identity-path: somegroup/myidentity # 
Enter subscription-id: 2eebf55a-1e02-45d8-a299-02aed8aea00b
Credential "test" added locally for cloud "azure".

The “managed-identity-path” is of the form <resourcegroup>/<identityname>

Now bootstrap.

$ juju bootstrap azure mycontroller

If you want the controller to be in the same resource group as used for the managed identity created above, then specify it at bootstrap.

$ juju bootstrap azure --config resource-group-name=somegroup mycontroller

Be aware though that in the above scenario, the managed identity will be deleted when the controller is destroyed.

2b. Add a credential as usual, then attach the managed identity to your controller during bootstrap

Makes it possible to use different subscriptions for the Juju resources vs. the managed identity


# Add a credential type service-principal-secret
# ...

# Bootstrap using the managed identity:
juju bootstrap azure --constraints "instance-role=subscription/resourcegroup/identityname"

Juju-created managed identity

Add a credential as usual, then attach a Juju-generated managed identity to your controller during bootstrap:

# Add a credential type service-principal-secret
#  ...

# Get Juju to create a managed identity during bootstrap:
juju bootstrap azure --constraints "instance-role=auto"


Contributors: @kylerhornor , @tmihoc, @wallyworld

@timClicks I added a note here about the add-credential operation re-requesting authentication, which seems to happen sometimes. The rest of the instructions seem good as of today :slight_smile:

Thanks for taking the time to make the change :slight_smile:

Suggest removing the email address in the cloud credentials initialisation config example.

- allocate-public-id

is a typo. Should be ip

@kylerhornor Fixed, thanks! (PS Added you to the Contributors list on the bottom of the doc.)

1 Like