OpenStack-Ansible Magnum

Ansible role that installs and configures OpenStack Magnum. Magnum is installed behind the Apache webserver listening on port 9511 by default.

To clone or view the source code for this repository, visit the role repository for os_magnum.

Note

Heat driver has been deprecated by Magnum team in 2025.1 (Epoxy) release and is completely removed in 2026.2 (Hibiscus) release.

All new deployments should define magnum_k8s_driver to vexxhost or azimuth and avoid heat driver if possible.

Design and Configuration

Default variables

## Verbosity Options
debug: false

# python venv executable
magnum_venv_python_executable: "{{ openstack_venv_python_executable | default('python3') }}"

# Enable/Disable Ceilometer
magnum_ceilometer_enabled: "{{ (groups['ceilometer_all'] is defined) and (groups['ceilometer_all'] | length > 0) }}"

# Set the host which will execute the shade modules
# for the service setup. The host must already have
# clouds.yaml properly configured.
magnum_service_setup_host: "{{ openstack_service_setup_host | default('localhost') }}"
magnum_service_setup_host_python_interpreter: >-
  {{
    openstack_service_setup_host_python_interpreter | default(
      (magnum_service_setup_host == 'localhost') | ternary(ansible_playbook_python, ansible_facts['python']['executable']))
  }}

# Set the package install state for distribution packages
# Options are 'present' and 'latest'
magnum_package_state: "{{ package_state | default('latest') }}"

magnum_system_group_name: magnum
magnum_system_user_name: magnum
magnum_system_user_comment: Magnum System User
magnum_system_user_shell: /bin/false
magnum_system_user_home: "/var/lib/{{ magnum_system_user_name }}"
magnum_etc_directory: /etc/magnum

magnum_service_name: magnum
magnum_service_user_name: magnum
magnum_service_type: container-infra
magnum_service_description: "OpenStack Containers (Magnum)"
magnum_service_project_name: service
magnum_service_role_names:
  - admin
  - service
magnum_service_token_roles:
  - service
magnum_service_token_roles_required: "{{ openstack_service_token_roles_required | default(True) }}"
magnum_service_region: "{{ service_region | default('RegionOne') }}"
magnum_barbican_service_region: "{{ magnum_service_region }}"
magnum_cinder_service_region: "{{ magnum_service_region }}"
magnum_glance_service_region: "{{ magnum_service_region }}"
magnum_heat_service_region: "{{ magnum_service_region }}"
magnum_neutron_service_region: "{{ magnum_service_region }}"
magnum_nova_service_region: "{{ magnum_service_region }}"
magnum_keystone_service_region: "{{ magnum_service_region }}"
magnum_octavia_service_region: "{{ magnum_service_region }}"
magnum_bind_port: 9511
magnum_service_proto: http
magnum_service_publicuri_proto: "{{ openstack_service_publicuri_proto | default(magnum_service_proto) }}"
magnum_service_publicurl: "{{ magnum_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ magnum_bind_port }}"
magnum_service_internaluri_proto: "{{ openstack_service_internaluri_proto | default(magnum_service_proto) }}"
magnum_service_internalurl: "{{ magnum_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ magnum_bind_port }}"
magnum_service_adminuri_proto: "{{ openstack_service_adminuri_proto | default(magnum_service_proto) }}"
magnum_service_adminurl: "{{ magnum_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ magnum_bind_port }}"
magnum_service_in_ldap: "{{ service_ldap_backend_enabled | default(False) }}"

magnum_management_address: "{{ management_address | default('127.0.0.1') }}"

magnum_config_overrides: {}
magnum_policy_overrides: {}
magnum_api_paste_ini_overrides: {}
magnum_keystone_auth_default_policy: []

magnum_pip_install_args: "{{ pip_install_options | default('') }}"
magnum_pip_install_env: "{{ {'REQUESTS_CA_BUNDLE': _venv_install_ca_bundle_path} | combine(_magnum_pip_install_env | default({})) }}"

# Name of the virtual env to deploy into
magnum_venv_tag: "{{ venv_tag | default('untagged') }}"
magnum_venv_path: "/openstack/venvs/magnum-{{ magnum_venv_tag }}"
magnum_bin: "{{ magnum_venv_path }}/bin"

magnum_git_repo: "https://opendev.org/openstack/magnum"
magnum_git_install_branch: master
magnum_upper_constraints_url: >-
  {{ requirements_git_url | default('https://releases.openstack.org/constraints/upper/' ~ requirements_git_install_branch | default('master')) }}
magnum_git_constraints:
  - "--constraint {{ magnum_upper_constraints_url }}"

# Database vars
magnum_db_setup_host: "{{ openstack_db_setup_host | default('localhost') }}"
magnum_db_setup_python_interpreter: >-
  {{
    openstack_db_setup_python_interpreter | default(
      (magnum_db_setup_host == 'localhost') | ternary(ansible_playbook_python, ansible_facts['python']['executable']))
  }}
magnum_galera_address: "{{ galera_address | default('127.0.0.1') }}"
magnum_galera_database_name: magnum_service
magnum_galera_user: magnum
magnum_galera_use_ssl: "{{ galera_use_ssl | default(False) }}"
magnum_galera_ssl_ca_cert: "{{ galera_ssl_ca_cert | default('') }}"
magnum_galera_port: "{{ galera_port | default('3306') }}"
magnum_db_max_overflow: "{{ openstack_db_max_overflow | default('50') }}"
magnum_db_max_pool_size: "{{ openstack_db_max_pool_size | default('5') }}"
magnum_db_pool_timeout: "{{ openstack_db_pool_timeout | default('30') }}"
magnum_db_connection_recycle_time: "{{ openstack_db_connection_recycle_time | default('600') }}"

# Oslo Messaging vars
# RPC
magnum_oslomsg_rpc_host_group: "{{ oslomsg_rpc_host_group | default('rabbitmq_all') }}"
magnum_oslomsg_rpc_setup_host: "{{ (magnum_oslomsg_rpc_host_group in groups) | ternary(groups[magnum_oslomsg_rpc_host_group][0], 'localhost') }}"
magnum_oslomsg_rpc_transport: "{{ oslomsg_rpc_transport | default('rabbit') }}"
magnum_oslomsg_rpc_servers: "{{ oslomsg_rpc_servers | default('127.0.0.1') }}"
magnum_oslomsg_rpc_port: "{{ oslomsg_rpc_port | default('5672') }}"
magnum_oslomsg_rpc_use_ssl: "{{ oslomsg_rpc_use_ssl | default(False) }}"
magnum_oslomsg_rpc_userid: magnum
magnum_oslomsg_rpc_policies: []
# vhost name depends on value of oslomsg_rabbit_quorum_queues. In case quorum queues
# are not used - vhost name will be prefixed with leading `/`.
magnum_oslomsg_rpc_vhost:
  - name: /magnum
    state: "{{ magnum_oslomsg_rabbit_quorum_queues | ternary('absent', 'present') }}"
  - name: magnum
    state: "{{ magnum_oslomsg_rabbit_quorum_queues | ternary('present', 'absent') }}"
magnum_oslomsg_rpc_ssl_version: "{{ oslomsg_rpc_ssl_version | default('TLSv1_2') }}"
magnum_oslomsg_rpc_ssl_ca_file: "{{ oslomsg_rpc_ssl_ca_file | default('') }}"

# Notify
magnum_oslomsg_notify_configure: "{{ oslomsg_notify_configure | default(magnum_ceilometer_enabled) }}"
magnum_oslomsg_notify_host_group: "{{ oslomsg_notify_host_group | default('rabbitmq_all') }}"
magnum_oslomsg_notify_setup_host: "{{ (magnum_oslomsg_notify_host_group in groups) | ternary(groups[magnum_oslomsg_notify_host_group][0], 'localhost') }}"
magnum_oslomsg_notify_transport: "{{ oslomsg_notify_transport | default('rabbit') }}"
magnum_oslomsg_notify_servers: "{{ oslomsg_notify_servers | default('127.0.0.1') }}"
magnum_oslomsg_notify_port: "{{ oslomsg_notify_port | default('5672') }}"
magnum_oslomsg_notify_use_ssl: "{{ oslomsg_notify_use_ssl | default(False) }}"
magnum_oslomsg_notify_userid: "{{ magnum_oslomsg_rpc_userid }}"
magnum_oslomsg_notify_password: "{{ magnum_oslomsg_rpc_password }}"
magnum_oslomsg_notify_vhost: "{{ magnum_oslomsg_rpc_vhost }}"
magnum_oslomsg_notify_ssl_version: "{{ oslomsg_notify_ssl_version | default('TLSv1_2') }}"
magnum_oslomsg_notify_ssl_ca_file: "{{ oslomsg_notify_ssl_ca_file | default('') }}"
magnum_oslomsg_notify_policies: []

## RabbitMQ integration
magnum_oslomsg_rabbit_quorum_queues: "{{ oslomsg_rabbit_quorum_queues | default(True) }}"
magnum_oslomsg_rabbit_stream_fanout: "{{ oslomsg_rabbit_stream_fanout | default(magnum_oslomsg_rabbit_quorum_queues) }}"
magnum_oslomsg_rabbit_transient_quorum_queues: "{{ oslomsg_rabbit_transient_quorum_queues | default(magnum_oslomsg_rabbit_stream_fanout) }}"
magnum_oslomsg_rabbit_qos_prefetch_count: "{{ oslomsg_rabbit_qos_prefetch_count | default(magnum_oslomsg_rabbit_stream_fanout | ternary(10, 0)) }}"
magnum_oslomsg_rabbit_queue_manager: "{{ oslomsg_rabbit_queue_manager | default(magnum_oslomsg_rabbit_quorum_queues) }}"
magnum_oslomsg_rabbit_quorum_delivery_limit: "{{ oslomsg_rabbit_quorum_delivery_limit | default(0) }}"
magnum_oslomsg_rabbit_quorum_max_memory_bytes: "{{ oslomsg_rabbit_quorum_max_memory_bytes | default(0) }}"

# Keystone AuthToken/Middleware
magnum_keystone_auth_plugin: password
magnum_service_project_domain_name: Default
magnum_service_user_domain_name: Default

# Trustee User
magnum_trustee_domain_admin_name: trustee_domain_admin
magnum_trustee_domain_name: magnum
magnum_trustee_domain_admin_roles:
  - admin
magnum_cluster_user_trust: true

# Glance images
## Example Glance Image - Fedora CoreOS
#  - name: fedora-coreos-latest
#    disk_format: qcow2
#    image_format: bare
#    visibility: public
#    url: https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/38.20230806.3.0/x86_64/fedora-coreos-38.20230806.3.0-openstack.x86_64.qcow2.xz
#    properties:
#      os_distro: "fedora-coreos"
#    checksum: "da359b10f9aa165c4f81e6cd9ca5f81b"
magnum_glance_images: []

# Define cluster templates to create. It should be list of
# dictionaries with keys that are supported by os_coe_cluster_template
# module (https://docs.ansible.com/ansible/latest/modules/os_coe_cluster_template_module.html)
# magnum_cluster_templates:
#   - name: k8s
#     cloud: default
#     coe: kubernetes
#     docker_volume_size: 50
#     external_network_id: public
#     network_driver: flannel
magnum_cluster_templates: []

# Create extra flavors to be used by magnum cluster template. It should be list
# of dictionaries with keys that are supported by os_nova_flavor module
# (https://docs.ansible.com/ansible/latest/modules/os_nova_flavor_module.html)
# magnum_flavors:
#   - name: k8s-pod
#     cloud: default
#     ram: 256
#     vcpus: 1
#     disk: 5
magnum_flavors: []

# Available drivers:
# - "vexxhost" - named as k8s_cluster_api in Magnum
# - "azimuth" - named as k8s_capi_helm in Magnum
# - "heat" - deprecated since 2025.1, removed in 2026.2
magnum_k8s_driver: heat

# Set the directory where the downloaded images will be stored
# on the magnum_service_setup_host host. If the host is localhost,
# then the user running the playbook must have access to it.
magnum_image_path: "{{ lookup('env', 'HOME') }}/openstack-ansible/magnum"
magnum_image_path_owner: "{{ lookup('env', 'USER') }}"

magnum_pip_packages:
  - "git+{{ magnum_git_repo }}@{{ magnum_git_install_branch }}#egg=magnum"
  - osprofiler
  - PyMySQL
  - pymemcache
  - python-memcached
  - systemd-python

# Memcached override
magnum_memcached_servers: "{{ memcached_servers }}"

# Specific pip packages provided by the user
magnum_user_pip_packages: []

# Store certificates in DB by default (x509keypair)
# Other valid values are: barbican, local
magnum_cert_manager_type: x509keypair

magnum_api_init_config_overrides: {}
magnum_conductor_init_config_overrides: {}

magnum_services:
  magnum-conductor:
    group: magnum_all
    service_name: magnum-conductor
    execstarts: "{{ magnum_bin }}/magnum-conductor"
    init_config_overrides: "{{ magnum_conductor_init_config_overrides }}"
    start_order: 1
  magnum-api:
    group: magnum_all
    service_name: magnum-api
    init_config_overrides: "{{ magnum_api_init_config_overrides }}"
    start_order: 2
    wsgi_app: true
    wsgi: "magnum.wsgi.api:application"
    uwsgi_overrides: "{{ magnum_api_uwsgi_ini_overrides }}"
    uwsgi_port: "{{ magnum_bind_port }}"
    uwsgi_bind_address: "{{ magnum_api_uwsgi_bind_address }}"
    uwsgi_tls: "{{ magnum_backend_ssl | ternary(magnum_uwsgi_tls, {}) }}"

# uWSGI Settings
magnum_api_uwsgi_ini_overrides: {}
magnum_wsgi_processes_max: 16
magnum_wsgi_processes: >-
  {{ [[(ansible_facts['processor_vcpus'] // ansible_facts['processor_threads_per_core']) | default(1), 1] | max * 2, magnum_wsgi_processes_max] | min }}
magnum_wsgi_threads: 1
magnum_api_uwsgi_bind_address: "{{ openstack_service_bind_address | default('0.0.0.0') }}"
magnum_uwsgi_tls:
  crt: "{{ magnum_ssl_cert }}"
  key: "{{ magnum_ssl_key }}"

# conductor settings
magnum_conductor_workers_max: 16
magnum_conductor_workers: >-
  {{ [[(ansible_facts['processor_vcpus'] // ansible_facts['processor_threads_per_core']) | default(1), 1] | max * 2, magnum_conductor_workers_max] | min }}

###
### Backend TLS
###

# Define if communication between haproxy and service backends should be
# encrypted with TLS(works only with uWSGI).
magnum_backend_ssl: "{{ openstack_service_backend_ssl | default(False) }}"

# Storage location for SSL certificate authority
magnum_pki_dir: "{{ openstack_pki_dir | default('/etc/openstack_deploy/pki') }}"

# Delegated host for operating the certificate authority
magnum_pki_setup_host: "{{ openstack_pki_setup_host | default('localhost') }}"

# magnum server certificate
magnum_pki_keys_path: "{{ magnum_pki_dir ~ '/certs/private/' }}"
magnum_pki_certs_path: "{{ magnum_pki_dir ~ '/certs/certs/' }}"
magnum_pki_intermediate_cert_name: "{{ openstack_pki_service_intermediate_cert_name | default('ExampleCorpIntermediate') }}"
magnum_pki_regen_cert: ""
magnum_pki_san: "{{ openstack_pki_san | default({'dns': [ansible_facts['hostname']], 'ip': [management_address]}) }}"
magnum_pki_backend: "{{ openstack_pki_backend | default('standalone') }}"
magnum_pki_certificates:
  - name: "magnum_{{ ansible_facts['hostname'] }}"
    cn: "{{ ansible_facts['hostname'] }}"
    san: "{{ magnum_pki_san }}"
    # standalone backend only
    provider: ownca
    signed_by: "{{ magnum_pki_intermediate_cert_name }}"

# magnum destination files for SSL certificates
magnum_ssl_cert: /etc/magnum/magnum.pem
magnum_ssl_key: /etc/magnum/magnum.key

# Installation details for SSL certificates
magnum_pki_install_certificates:
  - name: "magnum_{{ ansible_facts['hostname'] }}"
    type: "certificate_chain"
    dest: "{{ magnum_ssl_cert }}"
    owner: "{{ magnum_system_user_name }}"
    group: "{{ magnum_system_user_name }}"
    # standalone backend only
    src: "{{ magnum_user_ssl_cert | default(magnum_pki_certs_path ~ 'magnum_' ~ ansible_facts['hostname'] ~ '-chain.crt') }}"
  - name: "magnum_{{ ansible_facts['hostname'] }}"
    type: "private_key"
    dest: "{{ magnum_ssl_key }}"
    owner: "{{ magnum_system_user_name }}"
    group: "{{ magnum_system_user_name }}"
    # standalone backend only
    src: "{{ magnum_user_ssl_key | default(magnum_pki_keys_path ~ 'magnum_' ~ ansible_facts['hostname'] ~ '.key.pem') }}"

# Define user-provided SSL certificates
magnum_user_ssl_cert: ""
magnum_user_ssl_key: ""

# Cluster API
magnum_capi_control_cluster_group: k8s_all
magnum_capi_ca_file: "{{ _magnum_capi_ca_file }}"
magnum_capi_pip_packages: "{{ _magnum_capi_pip_packages | default([]) }}"
magnum_capi_build_requirements: "{{ _magnum_capi_build_requirements | default([]) }}"
magnum_capi_network_driver_default: "calico"
magnum_capi_network_drivers:
  - "calico"

# Cluster API Vexxhost defaults
magnum_capi_vexxhost_git_install_branch: main
magnum_capi_vexxhost_git_repo: https://github.com/vexxhost/magnum-cluster-api
magnum_capi_vexxhost_rust_cargo_config_path: "/root/.cargo/config.toml"
magnum_capi_vexxhost_rust_cargo_config: ""

# Cluster API Vexxhost proxy defaults
magnum_capi_vexxhost_proxy_system_group_name: 'capi_proxy'
magnum_capi_vexxhost_proxy_system_user_name: 'capi_proxy'
magnum_capi_vexxhost_proxy_system_user_comment: 'Magnum Cluster API Proxy System User'
magnum_capi_vexxhost_proxy_system_user_home: '/var/lib/{{ magnum_capi_vexxhost_proxy_system_user_name }}'
magnum_capi_vexxhost_proxy_system_user_shell: '/bin/false'

magnum_capi_vexxhost_proxy_upper_constraints_url: >-
  {{ requirements_git_url | default('https://releases.openstack.org/constraints/upper/' ~ requirements_git_install_branch | default('master')) }}
magnum_capi_vexxhost_proxy_git_constraints:
  - "--constraint {{ magnum_capi_vexxhost_proxy_upper_constraints_url }}"

magnum_capi_vexxhost_proxy_install_branch: "{{ magnum_capi_vexxhost_git_install_branch | default('main') }}"
magnum_capi_vexxhost_proxy_git_repo: "{{ magnum_capi_vexxhost_git_repo }}"

magnum_capi_vexxhost_proxy_pip_packages:
  - "{{ 'magnum-cluster-api@git+' ~ magnum_capi_vexxhost_proxy_git_repo ~ '@' ~ magnum_capi_vexxhost_proxy_install_branch }}"

magnum_capi_vexxhost_proxy_venv_tag: "{{ venv_tag | default('untagged') }}"
magnum_capi_vexxhost_proxy_bin: "/openstack/venvs/magnum-cluster-api-proxy-{{ magnum_capi_vexxhost_proxy_venv_tag }}/bin"

magnum_capi_vexxhost_k8s_conf_src: "{{ k8s_admin_conf_src | default('/etc/kubernetes/admin.conf') }}"
magnum_capi_vexxhost_k8s_conf_dest: "{{ k8s_admin_conf_dest | default(magnum_capi_vexxhost_proxy_system_user_home ~ '/.kube/config') }}"

magnum_capi_vexxhost_proxy_environment: {}

# Cluster API Azimuth HELM defaults
magnum_capi_azimuth_git_install_branch: master
magnum_capi_azimuth_git_repo: https://opendev.org/openstack/magnum-capi-helm
magnum_capi_azimuth_helm_base_url: https://azimuth-cloud.github.io
magnum_capi_azimuth_helm_addon_provider_version: 0.10.4
magnum_capi_azimuth_helm_charts_version: 0.22.0
magnum_capi_azimuth_helm_charts:
  - name: cluster-api-addon-provider
    namespace: addon-namespace
    repo_url: "{{ magnum_capi_azimuth_helm_base_url }}/cluster-api-addon-provider"
    version: "{{ magnum_capi_azimuth_helm_addon_provider_version }}"
  - name: etcd-defrag
    namespace: "addon-namespace"
    repo_url: "{{ magnum_capi_azimuth_helm_base_url }}/capi-helm-charts"
    version: "{{ magnum_capi_azimuth_helm_charts_version }}"
  - name: cluster-addons
    namespace: "addon-namespace"
    repo_url: "{{ magnum_capi_azimuth_helm_base_url }}/capi-helm-charts"
    version: "{{ magnum_capi_azimuth_helm_charts_version }}"

Example playbook

---
- name: Install Magnum server
  hosts: magnum_all
  user: root
  roles:
    - role: "os_magnum"
      tags:
        - os-magnum"
  vars:
    magnum_galera_address: "{{ internal_lb_vip_address }}"
    magnum_galera_password: secrete
    magnum_service_password: secrete
    magnum_oslomsg_rpc_password: secrete
    magnum_trustee_password: secrete

Tags

In addition to generic OpenStack-Ansible tags, this role supports two tags:

  • magnum-install - can be used to install and upgrade the service

  • magnum-config - can be used to maintain configuration of the

    service