Charmed MAAS setup

Here’s how to set up the MAAS Operator Charm:

  • Set up the environment
  • Install the base packages
  • Set up LXD
  • Bootstrap the Juju controller
  • Install PostgreSQL
  • Install HAProxy
  • Install MAAS

These steps are detailed below.

Set up the environment

You need to create some some environment variables to support this charm. Specifically, you need your LaunchPad ID and the specific location of the MAAS region and agent charms. Here’s how:

# LaunchPad ID
export LP_ID="my-lp-id"
export MAAS_REGION_CHARM=./maas-region-charm/maas-region_ubuntu-22.04-amd64.charm
export MAAS_AGENT_CHARM=./maas-agent-charm/maas-agent_ubuntu-22.04-amd64.charm

Install the base packages

Next, you need to install Juju, LXD, and Charmcraft, which form the foundation for this charm:

sudo snap install juju
sudo snap install lxd
sudo snap install charmcraft --classic

Juju needs to be invoked once to initialize its local state, including an SSH key that will be needed later.

# The actual command doesn't matter, just run Juju once
juju whoami

Set up LXD

Next, you need to set up LXD, since it’s part of this Charm configuration. Specifically, you’ll need networks, projects, profiles, and virtual machines before moving on to the next step.

Create networks

First, you’ll need managed network to act as the control plane:

lxc network create jujulab
lxc network edit jujulab <<EOF
name: jujulab
description: "Juju lab network"
type: bridge
config:
  dns.domain: juju-lab
  ipv4.address: 10.70.0.1/24
  ipv4.dhcp: "true"
  ipv4.dhcp.ranges: 10.70.0.65-10.70.0.126
  ipv4.nat: "true"
  ipv6.address: none
EOF

Next, you must integrate this network with the host’s DNS service and make this integration persistent:

resolvectl dns jujulab 10.70.0.1
resolvectl domain jujulab '~juju-lab'
cat <<EOF | sudo tee /etc/systemd/system/lxd-dns-net-juju.service
[Unit]
Description=LXD per-link DNS configuration for jujulab
BindsTo=sys-subsystem-net-devices-jujulab.device
After=sys-subsystem-net-devices-jujulab.device

[Service]
Type=oneshot
ExecStart=/usr/bin/resolvectl dns jujulab 10.70.0.1
ExecStart=/usr/bin/resolvectl domain jujulab '~juju-lab'
ExecStopPost=/usr/bin/resolvectl revert jujulab
RemainAfterExit=yes

[Install]
WantedBy=sys-subsystem-net-devices-jujulab.device
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now lxd-dns-net-juju

You’ll also need an unmanaged network for Devices-Under-Test (DUT):

lxc network create jujudata
lxc network edit jujudata <<EOF
name: jujudata
description: "Juju test network"
type: bridge
config:
  dns.domain: jujudata
  ipv4.address: 10.70.1.1/24
  ipv4.dhcp: "false"
  ipv4.nat: "false"
  ipv6.address: none
EOF

Now that the networks are set up, we’ll need a project and some profiles.

Create project and profiles

First, create a project to isolate the charm:

lxc project create juju-lab -c features.images=false
lxc project switch juju-lab

Next, create a profile for Juju controllers, which will use two network interface cards (NICs):

lxc profile create juju-host
lxc profile edit juju-host <<EOF
name: juju-host
description: Juju host
config:
    limits.cpu: 2
    limits.memory: 4GB
    user.user-data: |
        #cloud-config
        ssh_authorized_keys:
        - $(cat ${HOME}/.ssh/id_rsa.pub | cut -d' ' -f1-2)
        - $(cat ${HOME}/.local/share/juju/ssh/juju_id_rsa.pub | cut -d' ' -f1-2)
devices:
    eth0:
        type: nic
        name: eth0
        network: jujulab
    eth1:
        type: nic
        name: eth1
        network: jujudata
    root:
        path: /
        pool: default
        type: disk
EOF

Then, create a profile for devices under test (just one NIC this time):

lxc profile create juju-dut
lxc profile edit juju-dut <<EOF
name: juju-dut
description: Juju lab DUT
devices:
    eth0:
        type: nic
        name: eth0
        network: jujudata
    root:
        path: /
        pool: default
        type: disk
EOF

Create VMs

You’ll need some VMs to make this environment work, so create a few:

for h in $(seq 1 3); do \
    lxc launch ubuntu:jammy "m$h" --vm -p juju-host;\
done;\
sleep 5;\
for h in $(seq 1 3); do \
    lxc exec "m$h" -- cloud-init status --wait;\
    ssh-keyscan -H "m$h.juju-lab" >> ~/.ssh/known_hosts;\
done

Bootstrap Juju controller

Next, you’ll need to bootstrap the Juju controller:

cat >| maas-bootstrap.yaml <<EOF
clouds:
    maas-bootstrap:
        type: manual
        endpoint: ubuntu@m1.juju-lab
        regions:
            default: {}
EOF

juju add-cloud maas-bootstrap ./maas-bootstrap.yaml
juju bootstrap maas-bootstrap maas-controller
juju add-machine -m controller ssh:ubuntu@m2.juju-lab
juju add-machine -m controller ssh:ubuntu@m3.juju-lab
juju enable-ha -n 3 --to 1,2
juju controllers --refresh

Now we’re ready to install the packages that add MAAS to the charm, using the charm itself to install and configure them.

Install Postgres DB

Deploy a MAAS-usable PostgreSQL DB using the charm itself:

juju deploy -m controller postgresql --channel 14/stable --series jammy --to 0
juju add-unit -m controller postgresql -n 2 --to 1,2

Install HAProxy

You can also deploy HAProxy using the charm:

juju deploy -m controller haproxy --series jammy --to 0
juju add-unit -m controller haproxy -n 2 --to 1,2

Install MAAS

Finally, you can deploy MAAS using the charm, in several steps.

  1. Deploy a region-controller using the charm
    juju deploy -m controller ${MAAS_REGION_CHARM} --to 0
    juju status --watch 10s  # wait for it to initialize
  1. Make sure that Juju can consume offers from the region:
    juju integrate -m controller maas-region postgresql
    juju integrate -m controller maas-region haproxy
    juju status --watch 10s  # wait for it to settle
  1. Create an Admin user:
    juju run -m controller maas-region/leader create-admin username=maas password=maas email=maas@example.com ssh-import=lp:${LP_ID}
  1. Deploy a rack (the “agent”) using the charm:
    juju deploy -m controller ${MAAS_AGENT_CHARM} --to 1
    juju integrate -m controller maas-agent maas-region
    juju add-unit -m controller maas-agent --to 2
  1. Get the MAAS URL, which you’ll need to access your MAAS instance:
    juju run -m controller maas-region/leader get-api-endpoint

Conclusion

That’s it! Your MAAS is up and running, using the MAAS Operator Charm.