Several months back I was working quite a bit with MAAS and
needed a way to fully automate not only the MAAS deployment but also the
management of VMs. In this case they were VMs running on KVM .
So as I am backfilling with posts and catching up on some things that I had
intended on sharing this would be one of them.
First thing is to grab the ansible-maas
Ansible role if you would like to use that. This role is actually a very basic
single host deployment but can easily be adapted to separate out functionality
if needed.
Once you have your MAAS deployment completed you are then ready for managing MAAS
with what else other than, Ansible of course. Below you will find the templates
and playbook used for managing MAAS.
To generate MAAS Ansible inventory you can use the following Jinja2 template:
[maas_non_provisioned]
{% for host in (maas_machines['stdout']|from_json) %}
{% if groups['maas_deployed_machines'] is defined %}
{% if host['fqdn'] not in groups['maas_deployed_machines'] %}
{{ host['fqdn'] }}
{% elif host['hostname'] not in groups['maas_deployed_machines'] %}
{{ host['hostname'] }}
{% endif %}
{% elif groups['maas_deployed_machines'] is not defined %}
{{ host['fqdn'] }}
{{ host['hostname'] }}
{% endif %}
{% endfor %}
{% if kvm_vms_list is defined %}
{% if groups['maas_deployed_machines'] is defined %}
{% for kvm_vm in kvm_vms_list %}
{% if kvm_vm not in groups['maas_deployed_machines'] %}
{{ kvm_vm }}
{% endif %}
{% endfor %}
{% elif groups['maas_deployed_machines'] is not defined %}
{% for kvm_vm in kvm_vms_list %}
{{ kvm_vm }}
{% endfor %}
{% endif %}
{% endif %}
To generate MAAS related variables based dynamic discovery you can use the
following Jinja2 template:
---
# Defined vars from first maas play to continue onto additional plays.
# these will eventually be put into group_vars
inventory_directory: '{{ inventory_directory }}'
maas_login_profile: '{{ maas_login_profile }}'
maas_login_url: '{{ maas_login_url }}'
maas_login_user: '{{ maas_login_user }}'
maas_match_kvm_name: {{ maas_match_kvm_name }}
maas_virsh_user: '{{ maas_virsh_user }}'
# Defined machines marked as broken
{% if groups['maas_broken_machines'] is defined %}
maas_broken_machines:
{% for host in groups['maas_broken_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_broken_machines'] is not defined %}
maas_broken_machines: []
{% endif %}
# Defined machines to be Commissioned
{% if groups['maas_commission_machines'] is defined %}
maas_commission_machines:
{% for host in groups['maas_commission_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_commission_machines'] is not defined %}
maas_commission_machines: []
{% endif %}
# Defined machines to be deployed
{% if groups['maas_deployed_machines'] is defined %}
maas_deployed_machines:
{% for host in groups['maas_deployed_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_deployed_machines'] is not defined %}
maas_deployed_machines: []
{% endif %}
# Defined machines which have failed
{% if groups['maas_failed_machines'] is defined %}
maas_failed_machines:
{% for host in groups['maas_failed_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_failed_machines'] is not defined %}
maas_failed_machines: []
{% endif %}
# Defined machines as new
{% if groups['maas_new_machines'] is defined %}
maas_new_machines:
{% for host in groups['maas_new_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_new_machines'] is not defined %}
maas_new_machines: []
{% endif %}
# Defined machines which are in an unknown power state
{% if groups['maas_power_unknown_machines'] is defined %}
maas_power_unknown_machines:
{% for host in groups['maas_power_unknown_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_power_unknown_machines'] is not defined %}
maas_power_unknown_machines: []
{% endif %}
# Defined machines which are powered off
{% if groups['maas_powered_off_machines'] is defined %}
maas_powered_off_machines:
{% for host in groups['maas_powered_off_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_powered_off_machines'] is not defined %}
maas_powered_off_machines: []
{% endif %}
# Defined machines which are powered on
{% if groups['maas_powered_on_machines'] is defined %}
maas_powered_on_machines:
{% for host in groups['maas_powered_on_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_powered_on_machines'] is not defined %}
maas_powered_on_machines: []
{% endif %}
# Defined machines which are in a ready state
{% if groups['maas_ready_machines'] is defined %}
maas_ready_machines:
{% for host in groups['maas_ready_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_ready_machines'] is not defined %}
maas_ready_machines: []
{% endif %}
# Defined machines which are to be released
{% if groups['maas_release_machines'] is defined %}
maas_release_machines:
{% for host in groups['maas_release_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_release_machines'] is not defined %}
maas_release_machines: []
{% endif %}
# Defined machines which are currently in rescue mode
{% if groups['maas_rescue_mode_machines'] is defined %}
maas_rescue_mode_machines:
{% for host in groups['maas_rescue_mode_machines'] %}
- '{{ host }}'
{% endfor %}
{% elif groups['maas_rescue_mode_machines'] is not defined %}
maas_rescue_mode_machines: []
{% endif %}
# Defines KVM VMs to MAAS Relationships
kvm_maas_relationships:
{% for host in groups['kvm_hosts'] %}
{% for item in hostvars[host]['mac_addresses']['results'] %}
{% for item2 in (maas_machines['stdout']|from_json) %}
{% if item2['boot_interface']['mac_address'] == item['stdout'] %}
- kvm_vm_name: '{{ item['item'] }}'
kvm_vm_mac: '{{ item['stdout'] }}'
kvm_vm_host: '{{ host }}'
maas_fqdn: '{{ item2['fqdn'] }}'
maas_hostname: '{{ item2['hostname'] }}'
maas_ips:
{% for ip in item2['ip_addresses'] %}
- '{{ ip }}'
{% endfor %}
{% for item in maas_power_parameters['results'] %}
{% if item['item']['system_id'] == item2['system_id'] %}
maas_current_power_address: '{{ item['stdout'] }}'
{% endif %}
{% endfor %}
maas_desired_power_address: 'qemu+ssh://{{ maas_virsh_user }}@{{ hostvars[host]['ansible_host'] }}/system'
maas_power_id: '{{ item['item'] }}'
maas_power_state: '{{ item2['power_state'] }}'
maas_power_type: '{{ item2['power_type'] }}'
maas_status: '{{ item2['status'] }}'
maas_status_name: '{{ item2['status_name'] }}'
maas_system_id: '{{ item2['system_id'] }}'
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
# Defines boot image sources
maas_boot_image_sources:
{{ maas_boot_image_sources['stdout']|from_json|to_yaml }}
# Defines all currenly available images in MAAS
maas_available_images:
{{ maas_current_available_images['stdout']|from_json|to_yaml }}
# Defines machine power address
maas_machine_power_parameters:
{% for item in maas_power_parameters['results'] %}
- system_id: '{{ item['item']['system_id'] }}'
power_address: '{{ item['stdout'] }}'
{% endfor %}
# Defines all gathered information for every machine in MAAS
maas_machines:
{{ maas_machines['stdout']|from_json|to_yaml }}
And for the actual MAAS management playbook you can use the following:
---
- hosts: kvm_hosts
remote_user: remote
become: true
vars:
roles:
tasks:
- name: Capturing VM(s)
virt:
command: "list_vms"
register: "kvm_vms_capture"
tags:
- maas_machines
- prep_machines
- name: Capturing MAC Addresses
shell: "virsh domiflist {{ item }} | awk '{if (NR>2) print}' | awk '{ print $5 }'"
register: mac_addresses
with_items: '{{ kvm_vms_capture.list_vms }}'
changed_when: false
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For kvm_vms_list
add_host:
name: "{{ item['name'] }}"
groups: "kvm_vms_list"
become: false
changed_when: false
with_items: '{{ kvm_vms }}'
run_once: true
tags:
- maas_machines
- prep_machines
- name: Ensuring vars Directory Exists
file:
path: "./vars"
state: "directory"
delegate_to: "localhost"
become: false
tags:
- maas_machines
- prep_machines
- name: Generating KVM VMs List
template:
src: "templates/kvm_vms_list.yml.j2"
dest: "./vars/kvm_vms_list.yml"
become: false
delegate_to: "localhost"
run_once: true
tags:
- maas_machines
- prep_machines
- hosts: maas
remote_user: remote
become: true
vars:
inventory_directory: '../inventory'
maas_boot_images:
arches:
- 'amd64'
# - 'i386'
images:
- os: 'ubuntu'
release: 'precise'
- os: 'ubuntu'
release: 'trusty'
- os: 'ubuntu'
release: 'xenial'
# Defines DNSSEC validation of upstream zones
# auto, no, yes
maas_dnssec_validation: 'no'
maas_login_profile: 'admin'
maas_login_url: 'http://localhost:5240/MAAS/api/2.0'
maas_login_user: 'root'
maas_match_kvm_name: true
# Defines the hostname to assign to MAAS
maas_name: 'maas'
maas_ntp_servers:
- 'ntp.ubuntu.com'
maas_ntp_use_external_only: false
maas_release_machines: []
# - 'heroic-guinea'
# - 'square-gar'
# - 'sure-toucan'
# - 'worthy-sponge'
# Defines upstream DNS servers to configure
maas_upstream_dns_servers:
- '10.10.10.1'
maas_vars_folder: './vars'
maas_virsh_user: 'administrator'
vars_files:
- './vars/kvm_vms_list.yml'
roles:
tasks:
- name: Installing JQ
apt:
name: "jq"
state: "present"
tags:
- maas_dns
- maas_images
- maas_machines
- maas_ntp
- prep_machines
- name: Capturing MAAS CLI API Key
command: "maas-region apikey --username={{ maas_login_user }}"
register: "maas_api_key"
changed_when: false
tags:
- maas_dns
- maas_images
- maas_machines
- maas_ntp
- prep_machines
- name: Logging Into MAAS API
command: >
maas login {{ maas_login_profile }} {{ maas_login_url }}
{{ maas_api_key['stdout'] }}
become: false
changed_when: false
tags:
- maas_dns
- maas_images
- maas_machines
- maas_ntp
- prep_machines
- name: Capturing MAAS Name
shell: >
maas {{ maas_login_profile }} maas get-config
name=maas_name | jq . | sed 's|\"||g'
register: "maas_name_config"
become: false
changed_when: false
tags:
- maas_dns
- name: Configuring MAAS Name
command: >
maas {{ maas_login_profile }} maas set-config
name=maas_name value={{ maas_name }}
become: false
when: maas_name_config['stdout'] != maas_name
tags:
- maas_dns
- name: Capturing MAAS Boot Image Sources
shell: "maas {{ maas_login_profile }} boot-sources read | jq ."
register: "maas_boot_image_sources"
become: false
changed_when: false
tags:
- maas_images
- maas_machines
- prep_machines
- name: Capturing MAAS Boot Source Selections
shell: >
maas {{ maas_login_profile }} boot-source-selections
read {{ item['id'] }} | jq .
register: "maas_boot_source_selections"
become: false
changed_when: false
with_items: "{{ maas_boot_image_sources['stdout']|from_json }}"
tags:
- maas_images
- maas_machines
- prep_machines
- name: Capturing MAAS Currently Available Images
shell: "maas {{ maas_login_profile }} boot-resources read | jq ."
register: "maas_current_available_images"
become: false
changed_when: false
tags:
- maas_images
- maas_machines
- prep_machines
- name: Configuring MAAS Boot Sources
command: >
maas {{ maas_login_profile }} boot-source-selections
create {{ item[0]['id'] }}
arches={{ item[1]['arches']|default('amd64')}}
labels={{ item[1]['labels']|default('*') }}
os={{ item[1]['os'] }}
release={{ item[1]['release'] }}
subarches={{ item[1]['subarches']|default('*') }}
become: false
register: "maas_boot_sources_updated"
with_nested:
- "{{ maas_boot_image_sources['stdout']|from_json }}"
- "{{ maas_boot_images['images'] }}"
when: item[1]['release'] not in maas_boot_source_selections['results'][0]['stdout']
tags:
- maas_images
- name: Importing MAAS Boot Images
command: "maas {{ maas_login_profile }} boot-resources import"
become: false
when: maas_boot_sources_updated['changed']
tags:
- maas_images
- name: Capturing MAAS DNSSEC Validation Config
shell: >
maas {{ maas_login_profile }} maas get-config
name=dnssec_validation | jq . | sed 's|\"||g'
register: "maas_dnssec_validation_config"
become: false
changed_when: false
tags:
- maas_dns
- name: Configuring MAAS DNSSEC Validation Config
command: >
maas {{ maas_login_profile }} maas set-config
name=dnssec_validation value={{ maas_dnssec_validation }}
become: false
when: maas_dnssec_validation_config['stdout'] != maas_dnssec_validation
tags:
- maas_dns
- name: Capturing MAAS DNS Upstream Server(s)
shell: >
maas {{ maas_login_profile }} maas get-config
name=upstream_dns | jq . | sed 's|\"||g'
register: "maas_upstream_dns_config"
become: false
changed_when: false
tags:
- maas_dns
- name: Configuring MAAS DNS Upstream Server(s)
command: >
maas {{ maas_login_profile }} maas set-config
name=upstream_dns value={{ maas_upstream_dns_servers|join(' ') }}
become: false
when: maas_upstream_dns_config['stdout'] != maas_upstream_dns_servers|join(' ')
tags:
- maas_dns
- name: Capturing MAAS NTP Server(s)
shell: >
maas {{ maas_login_profile }} maas get-config
name=ntp_servers | jq . | sed 's|\"||g'
register: "maas_ntp_servers_config"
become: false
changed_when: false
tags:
- maas_ntp
- name: Configuring MAAS NTP Server(s)
command: >
maas {{ maas_login_profile }} maas set-config
name=ntp_servers value={{ maas_ntp_servers|join(',') }}
become: false
when: maas_ntp_servers_config['stdout'] != maas_ntp_servers|join(' ')
tags:
- maas_ntp
- name: Capturing MAAS NTP Use external NTP servers only Config
shell: >
maas {{ maas_login_profile }} maas get-config
name=ntp_external_only | jq .
register: "maas_ntp_use_external_only_config"
become: false
changed_when: false
tags:
- maas_ntp
- name: Configuring MAAS NTP Use external NTP servers only Config
command: >
maas {{ maas_login_profile }} maas set-config
name=ntp_external_only value={{ maas_ntp_use_external_only }}
become: false
when: maas_ntp_use_external_only_config['stdout'] != maas_ntp_use_external_only|lower
tags:
- maas_ntp
- name: Capturing MAAS DNS Domains
shell: "maas {{ maas_login_profile }} domains read | jq ."
register: "maas_dns_domains"
become: false
changed_when: false
tags:
- maas_dns
- name: Capturing MAAS DNS Resources
shell: "maas {{ maas_login_profile }} dnsresources read | jq ."
register: "maas_dns_resources"
become: false
changed_when: false
tags:
- maas_dns
# - name: Creating MAAS DNS Domains
# command: "maas {{ maas_login_profile }} domains create name={{ item }}"
# become: false
# with_items:
# # - "{{ maas_dns_domains['stdout']|from_json }}"
# - 'etsbv.internal'
# when: item not in maas_dns_domains['stdout']
# tags:
# - maas_dns
# - name: Creating MAAS DNS Domain Resources
# command: >
# maas {{ maas_login_profile }} dnsresources create
# fqdn={{ item['name'] }}
# ip_addresses={{ item['ip'] }}
# become: false
# with_items:
# - name: 'kibana.etsbv.internal'
# ip: '10.0.102.60'
# # - name: 'nas01.etsbv.internal'
# # ip: '10.0.101.50'
# # - name: 'nas02.etsbv.internal'
# # ip: '10.0.101.51'
# # - name: 'nas03.etsbv.internal'
# # ip: '10.0.101.52'
# when: >
# item['name'] not in maas_dns_resources['stdout']
# tags:
# - maas_dns
- name: Capturing MAAS Machines
shell: "maas {{ maas_login_profile }} machines read | jq ."
register: "maas_machines"
become: false
changed_when: false
tags:
- maas_machines
- prep_machines
- name: Capturing MAAS Machine Power power-parameters
shell: >
maas {{ maas_login_profile }} machine power-parameters
{{ item['system_id'] }} | grep power_address |
sed 's|\"||g' | sed 's|,||g' | awk '{ print $2 }'
register: "maas_power_parameters"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
tags:
- maas_machines
- prep_machines
- name: Logging Out Of MAAS API
command: "maas logout {{ maas_login_profile }}"
become: false
changed_when: false
tags:
- maas_dns
- maas_images
- maas_machines
- maas_ntp
- prep_machines
# Generates group of machines to release.
# This group needs to be generated prior to any others
- name: Generating Dynamic Group For maas_release_machines
add_host:
name: "{{ item }}"
groups: "maas_release_machines"
become: false
changed_when: false
with_items: '{{ maas_release_machines }}'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_release_machines
add_host:
name: "{{ item['fqdn'] }}"
groups: "maas_release_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(groups['maas_release_machines'] is defined and
(item['hostname'] in groups['maas_release_machines'] and
item['fqdn'] not in groups['maas_release_machines']))
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_release_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_release_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(groups['maas_release_machines'] is defined and
(item['hostname'] not in groups['maas_release_machines'] and
item['fqdn'] in groups['maas_release_machines']))
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_broken_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_broken_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 8)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_broken_machines
add_host:
name: "{{ item['fqdn'] }}"
groups: "maas_broken_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 8)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_commission_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_commission_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(item['status']|int == 0) or
(item['status']|int == 2)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_deployed_machines
add_host:
name: "{{ item['fqdn'] }}"
groups: "maas_deployed_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 6)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_failed_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_failed_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 11)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_new_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_new_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 0)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_power_unknown_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_power_unknown_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: item['power_state'] == 'unknown'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_powered_off_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_powered_off_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: item['power_state'] == 'off'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_powered_on_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_powered_on_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: item['power_state'] == 'on'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_ready_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_ready_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 4)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_rescue_mode_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_rescue_mode_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 16)
tags:
- maas_machines
- prep_machines
- name: Ensuring {{ maas_vars_folder }} Exists
file:
path: "{{ maas_vars_folder }}"
state: "directory"
delegate_to: "localhost"
become: false
tags:
- maas_machines
- prep_machines
- name: Generating MAAS Management Variables
template:
src: "templates/maas_management_vars.yml.j2"
dest: "{{ maas_vars_folder }}/maas_management_vars.yml"
delegate_to: "localhost"
become: false
tags:
- maas_machines
- prep_machines
- hosts: maas
become: true
remote_user: remote
vars:
maas_vars_folder: './vars'
vars_files:
- './vars/kvm_vms_list.yml'
- '{{ maas_vars_folder }}/maas_management_vars.yml'
roles:
tasks:
- name: Capturing MAAS CLI API Key
command: "maas-region apikey --username={{ maas_login_user }}"
register: "maas_api_key"
changed_when: false
tags:
- maas_machines
- prep_machines
- name: Logging Into MAAS API
command: >
maas login {{ maas_login_profile }} {{ maas_login_url }}
{{ maas_api_key['stdout'] }}
become: false
changed_when: false
tags:
- maas_machines
- prep_machines
- name: Configuring MAAS Machine Power Settings
command: >
maas {{ maas_login_profile }} machine update {{ item['maas_system_id'] }}
power_type=virsh
power_parameters_power_address={{ item['maas_desired_power_address'] }}
power_parameters_power_id={{ item['kvm_vm_name'] }}
become: false
with_items: '{{ kvm_maas_relationships }}'
when: >
item['maas_current_power_address'] != item['maas_desired_power_address']
tags:
- maas_machines
- name: Commissioning MAAS Machines Not Already Commissioned
command: >
maas {{ maas_login_profile }} machine commission
{{ item['system_id'] }}
become: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(groups['maas_commission_machines'] is defined and
item['hostname'] in groups['maas_commission_machines']) and
((groups['maas_release_machines'] is defined and
(item['hostname'] not in groups['maas_release_machines'] or
item['fqdn'] not in groups['maas_release_machines'])) or
groups['maas_release_machines'] is not defined)
tags:
- maas_machines
- prep_machines
- name: Allocating MAAS Machines In Ready State
command: >
maas {{ maas_login_profile }} machines allocate
system_id={{ item['system_id'] }}
become: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(groups['maas_ready_machines'] is defined and
item['hostname'] in groups['maas_ready_machines']) and
((groups['maas_release_machines'] is defined and
(item['hostname'] not in groups['maas_release_machines'] or
item['fqdn'] not in groups['maas_release_machines'])) or
groups['maas_release_machines'] is not defined)
tags:
- maas_machines
- prep_machines
- name: Deploying MAAS Machines In Ready State
command: >
maas {{ maas_login_profile }} machine deploy
{{ item['system_id'] }}
become: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(groups['maas_ready_machines'] is defined and
item['hostname'] in groups['maas_ready_machines']) and
((groups['maas_release_machines'] is defined and
(item['hostname'] not in groups['maas_release_machines'] or
item['fqdn'] not in groups['maas_release_machines'])) or
groups['maas_release_machines'] is not defined)
tags:
- maas_machines
- prep_machines
- name: Powering Off MAAS Machines To Release and Wipe Disk(s)
command: >
maas {{ maas_login_profile }} machine power-off
{{ item['system_id'] }}
become: false
register: "maas_machines_powered_off"
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
((groups['maas_release_machines'] is defined and
(item['hostname'] in groups['maas_release_machines'] or
item['fqdn'] in groups['maas_release_machines'])) and
(item['hostname'] in groups['maas_deployed_machines'] or
item['fqdn'] in groups['maas_deployed_machines'])) or
((groups['maas_failed_machines'] is defined and
item['hostname'] in groups['maas_failed_machines'])) and
item['hostname'] in groups['maas_powered_on_machines']
tags:
- maas_machines
- prep_machines
- name: Waiting For MAAS Machines To Power Off
pause:
seconds: 10
when: maas_machines_powered_off['changed']
tags:
- maas_machines
- prep_machines
- name: Releasing MAAS Machines
command: >
maas {{ maas_login_profile }} machine release
{{ item['system_id'] }}
become: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
((groups['maas_release_machines'] is defined and
(item['hostname'] in groups['maas_release_machines'] or
item['fqdn'] in groups['maas_release_machines'])) and
((item['hostname'] in groups['maas_deployed_machines'] or
item['fqdn'] in groups['maas_deployed_machines']) or
(item['status']|int == 15))) or
((groups['maas_failed_machines'] is defined and
item['hostname'] in groups['maas_failed_machines']))
tags:
- maas_machines
- prep_machines
- name: Configuring MAAS Machine Hostname
command: >
maas {{ maas_login_profile }} machine update
{{ item['maas_system_id'] }} hostname={{ item['kvm_vm_name'] }}
become: false
register: "maas_hostnames_changed"
with_items: '{{ kvm_maas_relationships }}'
when: >
maas_match_kvm_name and
((item['kvm_vm_name'] != item['maas_fqdn']) and
item['kvm_vm_name'] != item['maas_hostname'])
tags:
- maas_machines
- prep_machines
# We refresh the inventory to clean out any lingering hosts in dynamic groups
# to ensure we are clean going forward
- name: Refreshing Inventory
meta: refresh_inventory
become: false
tags:
- maas_machines
- prep_machines
# when: maas_hostnames_changed['changed']
# We recapture machines at the end of the run to catch any changes
# in names, status, and etc.
- name: Capturing MAAS Machines
shell: "maas {{ maas_login_profile }} machines read | jq ."
register: "maas_machines"
become: false
tags:
- maas_machines
- prep_machines
# when: maas_hostnames_changed['changed']
# We are regenerating all dynamic groups here to proceed in
# additional plays and after refreshing inventory
- name: Generating Dynamic Group For maas_release_machines
add_host:
name: "{{ item }}"
groups: "maas_release_machines"
become: false
changed_when: false
with_items: '{{ maas_release_machines }}'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_release_machines
add_host:
name: "{{ item['fqdn'] }}"
groups: "maas_release_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(groups['maas_release_machines'] is defined and
(item['hostname'] in groups['maas_release_machines'] and
item['fqdn'] not in groups['maas_release_machines']))
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_release_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_release_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(groups['maas_release_machines'] is defined and
(item['hostname'] not in groups['maas_release_machines'] and
item['fqdn'] in groups['maas_release_machines']))
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_broken_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_broken_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 8)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_broken_machines
add_host:
name: "{{ item['fqdn'] }}"
groups: "maas_broken_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 8)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_commission_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_commission_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(item['status']|int == 0) or
(item['status']|int == 2)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_deployed_machines
add_host:
name: "{{ item['fqdn'] }}"
groups: "maas_deployed_machines"
become: false
# changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: >
(maas_machines is defined and
(item['status']|int == 6))
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_failed_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_failed_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 11)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_new_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_new_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 0)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_power_unknown_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_power_unknown_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: item['power_state'] == 'unknown'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_powered_off_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_powered_off_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: item['power_state'] == 'off'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_powered_on_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_powered_on_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: item['power_state'] == 'on'
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_ready_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_ready_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 4)
tags:
- maas_machines
- prep_machines
- name: Generating Dynamic Group For maas_rescue_mode_machines
add_host:
name: "{{ item['hostname'] }}"
groups: "maas_rescue_mode_machines"
become: false
changed_when: false
with_items: "{{ maas_machines['stdout']|from_json }}"
when: (item['status']|int == 16)
tags:
- maas_machines
- prep_machines
- name: Logging Out Of MAAS API
command: "maas logout admin"
become: false
changed_when: false
tags:
- maas_machines
- prep_machines
# We are regenerating variables to capture any changes
- name: Generating MAAS Management Variables
template:
src: "templates/maas_management_vars.yml.j2"
dest: "{{ maas_vars_folder }}/maas_management_vars.yml"
delegate_to: "localhost"
become: false
tags:
- maas_machines
# We want to exclude these during the run in pipeline. This will be cleaned up
# at the end of the pipeline to not cause issues on future pipeline runs.
- name: Generating Temporary Inventory For maas_non_provisioned
template:
src: "templates/maas.inventory.inv.j2"
dest: "{{ inventory_directory }}/maas.inventory.inv"
become: false
delegate_to: "localhost"
tags:
- maas_machines
- prep_machines
# Ensure Python 2 is installed
- hosts: maas_deployed_machines:!maas_release_machines:!maas_broken_machines
remote_user: ubuntu
become: true
gather_facts: false
vars:
roles:
tasks:
- name: 'Install Python 2'
raw: "test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)"
changed_when: false
tags:
- maas_machines
- prep_machines
# Bootstrap provisioned machines
- hosts: maas_deployed_machines:!maas_release_machines:!maas_broken_machines
remote_user: ubuntu
become: true
vars:
email_from: 'MAAS@everythingshouldbevirtual.com'
email_notifications: 'mrlesmithjr@gmail.com'
email_notifications_enabled: false
email_server_hostname: 'smtp.charter.net'
email_server_port: '25'
roles:
- role: ansible-bootstrap
tags:
- maas_machines
- prep_machines
- role: ansible-users
tags:
- prep_machines
- role: ansible-manage-ssh-keys
tags:
- prep_machines
tasks:
- name: Generate E-Mail Notification Body
template:
src: "templates/email_notification.txt.j2"
dest: "./email_notification.txt"
delegate_to: "localhost"
become: false
run_once: true
when: email_notifications_enabled
- name: Send E-Mail Notification
mail:
host: "{{ email_server_hostname }}"
port: "{{ email_server_port }}"
to: "{{ email_notifications }}"
from: "{{ email_from }}"
subject: "Ansible-MAAS-report"
body: "{{ lookup('file', './email_notification.txt') }}"
delegate_to: "localhost"
become: false
run_once: true
when: email_notifications_enabled
Of course there is so much more you can do with this but I really just wanted to
share the foundation of the MAAS management here for others if there is ever a
need.
Enjoy!