Low Orbit Flux Logo 2 F

Ansible - Common Tasks

On this page we are going to be covering common Ansible tasks. These are going to include normal every day Ansible use cases that have already been implemented over and over by many different people. The purpose of this page will be to help prevent you from re-inventing the wheel. It should also give you a boost or head start automating configurations, deployments, and common tasks.

Better descripion:

“Modules should be idempotent, that is, running a module multiple times in a sequence should have the same effect as running it just once.”

Ping



- hosts: webservers
  remote_user: root
  tasks:
    - name: test connection
      ping:
      remote_user: yourname

Command



tasks:
  - name: enable selinux
    command: /sbin/setenforce 1

Shell



tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand || /bin/true

tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True

Script



- name: Run a script with arguments (free form)
  script: script1.sh -a 1234

- name: Run a script with arguments (using 'cmd' parameter)
  script:
    cmd: /opt/app1/script1.sh -a 1234

Raw



- name: Install Python on RHEL / Fedora
  ansible.builtin.raw: dnf install -y python3
      
- name: Install Python on Ubuntu / Debian
  ansible.builtin.raw: apt install -y python3
      
- name: Run a command that uses non-posix shell-isms (in this example /bin/sh doesn't handle redirection and wildcards together but bash does)
  ansible.builtin.raw: cat < /tmp/*txt
  args:
    executable: /bin/bash

File

Make sure file exists and has these permissions / ownership:



- name: Change file ownership, group and permissions
  ansible.builtin.file:
    path: /etc/foo.conf
    owner: foo
    group: foo
    mode: '0644'

More permissions, recursive:



- name: Touch the same file, but add/remove some permissions
  ansible.builtin.file:
    path: /data/set1
    state: directory
    recurse: yes
    mode: u+rw,g-wx,o-rwx

Create dir:



- name: Create a directory if it does not exist
  ansible.builtin.file:
    path: /etc/some_directory
    state: directory
    mode: '0755'

Create a symlink:



- name: Create a symbolic link
  ansible.builtin.file:
    src: /file/to/link/to
    dest: /path/to/symlink
    state: link

Remove a file:



- name: Remove file (delete file)
  ansible.builtin.file:
    path: /etc/foo.txt
    state: absent

Copy



- name: Copy ansible inventory file to client
  copy:
    src=/etc/ansible/hosts
    dest=/etc/ansible/hosts
    owner=root
    group=root
    mode=0644

Synchronize

Setting this option may fix some stange issues but don’t set this if not needed:


betsy eo smith
compress: false

Sync from control host to remote host:



- name: Synchronization of src on the control machine to dest on the remote hosts
  ansible.posix.synchronize:
    src: some/relative/path
    dest: /some/absolute/path

Pull down instead of pushing:



- name: Sync - Pull
  ansible.posix.synchronize:
    src: some/relative/path
    dest: /some/absolute/path
    mode: pull

Delegate to another host:



- name: Sync - Pull
  ansible.posix.synchronize:
    src: some/relative/path
    dest: /some/absolute/path
    mode: pull
  delegate_to: delegate.host

Replace

backup: true make a dated backup of file
before: “regex only replace lines before this
after: “regex only replace lines after this
regexp: “regex replace matching lines
replace: “string” string to replace with



- name: Replace old hostname with new hostname (requires Ansible >= 2.4)
  ansible.builtin.replace:
    path: /etc/hosts
    regexp: '(\s+)old\.host\.name(\s+.*)?$'
    replace: '\1new.host.name\2'

- name: Replace between the expressions (requires Ansible >= 2.4)
  ansible.builtin.replace:
    path: /etc/hosts
    after: '(?m)^<VirtualHost [*]>'
    before: '</VirtualHost>'
    regexp: '^(.+)$'
    replace: '# \1'


Lineinfile

backup: true make a dated backup of file
insertafter: “regex insert after last line that matches this
insertbefore “regex insert before last line that matches this
firstmatch: true modify insertafter/insertbefore to match first line
regexp: “regex replace last line matched, or remove if “state: absent” ( use regex )
search_string: “string” replace last line matched, or remove if “state: absent” ( use literal )
line: “string” the actual string we want
state: absent remove line instead, default is present,



- name: Ensure SELinux is set to enforcing mode
  ansible.builtin.lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: SELINUX=enforcing

- name: Make sure group wheel is not in the sudoers configuration
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    state: absent
    regexp: '^%wheel'

- name: Ensure the default Apache port is 8080
  ansible.builtin.lineinfile:
    path: /etc/httpd/conf/httpd.conf
    regexp: '^Listen '
    insertafter: '^#Listen '
    line: Listen 8080


Blockinfile

backup: true make a dated backup of file
insertafter: “regex insert after last line that matches this ( if no markers are found )
insertbefore “regex insert before last line that matches this ( if no markers are found )
block: “some text “ the acctual block of text
marker_begin: “BEGIN my section” mark begin of block
marker_end: “section END” mark end of block
mark: “# {mark} MY MANAGED BLOCK” marker line template



- name: Insert/Update "Match User" configuration block in /etc/ssh/sshd_config prepending and appending a new line
  ansible.builtin.blockinfile:
    path: /etc/ssh/sshd_config
    append_newline: true
    prepend_newline: true
    block: |
      Match User ansible-agent
      PasswordAuthentication no


- name: Insert/Update eth0 configuration stanza in /etc/network/interfaces
        (it might be better to copy files into /etc/network/interfaces.d/)
  ansible.builtin.blockinfile:
    path: /etc/network/interfaces
    block: |
      iface eth0 inet static
          address 192.0.2.23
          netmask 255.255.255.0


- name: Add mappings to /etc/hosts
  ansible.builtin.blockinfile:
    path: /etc/hosts
    block: |
      {{ item.ip }} {{ item.name }}
    marker: "# {mark} ANSIBLE MANAGED BLOCK {{ item.name }}"
  loop:
    - { name: host1, ip: 10.10.1.10 }
    - { name: host2, ip: 10.10.1.11 }
    - { name: host3, ip: 10.10.1.12 }


Manage Packages with Apt ( Ubuntu / Debian )

Install and remove package:



- name: Update repo cache and install nginx package
  ansible.builtin.apt:
    name: nginx
    update_cache: yes

- name: Remove nginx package
  ansible.builtin.apt:
    name: nginx
    state: absent

Manage Packages with DNF ( RHEL / CentOS / Fedora )

Install and remove package:



- name: Install nginx package
  ansible.builtin.dnf:
    name: nginx

- name: Remove the nginx package
  ansible.builtin.dnf:
    name: nginx
    state: absent

Manage Packages with Pacman ( Arch )

Install and remove package:



- name: Install package nginx
  community.general.pacman:
    name: nginx

- name: Install package nginx
  community.general.pacman:
    name: nginx
    state: absent

Manage Packages with Zypper ( Suse )

Install and remove package:



- name: Install nginx
  community.general.zypper:
    name: nginx

- name: Install nginx
  community.general.zypper:
    name: nginx
    state: absent

systemd Services

Everything on:



- name: Make sure a service is started, enabled, and not masked
  ansible.builtin.systemd_service:
    state: started
    name: nginx
    enabled: true
    masked: no

Everything off:



- name: Make sure a service is stopped, disabled, and masked
  ansible.builtin.systemd_service:
    state: stopped
    name: nginx
    enabled: false
    masked: yes

Bounce:



- name: Bounce
  ansible.builtin.systemd_service:
    state: restarted
    name: nginx

Reload:



- name: Reload
  ansible.builtin.systemd_service:
    state: reloaded
    name: nginx

Manage User Accounts

groups specify groups to be a member of
append: yes append groups instead of just creating
state:absent remove a user
remove: yes remove directories when removing a user
update_password: on_create only update password on initial creation ( default is always )
passwrod: “!” specify a password hash, “!” to disable

Create a user with defaults:



- name: Create a user
  ansible.builtin.user:
    name: jsmith

Specify hash:




- name: Create a user
  ansible.builtin.user:
    name: jsmith
    password: {{ 'mypassword' | password_hash('sha512', 'mysecretsalt') }}


Create a user with multiple different options:



- name: Create a user
  ansible.builtin.user:
    name: jsmith
    uid: 1040
    groups: admins,developers
    append: yes
    shell: /bin/zsh
    generate_ssh_key: yes
    ssh_key_bits: 2048
    ssh_key_file: .ssh/id_rsa

Remove user:



- name: Remove a user
  ansible.builtin.user:
    name: jsmith
    state: absent
    remove: yes

Examples specifying a password:




password: "!"
password: "$6$AQE675JFQhjtR8TD$Kb02EVmU56M3gcydDFkU6crdjtjksoswp8MOLWpyWX5ovlK4qkge69vjRzFpAhKp4rTLV4YsyqOfCmCy7jcom0"
password: {{ 'mypassword' | password_hash('sha512', 'mysecretsalt') }}


Generate a password hash on Linux:



mkpasswd --method=sha-512

Groups

Manage groups like this:



- name: Ensure group "somegroup" exists
  ansible.builtin.group:
    name: somegroup
    state: present

- name: Ensure group "docker" exists with correct gid
  ansible.builtin.group:
    name: docker
    state: present
    gid: 1750

SSH Keys

Managing up SSH keys is easy:




- name: Set authorized key taken from file
  ansible.posix.authorized_key:
    user: charlie
    state: present
    key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}"


Cron Jobs

Cron jobs can be managed like this:



- name: Ensure a job that runs at 2 and 5 exists. Creates an entry like "0 5,2 * * ls -alh > /dev/null"
  ansible.builtin.cron:
    name: "check dirs"
    minute: "0"
    hour: "5,2"
    job: "ls -alh > /dev/null"

- name: 'Ensure an old job is no longer present. Removes any job that is prefixed by "#Ansible: an old job" from the crontab'
  ansible.builtin.cron:
    name: "an old job"
    state: absent