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
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
.
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 |
|
- arch |
Valid values: amd64 . |
- container |
|
- cores |
|
- cpu-power |
|
- image-id |
|
- instance-role |
Starting with Juju 3.6: Valid values: - If the managed identity is created in a resource group on the same subscription: - If the managed identity is created in a resource group on a different subscription: - If the managed identity is created in a resource group and that resource group is used to host the controller model: 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 > See more: Appendix: Supported authentication types: Example workflows. |
- instance-type |
Valid values: See cloud provider. |
- mem |
|
- root-disk |
|
- root-disk-source |
Represents the juju storage pool for the root disk. By specifying a storage pool, the root disk can be configured to use encryption. |
- spaces |
|
- tags |
|
- virt-type |
|
- zones |
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.
- Create a managed identity. See more: Appendix: How to create a managed identity.
- Run
juju add-credential azure
; choosemanaged-identity
; supply the requested information (theâmanaged-identity-pathâ must be of the form<resourcegroup>/<identityname>
). - 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.
- Create a managed identity.
- 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
; chooseinteractive
, then leave the subscription ID field empty â Juju will fill this in for you. - Otherwise: Run
juju add-credential azure
, chooseinteractive
, then provide the subscription ID â Juju will open up a browser and youâll be prompted to log in to Azure.
- If you have the
service-principal-secret
: Runjuju add-credential azure
, then chooseservice-principal-secret
and supply all the requested information.
- 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)
- 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
; chooseinteractive
, then leave the subscription ID field empty â Juju will fill this in for you. - Otherwise: Run
juju add-credential azure
, chooseinteractive
, then provide the subscription ID â Juju will open up a browser and youâll be prompted to log in to Azure.
- If you have the
service-principal-secret
: Runjuju add-credential azure
, then chooseservice-principal-secret
and supply all the requested information.
- 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