Skip to content

Repository files navigation

Ansible Collection - bodsch.systemd

Documentation for the collection.

Roles

Role Description
bodsch.systemd.coredump GitHub Workflow Status configure systemd-coredump
bodsch.systemd.homed GitHub Workflow Status configure systemd-homed
bodsch.systemd.journald GitHub Workflow Status configure systemd-journald
bodsch.systemd.oomd GitHub Workflow Status configure systemd-oomd
bodsch.systemd.logind GitHub Workflow Status configure systemd-logind
bodsch.systemd.networkd GitHub Workflow Status configure systemd-networkd
bodsch.systemd.resolved GitHub Workflow Status configure systemd-resolved
bodsch.systemd.system GitHub Workflow Status configure systemd-system
bodsch.systemd.timesyncd GitHub Workflow Status configure systemd-timesyncd
bodsch.systemd.user GitHub Workflow Status configure systemd-user

Included content

Modules

Name Description
bodsch.systemd.journalctl Query the systemd journal with a very limited number of possible parameters
bodsch.systemd.unit_file This can be used to create a systemd unit file. The service, timer and socket types are supported.
bodsch.systemd.systemd_timer This can be used to create a systemd timer file, for the system or for a specific user, and optionally enable it / reload the manager.
bodsch.systemd.networkd_profiles Manages a whole set of systemd-networkd profile files. (.link / .netdev / .network)

Installing this collection

You can install the memsource collection with the Ansible Galaxy CLI:

#> ansible-galaxy collection install bodsch.systemd

To install directly from GitHub:

#> ansible-galaxy collection install git@github.com:bodsch/ansible-collection-systemd.git

You can also include it in a requirements.yml file and install it with ansible-galaxy collection install -r requirements.yml, using the format:

---
collections:
  - name: bodsch.systemd

The python module dependencies are not installed by ansible-galaxy. They can be manually installed using pip:

#> pip install -r requirements.txt

Important

The bodsch.systemd.systemd_timer module talks to the system service manager over D-Bus when enabled or daemon_reload is used with scope: system. This requires the python3-dbus library (the dbus Python bindings) to be present on the target host. It is best installed via the distribution package rather than pip:

#> apt-get install python3-dbus     # Debian / Ubuntu
#> dnf install python3-dbus         # Fedora / RHEL
#> pacman -S python-dbus            # Arch Linux

Pure file rendering (creating the .timer file without enabled / daemon_reload) does not require python3-dbus.

Using this collection

You can either call modules by their Fully Qualified Collection Name (FQCN), such as bodsch.systemd.coredump, or you can call modules by their short name if you list the bodsch.systemd collection in the playbook's collections keyword:

---
- name: configure systemd coredump
  bodsch.systemd.coredump:
    process_size_max: 32G
    external_size_max: 32G

Examples

bodsch.systemd.journalctl

- name: last 50 chrony entries, newest first
  bodsch.systemd.journalctl:
    identifier: chrony
    lines: 50
    reverse: true
  register: chrony_log

- name: errors from systemd-networkd in the last hour, as parsed entries
  bodsch.systemd.journalctl:
    unit: systemd-networkd.service
    priority: err
    since: "1 hour ago"
    output: json
  register: networkd_errors

- name: query several units at once
  bodsch.systemd.journalctl:
    units:
      - nginx.service
      - php-fpm.service
    priority: warning
    lines: 200

- name: query the systemd journal
  bodsch.systemd.journalctl:
    identifier: chrony
    lines: 150
  register: journalctl
  when:
    - restarted is defined
    - restarted.failed
    - chrony_query_journald
    - ansible_service_mgr == 'systemd'
  notify:
    - journalctl output

- name: journalctl output
  ansible.builtin.debug:
    msg: "{{ journalctl.stdout }}"
  when:
    journalctl.stdout is defined

bodsch.systemd.systemd_timer

name: create systemd timer file
bodsch.systemd.systemd_timer:
  name: certbot-renew
  unit:
    Description: Run Certbot on specific weekdays
  timer:
    persistent: true
    randomized_delay_sec: "43200"
  schedule:
    weekday: "{{ certbot_cron.weekday | default(['Sat']) }}"
    hour: "{{ certbot_cron.hour | default('2') }}"
    minute: "{{ certbot_cron.minute | default('58') }}"
  install:
    wanted_by: timers.target
  path: "{{ systemd_lib_directory }}"
notify:
  - daemon reload

The module can optionally enable the timer and reload the service manager. enabled: true/false runs the equivalent of systemctl enable/disable, and daemon_reload (default true) reloads the manager after the unit file changed:

name: create and enable a systemd timer file
bodsch.systemd.systemd_timer:
  name: certbot-renew
  unit:
    Description: Run Certbot on specific weekdays
  timer:
    persistent: true
  schedule:
    weekday: [Sat]
    hour: 2
    minute: 58
  install:
    wanted_by: timers.target
  enabled: true
  daemon_reload: true

A timer unit can also be created for a specific user. With scope: user the file is written to ~<user>/.config/systemd/user/<name>.timer and is owned by that user (any directories created below the home directory are owned by the user as well):

name: create, enable a per-user systemd timer file
bodsch.systemd.systemd_timer:
  name: backup
  scope: user
  user: alice
  unit:
    Description: Run user backup every morning
  timer:
    persistent: true
  schedule:
    hour: 7
    minute: 0
  install:
    wanted_by: timers.target
  enabled: true

Requirements for enabled / daemon_reload

These two options interact with the running service manager and therefore have additional requirements depending on the scope:

  • scope: system — communicates with the system manager over D-Bus and requires the python3-dbus library on the target host (see Installing this collection). Creating the .timer file without enabled/daemon_reload does not need it.

  • scope: user — the operations are routed to the target user's manager via systemctl --user --machine=<user>@.host, which requires that user's systemd instance to be running. Either an active login session must exist or lingering has to be enabled once with:

    #> loginctl enable-linger <user>

If you only want to render the unit file and handle reloading/enabling elsewhere (e.g. via a handler), set daemon_reload: false and leave enabled unset — then neither requirement applies.

bodsch.systemd.unit_file

- name: create getty drop-ins
  bodsch.systemd.unit_file:
    name: "getty@tty1"
    state: "present"
    unit_type: "service"
    drop_ins:
      - name: autologin
        state: present
        service:
          ExecStart:
            - ""
            - "{% raw %}-/sbin/agetty -o '-p -f -- \\\\u' --noclear --autologin username %I $TERM{% endraw %}"
          Type: simple

      - name: noclear
        state: absent
        service:
          TTYVTDisallocate: false
  when:
    - ansible_facts.service_mgr == 'systemd'

- name: create nextcloud-cron systemd service
  bodsch.systemd.unit_file:
    name: "nextcloud-cron"
    state: "present"
    unit_type: "service"
    unit_file:
      unit:
        Description: Nextcloud cron.php job
      service:
        User: www-data
        ExecCondition: php -f /var/www/nextcloud/server/occ status --exit-code
        ExecStart: /usr/bin/php -f /var/www/nextcloud/server/cron.php
        KillMode: process
  when:
    - ansible_facts.service_mgr == 'systemd'

- name: create nextcloud-cron systemd timer
  bodsch.systemd.unit_file:
    name: "nextcloud-cron"
    state: "present"
    unit_type: "timer"
    unit_file:
      unit:
        Description: Run Nextcloud cron.php every 5 minutes
      timer:
        OnBootSec: 5min
        OnUnitActiveSec: 5min
        Unit: nextcloud-cron.service
      install:
        WantedBy: timers.target
  when:
    - ansible_facts.service_mgr == 'systemd'

- name: create systemd unit files
  bodsch.systemd.unit_file:
    name: "{{ item.name }}"
    state: "{{ item.state }}"
    unit_type: "{{ item.unit_type }}"
    overwrite: "{{ item.overwrite | default(omit) }}"
    drop_ins: "{{ item.drop_ins | default(omit) }}"
    unit_file: "{{ item.unit_file | default(omit) }}"
  loop:
    "{{ systemd_unit }}"
  loop_control:
    label: "{{ item.name }}"
  register: systemd_unit_file
  ignore_errors: true
  when:
    - systemd_unit | count > 0

bodsch.systemd.networkd_profiles

- name: manage networkd profiles with validation
  bodsch.systemd.networkd_profiles:
    profiles:
      network:
        wg0:
          state: present
          config:
            Match:
              Name: wg0
            Network:
              Address: 10.10.0.1/24
            Address:
              - Address: 10.10.0.1/24
                Label: primary
              - Address: 10.10.0.2/24
            Route:
              - Gateway: 10.10.0.254
                Destination: 10.20.0.0/16
              - Gateway: 10.10.0.253
                Destination: 10.30.0.0/16
    validate: true
    purge: false

Contribution

Please read Contribution

Development, Branches (Git Tags)

The master Branch is my Working Horse includes the "latest, hot shit" and can be complete broken!

If you want to use something stable, please use a Tagged Version!

Author

  • Bodo Schulz

License

Apache

FREE SOFTWARE, HELL YEAH!

About

A collection of Ansible roles to manage systemd configurations.

Topics

Resources

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages