Skip to content
Snippets Groups Projects
README.md 8.2 KiB
Newer Older
Chris Croome's avatar
Chris Croome committed
# Webarchitects systemd Ansible role
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
[![pipeline status](https://git.coop/webarch/systemd/badges/main/pipeline.svg)](https://git.coop/webarch/systemd/-/commits/main)

Chris Croome's avatar
Chris Croome committed
`systemd` is a [System and Service Manager](https://systemd.io/) that _"runs as PID 1 and starts the rest of the system"_.

Chris Croome's avatar
Chris Croome committed
This repo contains an Ansible role for configuring systemd services on Debian, this role has been designed to be as generic as possible in order to enable to it be used to configure any systemd service, by default it configures `systemd-timesyncd`.

Chris Croome's avatar
Chris Croome committed
On Debian Buster [backports](https://backports.debian.org/Instructions/) is required to get the [latest version of systemd](https://packages.debian.org/buster-backports/systemd), the [Webarchitects apt role](https://git.coop/webarch/apt) can be used to enable backports.
Chris Croome's avatar
Chris Croome committed
## Role variables

Chris Croome's avatar
Chris Croome committed
See the [defaults/main.yml](defaults/main.yml) file for the default variables and [meta/argument_specs.yml](meta/argument_specs.yml) for the variable specification.
Chris Croome's avatar
Chris Croome committed

### systemd

Chris Croome's avatar
Chris Croome committed
Set the `systemd` variable to `false` to prevent any tasks in this role being run.

The `systemd` variable defaults to `true`.
Chris Croome's avatar
Chris Croome committed

### systemd_delete_broken_symlinks

Delete broken symlinks found in the `/etc/systemd` directory, `systemd_delete_broken_symlinks` defaults to `false`.

### systemd_delete_devnull_symlinks

Delete symlinks that point to `/dev/null` in the `/etc/systemd` directory, `systemd_delete_devnull_symlinks` defaults to `false`.

Chris Croome's avatar
Chris Croome committed
### systemd_timesyncd_reboot

Chris Croome's avatar
Chris Croome committed
When the `systemd_timesyncd_reboot` variable is set to `true` servers which have incorrect clocks will be rebooted by this role in order to correct their clocks.

The `systemd_timesyncd_reboot` variable defaults to `false`.
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
### systemd_tz

Chris Croome's avatar
Chris Croome committed
The time zone to be used (the hardware clock is set to UTC), for example `Europe/London`.

The `systemd_tz` variable defaults to `Etc/UTC`.
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
### systemd_units

Chris Croome's avatar
Chris Croome committed
`systemd_units` is a list of systemd units to configure, for example:
Chris Croome's avatar
Chris Croome committed

```yaml
systemd_units:
  - name: systemd-timesyncd
    files:
      - path: /etc/systemd/timesyncd.conf
        comment: |
          Entries in this file show the compile time defaults.
          You can change settings by editing this file.
          Defaults can be restored by simply deleting this file.
          See timesyncd.conf(5) for details.
        conf:
          Time:
            NTP: 0.pool.ntp.org 1.pool.ntp.org 3.pool.ntp.org 2.pool.ntp.org
        state: present
Chris Croome's avatar
Chris Croome committed
    pkgs:
      - systemd-timesyncd
    state: present
    unit_state: started
    verify: systemd-timesyncd.service
Chris Croome's avatar
Chris Croome committed
  - name: systemd-networkd
    files:
      - path: /etc/systemd/network/eth0.network
        state: templated
        conf:
          Match:
            Name: eth0
            Type: ether
          Network:
            Address:
              - 192.168.0.2/24
              - 192.168.0.3/24
            Gateway: 192.168.0.1
    verify: networking.service
```

Note that lists like:

```yaml
Address:
  - 192.168.0.2/24
  - 192.168.0.3/24 
```

Are converted into duplicates:

```ini
Address=81.95.52.56/24
Address=81.95.52.57/24
Chris Croome's avatar
Chris Croome committed
```

Chris Croome's avatar
Chris Croome committed
#### name

Chris Croome's avatar
Chris Croome committed
The only required variables is `name`, see the [meta/argument_specs.yml](meta/argument_specs.yml) for the variable types.

Chris Croome's avatar
Chris Croome committed
#### files
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
The `files` variable is a list of files, which can use the following variables:
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
##### path

The `path` variable is the path to the file to configure.

##### comment

The `comment` variable can be used for commented text at the top of the file.

##### conf
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
The `conf` dictionary defines the systemd `ini` file variables, as a dictionary. The depth of the dictionary defines the type of file generated, for example to generate a systemd environment file:

```yaml
conf:
  FOO: bar
```

And to generate generate a systemd unit file:

```yaml
conf:
  Unit:
    Description: Docker Compose container starter
```

Chris Croome's avatar
Chris Croome committed
When files are updated or deleted backups are created based on the existing file name but prefixed with a leading `.` and suffixed with a timestamp in ISO8601 format and the file extension `.bak`.

Chris Croome's avatar
Chris Croome committed
##### state

The `files` can optionally have one of four optional states set:

* `absent` - the file will be deleted.
Chris Croome's avatar
Chris Croome committed
* `edited` - the existing file will be edited using the [Ansible ini module](https://docs.ansible.com/ansible/latest/collections/community/general/ini_file_module.html), as long as there are no duplicates, if there are the file will be templated.
* `present` - if the file exists it will be edited using the [Ansible ini module](https://docs.ansible.com/ansible/latest/collections/community/general/ini_file_module.html), as long as there are no duplicates, if there are duplicates or it doesn't exist it will be created using the [templates/unit.j2](templates/unit.j2) template.
Chris Croome's avatar
Chris Croome committed
* `templated` - the file will be created if it does not exist or updated if it already exists using the [templates/unit.j2](templates/unit.j2) template.

If the `files` `state` is not set it defaults to `present`. The `edited` option can not remove variables and, unlike the `templated` option, it preserves existing comments.

#### pkgs

Chris Croome's avatar
Chris Croome committed
The `pkgs` variable is a list of `.deb` packages which will be installed when the `state` is present and removed when `absent`.

Chris Croome's avatar
Chris Croome committed
#### state
Chris Croome's avatar
Chris Croome committed

The `systemd_units` list elements can have a `state` of `absent` or `present`.

#### unit_enabled

A boolean, `unit_enabled` determins if the untit is enabled or not.
Chris Croome's avatar
Chris Croome committed

#### unit_state

The `unit_state` variable is used for the [Ansible systemd module state](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/systemd_module.html#parameter-state) so it can be one of `reloaded`, `restarted`, `started` or `stopped`.
Chris Croome's avatar
Chris Croome committed

#### verify

A service name to be passed to `systemd-analyze verify`.

Chris Croome's avatar
Chris Croome committed
A list of services that can be verified can be generated using:

```bash
systemctl list-unit-files | jc --systemctl-luf | jp "[?state == 'enabled'].unit_file"
```

Chris Croome's avatar
Chris Croome committed
This role can be included in another role along these lines (this has been based on [this gist](https://gist.github.com/Luzifer/7c54c8b0b61da450d10258f0abd3c917)):

```yaml
- name: Include systemd role
  ansible.builtin.include_role:
    name: systemd
    tasks_from: unit_present.yml
  vars:
    systemd_unit:
      name: docker-compose
      files:
Chris Croome's avatar
Chris Croome committed
        - path: /etc/systemd/docker-compose.conf
          conf:
            DOCKER_COMPOSE_VERSION: native
        - path: /etc/systemd/service/docker-compose.service
          conf:
            Unit:
              Description: Docker Compose container starter
              After: docker.service network-online.target
              Requires: docker.service network-online.target
            Service:
Chris Croome's avatar
Chris Croome committed
              User: mailcow
              Group: mailcow
              EnvironmentFile: /etc/systemd/system/sharedfutures.conf
              WorkingDirectory: /opt/mailcow-dockerized
              Type: oneshot
              RemainAfterExit: "yes"
              ExecStart: docker compose up -d
              ExecStop: docker compose down
            Install:
              WantedBy: multi-user.target
```

Chris Croome's avatar
Chris Croome committed
## Read existing systemd files as YAML using jc
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
You can read existing systemd files as YAML on the command line using [jc](https://github.com/kellyjonbrazil/jc), for example:
Chris Croome's avatar
Chris Croome committed

```bash
cat /etc/systemd/timesyncd.conf | jc --ini -py
---
Time:
  NTP: 0.pool.ntp.org 1.pool.ntp.org 3.pool.ntp.org 2.pool.ntp.org
```

Chris Croome's avatar
Chris Croome committed
Note that the [jc --ini parser](https://kellyjonbrazil.github.io/jc/docs/parsers/ini) doesn't support duplicate keys.

Chris Croome's avatar
Chris Croome committed
## Dependencies

This role requires Ansible `2.13` or newer, [JC](https://pypi.org/project/jc/) and [JMESPath](https://pypi.org/project/jmespath/) to be installed using `pip3` on the Ansible controller.
Chris Croome's avatar
Chris Croome committed

Chris Croome's avatar
Chris Croome committed
## Repository
Chris Croome's avatar
Chris Croome committed

The primary URL of this repo is [`https://git.coop/webarch/systemd`](https://git.coop/webarch/systemd) however it is also [mirrored to GitHub](https://github.com/webarch-coop/ansible-role-systemd) and [available via Ansible Galaxy](https://galaxy.ansible.com/chriscroome/systemd).

If you use this role please use a tagged release, see [the release notes](https://git.coop/webarch/systemd/-/releases).

## Copyright

Copyright 2019-2023 Chris Croome, <[chris@webarchitects.co.uk](mailto:chris@webarchitects.co.uk)>.
Chris Croome's avatar
Chris Croome committed

This role is released under [the same terms as Ansible itself](https://github.com/ansible/ansible/blob/devel/COPYING), the [GNU GPLv3](LICENSE).