Ansible - Configuration Modules

Ansible
Published

August 9, 2018

Modified

July 25, 2024

Modules provide the configuration capabilities…

Types of modules…

command

Read the section about ad-hoc commands above

Execute a command and register its output, execute another commend depending on its output…

- name: Read Apptainer bind path configuration
  ansible.builtin.command: 'apptainer config global --get "bind path"'
  register: apptainer_bind_path
  changed_when: false

- name: Add /lustre to the Apptainer bind path configuration
  ansible.builtin.command: 'apptainer config global --set "bind path" /lustre'
  when: apptainer_bind_path.stdout.find('lustre') == -1

Users & Groups

ansible.builtin.user and ansible.builtin.group

- name: Set password for the root account
  ansible.builtin.user:
    name: root
    password: '$6$/DILhqdfs3fse5ReEtJaqS...'

- name: Ensure an admin group exists
  ansible.builtin.group:
    name: admin

- name: Create all admin users
  ansible.builtin.user:
    name: "{{ item.name }}"
    uid: "{{ item.uid }}"
    group: admin
    create_home: true
  with_items:
    - name: alice_adm
      uid: 986
    - name: bob_adm
      uid: 987

ansible.posix.authorized_key adds or removes an SSH authorized key…

---
- name: Set authorized key for root user removing all the authorized keys already set
  ansible.posix.authorized_key:
    user: root
    key: "{{ lookup('file', 'files/ssh-authorized-keys') }}"
    state: present
    exclusive: true

Packages

ansible.builtin.dnf …manages packages with the dnf package manager

- name: Install dependency packages
  ansible.builtin.dnf:
    name:
      - git
      - podman
    state: installed

Templating

Templates are processed by the Jinja2 templating language…

  • …enables dynamic expressions and access to variables and facts
  • Used to…
    • …create a template for a configuration file
    • …template task names and more
  • …templating happens on the Ansible controller

Default Jinja delimiters…

  • {% ... %} …statements
  • { ... } …expressions …print to the template output
  • {# ... #} …comments

ansible.builtin.template module…

  • …file name suffix for the templates .j2
  • …templates are loaded with trim_blocks=True …newlines removed from blocks

Example templates/smatd.j2 using a registered variable…

DEFAULT -H -m smart-notify@example.org -M once -M exec /usr/libexec/smartmontools/smartdnotify
{{ smartctl_scan_open.stdout }}

…using the ansible.builtin.template module…

#...
    - name: Execute smartctl --scan-open
      ansible.builtin.command: 'smartctl --scan-open'
      register: smartctl_scan_open
      changed_when: false

    - name: Create configuration file /etc/smartmontools/smartd.conf
      ansible.builtin.template:
        src: ../templates/smartmontools/smartd.j2
        dest: /etc/smartmontools/smartd.conf
      notify: smartd_restart
#...

Services

service

ansible.builtin.service module manages service…

  • …supports all common init-systems (like Systemd, SysV, etc)
  • …acts as a proxy to the underlying service manager module

Restart a service if a configuration file is changes…

handlers:
  - name: restart chronyd service
    listen: chronyd_restart
    ansible.builtin.service:
      name: chronyd
      state: restarted

tasks:
  - name: change NTP server address in chrony.conf
    ansible.builtin.lineinfile:
      path: /etc/chrony.conf
      backup: true
      regexp: '^pool '
      firstmatch: true
      line: 'pool 1.pool.ntp.org iburst'
    notify: chronyd_restart

systemd_service

ansible.builtin.systemd_service manages Systemd units…

Create a Systemd service unit file and start the service…

#...
    - name: Create systemd set-timezone.service unit file
      ansible.builtin.copy:
        src: files/set-timezone.ini
        dest: /etc/systemd/system/set-timezone.service
    
    - name: Enable/start systemd set-timezone.service
      ansible.builtin.systemd_service:
        name: set-timezone.service
        daemon_reload: yes
        enabled: true
        state: started
#...

SELinux

Configure SELinux with ansible.posix.selinux

- ansible.builtin.lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: 'SELINUX=disabled'
#...or...
- name: Disable SELinux
  ansible.posix.selinux:
    state: disabled

ansible.posix.seboolean …toggle SELinux booleans

community.general.seport …manages SELinux network port type definitions

# ...requirements needed on the host that executes this module
- name: install python packages for selinux
  ansible.builtin.dnf:
    name:
      - python3-libselinux
      - python3-policycoreutils
    state: installed

# ...allow SSH to listen on another port
- name: Allow sshd to listen on tcp port 2849
  community.general.seport:
    ports: 2849
    proto: tcp
    setype: ssh_port_t
    state: present

Containers

containers.podman module collection…

  • containers.podman.podman_image …pull/build container images
  • containers.podman.podman_container …manage container instances
---
- hosts: pxesrv_server
  become: true
  gather_facts: false

  vars:
    pxesrv_repo: /opt/pxesrv
    pxesrv_root: /srv/pxesrv

  tasks:
    - name: Install dependency packages
      ansible.builtin.dnf:
        name:
          - git
          - podman
        state: installed

    - name: Clone PXESrv source code to {{pxesrv_repo}}
      ansible.builtin.git:
        repo: "https://github.com/vpenso/pxesrv"
        dest: "{{pxesrv_repo}}"

    # ...build a container image from the Dockerfile in the source code repository
    - name: Build PXESrv container image in {{pxesrv_repo}}
      containers.podman.podman_image:
        state: build
        force: true
        name: pxesrv
        path: "{{pxesrv_repo}}"

    - name: Make sure {{pxesrv_root}} exists
      ansible.builtin.file:
        state: directory
        path: "{{pxesrv_root}}"

    # ...configure the container instance and create a systemd unit file
    - name: Start PXESrv container
      containers.podman.podman_container:
        state: present
        name: pxesrv
        image: localhost/pxesrv:latest
        log_opt:
          path: /var/log/pxesrv.log
        expose:
          - 4567
        volume:
          - "{{pxesrv_root}}"
        generate_systemd:
          path: /etc/systemd/system
          restart_policy: always

    # ...make sure the container is started by the systemd unit
    - name: Enable/start container-pxesrv.service
      ansible.builtin.systemd_service:
        name: container-pxesrv.service
        enabled: true
        state: started

Raw

Use ansible.builtin.raw 2 for an environment without a python interpreter…

  • Executes commands directly on the remote shell and returns standard output/error, and the return code
  • Process the command standard output with ansible.builtin.regex_search 3
    • …pattern matching is implemented with Python re.search 4
    • …regex can be conveniently tested on https://pythex.org/
  • Set variables with information extracted from the command output with ansible.builtin.set_fact 5
---
- name: Update BIOS firmware
  tags: bios_firmware
  block:

    - name: Gather output version information from the BMC
      ansible.builtin.raw: 'ipmcget -d version'
      register: ipmcget_version

    - name: Extract the active BIOS version information
      ansible.builtin.set_fact:
        bios_version: "{{ ipmcget_version.stdout | ansible.builtin.regex_search(regex, '\\1', multiline=True) }}"
      vars:
        regex: '^Active BIOS[  ]*Version:[ (]*U[0-9]*[)](\d{1}\.\d{2}\.\d{2})'

    - local_action: ansible.builtin.command scp {{role_path}}/files/fusion/2258V7/bios-2.09.17.hpm {{ansible_user}}@{{inventory_hostname}}:/tmp/bios-2.09.17.hpm
      when: bios_version != "2.09.17"

Footnotes

  1. Git Module, Ansible Community Documentation
    https://docs.ansible.com/ansible/latest/collections/ansible/builtin/git_module.html↩︎

  2. ansible.builtin.raw module, Ansible Community Documentation
    https://docs.ansible.com/ansible/latest/collections/ansible/builtin/raw_module.html↩︎

  3. ansible.builtin.regex_search module, Ansible Community Documentation
    https://docs.ansible.com/ansible/latest/collections/ansible/builtin/regex_search_filter.html↩︎

  4. re Regular Expression Operations, Python Standard Library
    https://docs.python.org/3/library/re.html↩︎

  5. ansible.builtin.set_fact module, Ansible Community Documentation
    https://docs.ansible.com/ansible/latest/collections/ansible/builtin/set_fact_module.html↩︎