<a id="cloud-maas"></a>

# MAAS

In Juju, [MAAS](https://maas.io/) is a [machine cloud](https://documentation.ubuntu.com/juju/4.0/reference/cloud.md#machine-cloud) and works as described below.

#### NOTE
This reference assumes basic familiarity with Juju. If you are new to Juju, start with the [Tutorial](https://documentation.ubuntu.com/juju/4.0/tutorial.md#tutorial), then use this page together with the generic materials it links to and/or consult the [example workflows](#maas-appendix-example-workflows).

<a id="maas-limitations"></a>

## Limitations

- **Pre-existing infrastructure required**: All machines, networks, and storage must exist in MAAS before use. Juju does not provision new hardware.
- **Spaces inherited from MAAS**: Juju reads MAAS spaces and subnets but does not create or modify them. If spaces or subnets change in MAAS, reload them with `juju reload-spaces`. Note: the `alpha` space does not exist in MAAS, so applications are not connected to any space by default. Use `default-space` in model config or bind applications explicitly to an existing MAAS space.
- **Static storage only**: The MAAS storage provider cannot dynamically create or release volumes. Storage must exist on machine hardware and can only be requested at deploy time. Juju cannot dissociate a MAAS disk from its machine – attempting to deploy a unit with storage to an existing MAAS machine returns an error.
- **Machines released on removal**: When a machine is removed from a Juju model, it is released back to the MAAS inventory rather than destroyed.

<a id="maas-requirements"></a>

## Requirements

Starting with Juju 3.0, MAAS versions earlier than 2 are no longer supported.

<a id="maas-concepts"></a>

## Concepts

The following table shows how MAAS abstractions map to Juju concepts:

| MAAS                               | Juju                                                                   |
|------------------------------------|------------------------------------------------------------------------|
| Allocated machine from inventory   | [machine](https://documentation.ubuntu.com/juju/4.0/reference/machine.md#machine)         |
| Process on a commissioned machine  | [unit](https://documentation.ubuntu.com/juju/4.0/reference/unit.md#unit)               |
| Group of units for one workload    | [application](https://documentation.ubuntu.com/juju/4.0/reference/application.md#application) |
| MAAS-managed disks and filesystems | [storage](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage)         |
| MAAS spaces/fabrics/subnets        | Network spaces and placement targets                                   |
| MAAS API key (`maas-oauth`)        | Cloud credential                                                       |

<a id="maas-cloud"></a>

## The cloud

See also: [Cloud](https://documentation.ubuntu.com/juju/4.0/reference/cloud.md#cloud), [Juju | Manage clouds](https://documentation.ubuntu.com/juju/4.0/howto/manage-clouds.md#manage-clouds), [Terraform Provider for Juju | Manage clouds](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-clouds/#manage-clouds)

As for all machine clouds, the cloud is registered in Juju via a cloud definition, stored in `clouds.yaml` on the client (on Linux: `~/.local/share/juju/clouds.yaml`) and following this schema:

```yaml
clouds:
  <cloud-name>:  # User-defined name
    type: maas
    auth-types:
      - <auth-type>                # See Authentication types below
    endpoint: <maas-api-url>       # MAAS API endpoint
    config:                        # Optional: model config defaults
      <config-key>: <value>        # See Configuration keys below
```

<a id="maas-credential"></a>

## Credentials

See also: [Credential](https://documentation.ubuntu.com/juju/4.0/reference/credential.md#credential), [Juju | Manage credentials](https://documentation.ubuntu.com/juju/4.0/howto/manage-credentials.md#manage-credentials), [Terraform Provider for Juju | Manage credentials](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-credentials/#manage-credentials)

As for all machine clouds, credentials are stored in `credentials.yaml` on the client and follow this schema:

```yaml
credentials:
  <your-maas-cloud>           # Cloud name as defined above
    <credential-name>:             # User-defined credential name
      auth-type: <auth-type>       # oauth1 (the only type)
      <attribute>: <value>         # Auth-type-specific attributes (see below)
```

<a id="maas-credential-authentication-types"></a>

### Authentication types

MAAS supports the following authentication types:

<a id="maas-credential-oauth1"></a>

#### `oauth1`

Attributes:

- `maas-oauth`: OAuth/API-key credentials for MAAS (required).

#### NOTE
`maas-oauth` is your MAAS API key. See more: [MAAS | How to add an API key for a user](https://maas.io/docs/how-to-enhance-maas-security#p-9102-manage-api-keys)

<a id="maas-controller"></a>

## Controllers

See also: [Controller](https://documentation.ubuntu.com/juju/4.0/reference/controller.md#controller), [Juju | Manage controllers](https://documentation.ubuntu.com/juju/4.0/howto/manage-controllers.md#manage-controllers), [Terraform Provider for Juju | Manage controllers](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-controllers/#manage-controllers)

<a id="maas-controller-bootstrap-behavior"></a>

### Bootstrap behavior

Allocates a machine from MAAS inventory that meets the specified hardware constraints. After allocation, MAAS deploys the Ubuntu OS to the machine and executes cloud-init configuration containing the controller setup.

<a id="maas-controller-resources-created-at-bootstrap"></a>

### Resources allocated at bootstrap

MAAS allocates (rather than creates) existing machines from inventory. The controller runs on a machine provisioned using the same mechanisms as workload machines – see [Resources allocated/created per machine](#maas-machine-resources-created-per-machine) for the full per-machine resource model. Controller-specific differences are noted below.

**Compute**

- **Machine allocation**: A machine from MAAS inventory matching hardware constraints (CPU, RAM, architecture) is allocated and commissioned.

**Networking**

- **Network interfaces**: Allocated machine must have NICs matching any space requirements from constraints.

**Storage**

- **Disks**: Allocated machine must have disks matching root disk size requirements.

**Deployment**: MAAS deploys the OS image and injects cloud-init userdata. The machine is tagged with `juju-is-controller: true`, `juju-controller-uuid`, and `juju-model-uuid`.

<a id="maas-machine"></a>

## Machines

See also: [Machine](https://documentation.ubuntu.com/juju/4.0/reference/machine.md#machine), [Juju | Manage machines](https://documentation.ubuntu.com/juju/4.0/howto/manage-machines.md#manage-machines), [Terraform Provider for Juju | Manage machines](https://canonical.com/juju/docs/terraform-provider-juju/latest/howto/manage-machines/#manage-machines)

MAAS provides two modes of machine provisioning, selected via the `virt-type` constraint:

- **Default (bare metal or pre-existing VM)**: Juju calls `AllocateMachine` to allocate an existing machine from the MAAS inventory. Nothing is created.
- **`virt-type=virtual-machine`**: Juju calls `ComposeMachine` to create a new VM from a MAAS pod (KVM or LXD host). The pod must pre-exist in MAAS, but the VM itself is created on demand.

<a id="maas-machine-constraints"></a>

### Constraints

MAAS supports the following [constraints](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint):

**Compute**

- [arch](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-arch). Valid values: See cloud provider.
- [cores](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-cores)
- [image-id](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-image-id). Starting with Juju 3.2. Valid values: An image name from MAAS.
- [mem](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-mem)
- [virt-type](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-virt-type). Starting with Juju 3.6.22. Valid values: `virtual-machine`. Default: empty string (allocates from inventory). Use `virtual-machine` to compose a VM from a pod.

**Networking**

- [spaces](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-spaces)
- [zones](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-zones)

**Storage**

- [root-disk](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-root-disk)

**Other**

- [container](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-container)
- [tags](https://documentation.ubuntu.com/juju/4.0/reference/constraint.md#constraint-tags). Used to match machines with specific MAAS tags.

<a id="maas-machine-placement-directives"></a>

### Placement directives

MAAS supports the following [placement directives](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive):

- [<machine>](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive-machine)
- [system-id=<system ID>](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive-system-id)
- [zone=<zone>](https://documentation.ubuntu.com/juju/4.0/reference/placement-directive.md#placement-directive-zone): If there’s no ‘=’ delimiter, assume it’s a node name.

<a id="maas-machine-resources-created-per-machine"></a>

### Resources allocated/created per machine

Applies to all machines, including controller machines. Controller-specific differences are documented in [Resources allocated at bootstrap](#maas-controller-resources-created-at-bootstrap).

**Compute**

- **Machine**: Allocated from MAAS inventory (bare metal or pre-existing VM) matching hardware constraints, or composed as a new VM from a pod when `virt-type=virtual-machine`.

**Networking**

- **Network interfaces**: Pre-configured NICs with IP addresses allocated from MAAS subnets.

**Storage**

- **Disks**: Physical disks on the machine matching storage constraints.

**Deployment**: Ubuntu image deployed via MAAS with Juju agent installed via cloud-init. Machine tagged with `juju-controller-uuid`, `juju-model-uuid`, `juju-machine-id`, and `juju-units-deployed`.

<a id="maas-machine-networking-behavior"></a>

### Networking behavior

- **IP addressing**: MAAS allocates IPs from configured subnet pools (static, DHCP, or auto).
- **Spaces**: Juju reads MAAS spaces and subnets but does not create or modify them. Machines are allocated based on required spaces from endpoint bindings and constraints.
- **Network topology**: Uses pre-existing MAAS network configuration (VLANs, subnets, spaces). Juju does not provision networks.

<a id="maas-machine-storage-behavior"></a>

### Storage behavior

See also: [maas](#storage-provider-maas) for the MAAS storage provider configuration options.

- **Physical disks only**: Storage must exist on machine hardware. Juju cannot dynamically provision storage volumes.
- **Deploy-time only**: Storage can only be requested at deploy time; it cannot be added to existing machines.
- **No detachment**: Juju cannot dissociate a MAAS disk from its machine.
- **Released on removal**: Storage is removed when the machine is removed from the model.

<a id="maas-storage"></a>

## Storage

See also: [Storage](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage), [Juju | Manage storage](https://documentation.ubuntu.com/juju/4.0/howto/manage-storage.md#manage-storage)

<a id="maas-storage-providers"></a>

### Storage providers

In addition to generic storage providers, MAAS provides the following [cloud-specific storage providers](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage-provider-cloud-specific):

<a id="storage-provider-maas"></a>

#### `maas`

**Type:** Physical/virtual disks on MAAS machines

**Configuration options:**

- `tags`: A comma-separated list of tags to match on the disks in MAAS. For example, tag some disks as `fast` and create a Juju storage pool that draws from disks with that tag.

<a id="maas-appendix-example-workflows"></a>

## Appendix: Example workflows

<a id="maas-appendix-quickstart"></a>

### Add cloud, add credential, bootstrap

1. Add the MAAS cloud endpoint with `juju add-cloud`.
2. Add credentials with `juju add-credential` and choose `oauth1`.
3. Bootstrap with `juju bootstrap <maas-cloud-name> maas-controller`.
