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).

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)

Notes on juju add-cloud

Type in Juju: azure.

Name in Juju: azure.

Notes on juju add-credential

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.

For some example workflows:

See Appendix: Example authentication workflows.

Authentication types

managed-identity (preferred)

Requirements:

  • Juju 3.6+.
  • A managed identity. See more: Appendix: How to create a managed identity.
  • The managed identity and the Juju resources must be created on the same subscription.
  • The add-credential steps must be run from either the Azure Cloud Shell^ or a jump host running in Azure in order to allow the cloud metadata endpoint to be reached.

This is the recommended way to authenticate with Azure as this way you are never touching your cloud credentials directly.

See more: Appendix: Example authentication workflows > Workflow 1

interactive = “service-principal-secret-via-browser”

This is the recommended way to authenticate with Azure if you want to use a service principal secret.

When you add the credential in this way and provide the subscription ID, Juju will open up a browser and you’ll be prompted to log in to Azure.

Note: If you are using the unconfined juju snap /snap/juju/current/bin/juju add-credential azure and have the azure CLI and you are logged in and you want to use the currently logged in user: You may leave the subscription ID empty – Juju will fill it in for you.

Either way, starting with Juju 3.6, you can also combine this authentication type with a managed identity by bootstrapping with the instance-role constraint.

See more: Appendix: Example authentication workflows > Workflows 2-3

service-principal-secret (dispreferred)

Starting with Juju 3.6, you can also combine this with a managed identity by bootstrapping with the instance-role constraint.

See more: Appendix: Example authentication workflows > Workflows 2-3

Notes on juju bootstrap

If during juju add-credential you chose interactive (= “service-principal-secret-via-browser”) or service-principal-secret: You can still combine this with a managed identity by running juju bootstrap with --constraints instance-role=....

See more: Appendix: Example authentication workflows > Workflow 2, Supported constraints

Cloud-specific model configuration keys

load-balancer-sku-name

Mirrors the LoadBalancerSkuName type in the Azure SDK.

type string
default value “Standard”
immutable false
mandatory true

resource-group-name

If set, use the specified resource group for all model artefacts instead of creating one based on the model UUID.

type string
default value schema.omit{}
immutable true
mandatory false

network

If set, use the specified virtual network for all model machines instead of creating one.

type string
default value schema.omit{}
immutable true
mandatory false

Supported constraints

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 (Juju creates a managed identity for you) 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>

Note: 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: Supported authentication types: Example 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:

Supported placement directives

Appendix: Example authentication workflows

Worflow 1 – Managed identity only (recommended)

Requirements:

  • Juju 3.6+.
  • A managed identity. See more: Appendix: How to create a managed identity.
  • The managed identity and the Juju resources must be created on the same subscription.
  • The add-credential steps must be run from either the Azure Cloud Shell^ or a jump host running in Azure in order to allow the cloud metadata endpoint to be reached.
  1. Create a managed identity. See more: Appendix: How to create a managed identity.
  2. Run juju add-credential azure; choose managed-identity; supply the requested information (the“managed-identity-path” must be of the form <resourcegroup>/<identityname>).
  3. Bootstrap as usual.

Did you know? With this workflow where you provide the managed identity during add-credential you avoid the need for either your Juju client or your Juju controller to store your credential secrets. Relatedly, the user running add-credential / bootstrap doesn’t need to have any credential secrets supplied to them.

Workflow 2 – Service principal secret + managed identity

Requirements:

  • Juju 3.6+.
  • A managed identity. See more: Appendix: How to create a managed identity.
  1. Create a managed identity.
  2. Add a service-principal-secret:
    • interactive = “service-principal-via-browser” (recommended):
      • If you have the azure CLI and you are logged in and you want to use the currently logged in user: Run /snap/juju/current/bin/juju add-credential azure; choose interactive, then leave the subscription ID field empty – Juju will fill this in for you.
      • Otherwise: Run juju add-credential azure, choose interactive, then provide the subscription ID – Juju will open up a browser and you’ll be prompted to log in to Azure.
    • service-principal-secret: Run juju add-credential azure, then choose service-principal-secret and supply all the requested information.
  3. During bootstrap, provide the managed identity to the controller by using the instance-role constraint.

Did you know? With this workflow where you provide the managed identity during bootstrap you avoid the need for your Juju controller to store your credential secrets. Relatedly, the user running / bootstrap doesn’t need to have any credential secrets supplied to them.

Workflow 3 – Service principal secret only (dispreferred)

  1. Add a service-principal-secret:
    • interactive = “service-principal-via-browser” (recommended):
      • If you have the azure CLI and you are logged in and you want to use the currently logged in user: Run /snap/juju/current/bin/juju add-credential azure; choose interactive, then leave the subscription ID field empty – Juju will fill this in for you.
      • Otherwise: Run juju add-credential azure, choose interactive, then provide the subscription ID – Juju will open up a browser and you’ll be prompted to log in to Azure.
    • service-principal-secret: Run juju add-credential azure, then choose service-principal-secret and supply all the requested information.
  2. Bootstrap as usual.

Appendix: How to create a managed identity

This is just an example. For more information please see the upstream cloud documentation. See more: Microsoft Azure | Managed identities.

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}"


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

Few comments on this doc:

notes on bootstrap: (1) (recommended) (1a) Create the managed identity.

We are saying that recommended way is the one that currently exists only in juju 3.6-beta2. Should we recommend something that exists in stable juju as most of the users would use a stable version? Also, there are no notes on bootstrap of the ‘service-principal-secret’ way at all, which is the main option for stable juju now. Would be good to add those.

notes on bootstrap:

(1) (recommended) (1a) Create the managed identity. …

(2) (2a) Create the managed identity yourself. …

(3) (3a) Create a credential type service-principal-secret …

This section is the same is in the other doc by wallyfworld, however sections are rephrased and options 2 and 3 are switched places comparing to wallyfworld’s doc. This creates confusion. I suggest having the same names for options and having them in the same order.

1 Like

I’ll add more information on the service-principal-secret.

About the recommendation to use an option that is only available in beta: Fair point. I’ll keep the recommendation but caveat that it requires at least 3.6 beta.

About the other post: It was not intended as a doc (i.e., permanent content) – just an announcement. But I can see how having two sources can be confusing. I’ll work with you to update this doc and then make the announcement merely point to the doc (instead of trying to give the instructions again).

Thanks!