Chapter 10: Automating Linux Administration Tasks

Ansible Linux automation cheat sheet

The chapter on one page: one module per job in each of the five areas, and flashcards for quick revision.

The chapter in seven sentences

Cheat sheet

Software

- ansible.builtin.dnf:
    name: [httpd, "@Development Tools"]
    state: present                     # latest | absent
- ansible.builtin.rpm_key:
    key: /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
- ansible.builtin.yum_repository:
    name: lab-crb
    description: Rocky Linux 9 CRB (lab)
    mirrorlist: https://mirrors.rockylinux.org/mirrorlist?arch=$basearch&repo=CRB-$releasever
    gpgcheck: true
    gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
- ansible.builtin.package_facts:

Users

- ansible.builtin.group: { name: webdev }
- ansible.builtin.user:
    name: jane
    groups: webdev
    append: true
    password: "{{ pw | password_hash('sha512') }}"
    update_password: on_create
- ansible.posix.authorized_key:
    user: jane
    key: "{{ lookup('ansible.builtin.file', 'files/jane.pub') }}"
- ansible.builtin.copy:
    content: "%webdev ALL=(ALL) NOPASSWD: ALL\n"
    dest: /etc/sudoers.d/webdev
    mode: "0440"
    validate: /usr/sbin/visudo -cf %s

Boot and schedule

- ansible.builtin.cron:
    name: Log uptime                   # identifies the entry
    user: devops
    minute: "*/5"
    job: uptime >> /home/devops/uptime.log
- ansible.posix.at:
    command: date > /tmp/at-was-here
    count: 20
    units: minutes
    unique: true
- ansible.builtin.service: { name: httpd, state: started, enabled: true }
- ansible.builtin.file:
    src: /usr/lib/systemd/system/multi-user.target
    dest: /etc/systemd/system/default.target
    state: link
  notify: reboot                       # handler: ansible.builtin.reboot

Storage

- name: LVM with the storage role
  hosts: webservers
  roles:
    - name: redhat.rhel_system_roles.storage
      storage_pools:
        - name: apache-vg
          type: lvm
          disks: [/dev/vdb]
          volumes:
            - name: content-lv
              size: 512m
              mount_point: /var/www
              fs_type: xfs
              state: present
- community.general.parted:
    device: /dev/sdb
    number: 1
    part_end: 1GiB
    flags: [lvm]
    state: present
- community.general.lvg: { vg: apps, pvs: /dev/sdb1 }
- community.general.lvol: { vg: apps, lv: data, size: 500m, resizefs: true }
- community.general.filesystem: { dev: /dev/apps/data, fstype: xfs }
- ansible.posix.mount:
    path: /srv/data
    src: /dev/apps/data
    fstype: xfs
    state: mounted

Network

- ansible.builtin.debug:
    var: ansible_facts['default_ipv4']
- community.general.nmcli:
    conn_name: lab-dummy0
    type: dummy
    ifname: dummy0
    ip4: 192.0.2.10/24
    state: present
- ansible.builtin.hostname: { name: web01.lab.example.com }
- ansible.posix.firewalld:
    service: https
    permanent: true
    immediate: true
    state: enabled

Archives

- name: Contents of /srv/release are packaged
  community.general.archive:
    path: /srv/release/          # trailing slash: contents only
    dest: /tmp/release.tar.gz
    format: gz

- name: Release is restored            # dest must already exist
  ansible.builtin.unarchive:
    src: /tmp/release.tar.gz
    dest: /srv/restored
    remote_src: true                   # archive is on the managed host
    owner: root
    group: root
Update every package on a host?
`ansible.builtin.dnf` with `name: "*"` and `state: latest`.
Install a package group?
`name: "@Group Name"`, quoted.
Which module writes a .repo file?
`ansible.builtin.yum_repository`
Where are installed packages after package_facts?
`ansible_facts['packages']['NAME']`, a list of versions.
Keep a user in their other groups?
`append: true` with `groups:`.
Make a password task idempotent?
`update_password: on_create`, or a fixed salt in `password_hash`.
Safe way to add a sudo rule?
A file in `/etc/sudoers.d/` with `validate: /usr/sbin/visudo -cf %s`.
How does the cron module recognise its job?
By `name`, stored as `#Ansible: NAME` in the crontab.
Set the default boot target?
Link `/etc/systemd/system/default.target` to the target unit.
Grow a logical volume and its file system?
`community.general.lvol` with a bigger `size` and `resizefs: true`.
mount `state: mounted` vs `present`?
mounted: now and in fstab. present: only in fstab.
Where to practise network changes?
On an extra (for example dummy) interface, not the one Ansible uses.
unarchive an archive that is already on the managed host?
Add `remote_src: true`; otherwise `src` is read from the control node.
What does a trailing slash on archive `path` change?
Only the directory's contents are packed, so they extract straight into `dest`.