Contents:
Add cloud
Juju already has knowledge of the Azure cloud, which means adding your Azure account to Juju is quick and easy.
You can see more specific information on Juju’s Azure support (e.g. the supported regions) by running:
juju show-cloud azure
To ensure that Juju’s information is up to date (e.g. new region support), you can update Juju’s public cloud data by running:
juju update-public-clouds
Add credentials
The Credentials page offers a full treatment of credential management.
Several steps are required to add Azure credentials to Juju:
- Install the CLI tool
- Log in to Azure
- Import the credentials
Azure account credentials have been reported to expire. If a previously working setup suddenly behaves as if incorrect credentials are being used then you may need to update the credentials on the controller. See Updating remote credentials for guidance.
Alternately, you can use your credentials with Juju as a Service, where charms can be deployed within a graphical environment that comes equipped with a ready-made controller.
A note on permissions in locked-down environments
As of this writing, the Azure account needs, at minimum, the following permissions, in order to enable fully automated provisioning of Virtual Machines with attached storage with Juju. (In most public cloud environments, you’ll have these permissions by default, and can skip this section.)
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)
Install the CLI tool
You will need to import your Azure credentials into Juju using the Azure CLI 2.0 tool from Microsoft.
Ubuntu/Linux users can install Azure CLI 2.0 with the following command:
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
For instructions that cover installing Azure CLI on Microsoft Windows and Apple macOS, see Microsoft’s Install Azure CLI 2.0 documentation.
If the installer encounters any difficulties it will let you know. Examples include the inability to find your system’s Python interpreter or missing software dependencies. Run any commands that the installer suggests in order to rectify these deficiencies. You may need to prepend sudo
to some commands (only do this if needed). After each command, rerun the above curl
command. Accept the suggested default answers to any questions it may ask (by just pressing ‘Enter’).
For Ubuntu 20.04 (focal) and later, no additional setup steps are needed.
For Ubuntu 18.04 (bionic) the following commands are needed prior to the curl
command:
sudo ln -s /usr/bin/python3 /usr/bin/python
sudo apt install python3-distutils gcc python3-dev
At the end you will be asked to run exec -l $SHELL
to restart your shell.
Verify that the tool is properly installed by running az --version
.
Log in to Azure
Log in to your Azure account in order to display the credentials that you will, in turn, provide to Juju:
az login
This will output a URL and a code, for example:
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code D6FRLOY6U to authenticate.
After entering the code the web site should show ‘Microsoft Azure Cross-platform Command Line Interface’. Press the ‘Continue’ button. The resulting page will ask you to “Pick an account”. This is just the email address that you’ve associated with your Azure account. Click on it. You are now logged in to your Azure account.
Import the credentials
Back on the command line, the output from az login
should now display your Azure account information:
[
{
"cloudName": "AzureCloud",
"id": "f717c8c1-8e5e-4d38-be7f-ed1e1c879e18",
"isDefault": true,
"name": "Pay-As-You-Go",
"state": "Enabled",
"tenantId": "0fb95fd9-f42f-4c78-94c9-e3d01c2bc5af",
"user": {
"name": "javierlarin72@gmail.com",
"type": "user"
}
}
]
Now initiate the process to import your Azure credentials into Juju:
juju add-credential azure
You will first be asked for an arbitrary credential name (e.g. ‘ubuntu’). Secondly, you will be asked to select an ‘Auth Type’ from among the following two methods:
- interactive
- service-principal-secret
The default choice is interactive
and it is the recommended method. It is far quicker and easier than the manual service-principal-secret
method. Here, we’ll assume that ‘interactive’ has been chosen.
For guidance on the manual method, see Manually adding Azure credentials. Use this method if the interactive option fails, or if you want to automate the configuration process.
You then will be asked for your subscription id. In the example above, it is ‘f717c8c1-8e5e-4d38-be7f-ed1e1c879e18’. The recommended way is to simply press ‘Enter’ and let the tool automatically retrieve what’s needed. If you do so, after a few seconds you will see the following (assuming ‘ubuntu’ is the credential name):
Credential "ubuntu" added locally for cloud "azure".
You may once again be asked to visit the https://microsoft.com/devicelogin site and enter a code. In this case it is important to verify that the credential process is complete before closing the authentication window.
You can also verify that the credentials were successfully added by running juju credentials
.
Create a controller
You are now ready to create a Juju controller for cloud ‘azure’:
juju bootstrap azure azure-controller
Above, the name given to the new controller is ‘azure-controller’. Azure will provision an instance to run the controller on.
This will result in the controller environment being visible in the Azure portal.
For a detailed explanation and examples of the bootstrap
command see the Creating a controller page.
Spaces support
The Azure provider supports network spaces.
juju subnets
will show the subnets Juju knows about for a given model.
To add a space in one of the available subnets:
juju add-space foo 192.169.2.0/24
and now add a machine in that space:
juju add-machine --constraints="space=foo"
This will create a machine and use “subnet1 192.169.2.0/24” for the network
configuration of the primary NIC machine-X-primary
. If no space is specified, Juju will default to using a subnet called juju-internal-network
in the configured vnet.
You can create another space:
juju add-space bar 192.168.3.0/24
and create a machine in both spaces:
juju add-machine --constraints="spaces=foo,bar"
A machine gets created with 2 NICs, machine-X-primary
and machine-X-interface-1
.
Each NIC is bound to the subnet of each space.
If you do this instead (ie a space with multiple subnets):
juju add-space foobar 192.169.2.0/24 192.169.3.0/24
juju add-machine --constraints="spaces=foobar"
Then the machine only gets one NIC and one of the subnets is chosen at random.
Azure-specific features
Azure accounts are initially limited to 10 cores (trial accounts can be even lower). You will need to file a support ticket with Azure to raise your quota limit.
Juju supports a number of Azure specific features:
- availability set support
- bring your own resource group
- bring your own virtual network
- full disk encryption on instance volumes
Availability sets
As long as at least two units are deployed, Azure guarantees 99.95% availability of the application overall. Exposed ports are automatically load-balanced across all units within the application. Using availability sets disables manual placement and the add-machine
command.
Availability sets work differently from zones, but serve the same basic purpose. With zones, Juju directly ensures each unit of a distribution group is placed into a different zone. With sets, Juju places each unit of a distribution group into the same set, and Azure will then try to ensure that not all units in the set will become unavailable at the same time.
Availability sets are not enforced when unit placement (i.e. the --to
option for the deploy
or add-unit
commands) is used.
When creating a new machine, the algorithm used for choosing the availability set is:
- if the machine is a controller, use the availability set name
juju-controller
- if the machine has units assigned, create an availability set with a name based on the value of the
tags.JujuUnitsDeployed
tag in vmTags, if it exists - otherwise, do not assign the machine to an availability set
Custom resource groups
By default, Juju will create a new resource group for each model, to hold the artifacts for that model.
Sometimes, permissions will be such that the user does not have rights to create new resource groups, but they can use existing groups. Juju models can be configured to use such pre-existing resource groups using the resource-group-name
model config, eg
juju add-model test --config resource-group-name=myresgroup
It’s also possible to bootstrap using an existing resource group for the controller model, eg
juju bootstrap azure --config resource-group-name=myresgroup --no-default-model
Note that the --no-default-model
option is required to ensure Juju does not create an additional “default” model in a new resource group as would normally occur.
Note: When destroying a controller containing models with BYO resource groups, those resource groups will need to be cleaned up manually since there’s a limitation in how Juju tears down a controller, preventing those groups from being cleaned up up automatically.
Custom virtual network
It’s possible to use an existing virtual network when provisioning instances. Say there’s an existing resource group containing a virtual network
|- test-rg
|- test-vn
|- juju-controller-subnet 192.169.2.0/24
|- subnet2 192.169.3.0/24
The network
model config attribute can be used to specify this network be used instead of Juju creating a new one:
juju add-model --config network=test-rg/test-vn
Depending on spaces setup (see below), the machine can be provisioned with NICs on each subnet.
If the specified virtual network has a security group already, Juju will use that, otherwise it will create a new one called juju-internal-nsg
.
Placement also works, eg to choose one of the subnets in the vnet:
juju deploy mysql --to subnet=subnet2
Note: For bootstrap, if space constraints are not used to specify a particular subnet, Juju will prefer a subnet called juju-controller-subnet
to use for the controller’s primary NIC. If a so named subnet does not exist, Juju will choose one at random, or else error. A simple option for specifying a particular non-default subnet to use (if spaces are not set up) is to use placement:
juju bootstrap azure --config network=test-rg/test-vn --to subnet=subnet2
You must also ensure that the subnet has a security group which is configured to allow incoming traffic to the following ports:
- 22 (for bootstrap to use ssh to provision the instance)
- 17070 (to allow Juju clients and agents to connect to the controller API server)
Full disk encryption
When provisioning an Azure instance, it is possible to ask for root disk encryption using a disk encryption set and a key vault.
You can either use your own disk encryption set or have Juju create a key vault and disk encryption set. Right now, the key size and algorithm is not user configurable. It’s RSA and 4096 bits.
The provisioning is configured using a Juju storage pool. The configurable parameters are:
- encrypted (must be true for Juju to act on it)
- disk-encryption-set-name (defaults to vault name prefix)
- vault-name-prefix
- vault-key-name (defaults to "disk-secret")
- vault-user-id
If just the disk encryption set name is configured, Juju will use that existing disk encryption set and not create any additional resources. It can reside in a different resource group by specifying resgroup_name/DES_name
If a vault name prefix
is also configured, Juju will create a vault called vault_name_prefix-resource_group_name
. Vault names need to be unique across a subscription.
If vault-user-id
is configured, that user will be given full access to manage the vault and keys created by Juju.
To add an instance with disk encryption, first create a storage pool and then use the root-disk-source
constraint when adding the Juju machine, eg
juju create-storage-pool byo azure encrypted=true disk-encryption-set-name="mydisksecrets"
juju add-machine --constraints="root-disk-source=byo"
or
juju create-storage-pool des azure encrypted=true vault-name-prefix=mysecrets vault-user-id=27f86c31-bca0-4a37-b233-0e5030107696
juju add-machine --constraints="root-disk-source=des"
etc.
If you want the controller to also use disk encryption, the storage pool will need to be created at bootstrap time, eg
juju bootstrap azure \
--no-default-model \
--storage-pool name=foo \
--storage-pool type=azure \
--storage-pool encrypted=true \
--storage-pool vault-name-prefix=secret \
--bootstrap-constraints="root-disk-source=foo"
The same arg handling as is used for --config
is used here; either a YAML file or multiple cmd args can be used with --storage-pool
.
Next steps
A controller is created with two models - the ‘controller’ model, which should be reserved for Juju’s internal operations, and a model named ‘default’, which can be used for deploying user workloads.
See these pages for ideas on what to do next: