The upcoming Juju 2.9 release brings some new Azure capabilities. These landed in the early release candidates and have had some successful field testing so it’s time to announce them to a wider audience.
In summary, the new features include:
- bring your own resource group
- bring your own virtual network
- space aware / multi-NIC instances
- constraint to allow instances to be provisioned without a public IP address
- full disk encryption on instance volumes
BYO Resource Group
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
model config, eg
juju add-model test --config resource-group=myresgroup
It’s also possible to bootstrap using an existing resource group for the controller model, eg
juju bootstrap azure --config resource-group=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.
BYO 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)
Spaces support
The Azure provider now supports network spaces.
juju subnets
will show the subnets Juju knows about for a given model.
Assuming the example from above, add a space in one of the 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.
Public IP address constraint
A new constraint value is available: allocate-public-ip
.
It defaults to true
and specifies whether instances get a public IP address or not.
The constraint is supported across all relevant providers, not just Azure (AWS, GCE, Openstack etc).
eg
juju add-machine --constraints="allocate-public-ip=false"
Full disk encryption
When provisioning an Azure instance, it is now 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
.