Ansible Playbook Downloads

General Information

This page will contain Ansible playbook/role downloads.

In order to install/configure Ansible, see this page first.


  • Ansible installed and configured

Playbook Downloads

Example Ansible playbooks/roles are maintained here: https://gitlab.com/whowe/ansible

Playbook Snippets

Snippets of tasks to provide examples of some Ansible modules in action.

Most of these snippets are tasks that span multiple documentation sources or were discovered through searches and trial/error.

Ansible Module Index: https://docs.ansible.com/ansible/2.4/modules_by_category.html

ACL module.


  • Set default group permissions for “awesome” group. (so any files created in the directory will get those group permissions)
    - name: my_description|ACL of MyApp config dir
        path: "/etc/myapp"
        entity: awesome
        etype: group
        default: yes
        permissions: rw
        state: present

Copy module examples.


  • Copy a kernel tuning drop in file and load settings if file changes
    - name: tuning|MyApp kernel tuning
        src: "sysctl_myapp_{{env}}"
        dest: "/etc/sysctl.d/55-myapp.conf"
        owner: root
        group: root
        mode: 0600
      notify: reload sysctl
    # Handler file contents (../handlers/main.yml)
    ##-- Service Reloads --##
    # Sysctl reload
    - name: reload sysctl
      command: sysctl --system
  • Copy autofs config files and restart autofs
    # AutoFS: Config files
    - name: mounts|Copy Master AutoFS Config
        src: "autofs_auto.master"
        dest: "/etc/auto.master.d/master-configs.autofs"
        owner: root
        group: root
        mode: 0644
      notify: restart autofs
    - name: mounts|Copy AutoFS Direct Maps
        src: "autofs_auto.direct-maps"
        dest: "/etc/auto.direct-maps"
        owner: root
        group: root
        mode: 0644
      notify: restart autofs
    # Handler file for autofs (../handlers/main.yml)
    ##-- Service Restarts --##
    # AutoFS Service
    - name: restart autofs
        name: autofs
        state: restarted

Some file module examples.


  • Recursively remove a list of directories
    - name: my_app|Remove MyApp directories
        path: "{{ item }}"
        state: absent
        - "/opt/MyApp/"
        - "/var/log/myapp/"
        - "/usr/local/lib/myapp/"
  • Recursively set ownership to myappdaemon:awesome
    - name: my_description|Ownership of MyApp Log dir
        path: "/var/log/myapp"
        owner: myappdaemon
        group: awesome
        recurse: yes
  • Set ownership of all /data* directories for myappdaemon:awesome
    # Find all /data* directories
    - name: my_description|Info Gather find all Data dirs
        paths: "/"
        patterns: 'data*'
        recurse: no
        file_type: directory
      register: dirs_data
    # Set ownership of all /data* directories
    - name: my_description|Ownership of Data dirs
        path: "{{item.path}}"
        owner: myappdaemon
        group: awesome
        recurse: no
      with_items: "{{dirs_data.files}}"

Using a combination of the command module, registering variables, and the fail module, any command can be checked for a certain return code.

This can be useful for pre-req checks.


  • Ensure a certain mount point exists
    # Info gather for /data1 to see if its a mountpoint
    - name: pre_reqs|Info gather on /data1
      command: mountpoint -q /data1
      register: mount_stat
      failed_when: False
      changed_when: False
    # Exit playbook if /data1 is not a configured mountpoint
    - name: pre_regs|Exit if /data1 is NOT a mountpoint
        msg: "/data1 is not a mountpoint! Exiting."
      when: mount_stat.rc != 0
  • Check for a specific configured network interface
    # Info gather for all ip addresses to ensure storage network is setup
    - name: pre-reqs|Info gather on Storage Network (
      shell: ip address show | grep 172.16.1.
      register: storage_network
      failed_when: False
      changed_when: False
    # Exit playbook if Storage Network interface is not configured
    - name: pre-reqs|Exit if Storage Network ( interface not found
        msg: "Storage Network ( interface not found! Exiting."
      when: storage_network.rc != 0
  • Check for the existence of a certain package, stop service if so
    - name: my_app|Check for myapp RPM
      shell: rpm -q myapp
      register: myapp_rpm_exists
      changed_when: False
      failed_when: False
    # EL7: Stop service if RPM exists
    - name: my_app|Stop service (EL7 if RPM exists)
        name: myapp
        state: stopped
        - myapp_rpm_exists.rc == 0
        - ansible_distribution_major_version == "7"

One method of installing pip into a Python environment.

# Check to see if pip exists, store answer in "pip_path"
- name: software|Check for pip
    path: "/usr/bin/pip"
  register: pip_path
# Copy pip script to system if pip did not exist
- name: software|No Pip - Copy get-pip.py for pip install
    src: "python_get-pip.py"
    dest: "/root/get-pip.py"
  when: pip_path.stat.exists == False
# Install pip into Python site packages if pip did not exist
- name: software|No Pip - Install pip using Python (/usr/bin/python)
  command: "/usr/bin/python /root/get-pip.py"
  when: pip_path.stat.exists == False
# Remove get-pip.py if pip did not exist before
- name: software|No Pip - Remove get-pip.py
    path: "/root/get-pip.py"
    state: absent
  when: pip_path.stat.exists == False

Installing Python packages via pip.

  • Install virtualenv
    # Install virtualenv python package
    - name: software|Install virtualenv python package via pip
        executable: "/usr/bin/pip"
        name: "virtualenv"

Running remote scripts and capturing results.


  • Copy a script to the remote system if it is different. Run the script as the app user and record as changed if the script outputs the string “Modified”.
    # Copy calculation script to system
    - name: script|Copy Calcuation Script to System
        src: "calc-resources.py"
        dest: "/home/{{ app_user }}/bin/calc-resources.py"
        owner: "{{ app_user }}"
        group: "{{ app_group }}"
        mode: 0700
      tags: calc_resources
    # Run calculcation script - Mark as changed if std out contains 'Modified'
    - name: script|Run Resource Calcuation Script
      become: yes
      become_method: su
      become_user: "{{ app_user }}"
        LOCAL_ENV_VAR_NEEDED_IN_SCRIPT: "/home/{{ app_user }}/bin/myapp/"
      command: "/home/{{ app_user }}/bin/calc-resources.py"
      register: resource_calc_result
      changed_when: "'Modified' in resource_calc_result.stdout"
      tags: calc_resources
    # Uncomment debug to see variable contents of 'resource_calc_result'
    - debug:
        var: resource_calc_result
      tags: calc_resources

Manipulating SSH keys on remote hosts.


  • Add a public key to a user's authorized_keys
    - name: ssh-access|Copy a public key to a remote users authorized_keys
        user: "{{ app_user }}"
        state: present
        key: "{{ item }}"
        - "ssh_{{ app_user }}-id-rsa.pub"
  • Generate a SSH Key Pair (public/private) for a user
    - name: ssh-access|SSH Key Generation for App User
        name: "{{ app_user }}"
        generate_ssh_key: yes
        ssh_key_bits: 2048
  • Fetch a remote SSH public key, save to the local Ansible system, then add that now local key to the remote system
    # Fetch remote ssh public key
    - name: ssh-access|Fetching remote ssh public key
        src: "/home/{{ app_user }}/.ssh/id_rsa.pub"
        dest: "/tmp/ansible-ssh-pub/{{ inventory_hostname }}_pubkey"
        flat: yes
    # Add fetched key to authorized_keys
    - name: ssh-access|Add Local SSH Key to authorized_keys
        user: "{{ app_user }}"
        state: present
        key: "{{ lookup('file', '/tmp/ansible-ssh-pub/{{ inventory_hostname }}_pubkey') }}"
  • Add a list of system names to a remote system's SSH known_hosts (so there is no fingerprint accept prompt
    # Check each item to see if its in known_hosts, save results to register variable
    - name: ssh-access|Check to see if host name is in known_hosts
      shell: "ssh-keygen -f /home/{{ app_user }}/.ssh/known_hosts -F {{ item }}"
        - "localhost"
        - ""
        - "{{ ansible_nodename|lower }}"
        - "{{ ansible_hostname|lower }}"
      register: ssh_known_host_results
      changed_when: false
      ignore_errors: yes
    # Uncomment debug to see stored object
    - debug:
        var: ssh_known_host_results
    # If the saved results from above do not contain output, add the host to known_hosts
    - name: ssh-access|Scan public keys (add to known_hosts)
      shell: "ssh-keyscan {{ item.item }} >> /home/{{ app_user }}/.ssh/known_hosts"
      when: item.stdout == ""
      with_items: "{{ ssh_known_host_results.results }}"
    # Ensure known_hosts is owned by app user and group
    - name: ssh-access|Ensure known_hosts is owned by the application user
        path: "/home/{{ app_user }}/.ssh/known_hosts"
        state: file
        owner: "{{ app_user }}"
        group: "{{ app_group }}"
        mode: 0644

Copying tarballs to a remote system only if newer and un-archiving only if the tarball changed.

# Copy myapp tarball if source is newer
- name: my_app|MyApp tarball copy
    src: "myapp_current.tar"
    dest: "/var/opt/myapp/"
    owner: root
    group: root
    mode: 0755
    follow: yes
  register: myapp_new_archive
# Unarchive tarball on remote system if it was changed
- name: my_app|MyApp tarball unarchive if newer
    src: "/var/opt/myapp/myapp_current.tar"
    dest: "/var/opt/myapp/"
    copy: no
    - myapp_new_archive is changed

The user module.


  • Add a list of users to a local group.
    # Local "awesome" group
    - name: my_description|Add users to the local awesome group
        name: "{{item}}"
        groups: awesome
        append: yes
      with_items: "{{awesome_users}}"
    # Variable file (../vars/main.yml)
    # Awesome Group Users
      - yoda
      - vader
      - rjones

Only execute certain tasks under certain conditions.


  • Do not execute any of the imported “mytasks.yml” if host is “server01” or “server02”
    - import_tasks: mytasks.yml
        - inventory_hostname != "server01"
        - inventory_hostname != "server02"
  • Execute a task if a host is in the “special” inventory group
    - import_tasks: mytasks.yml
      when: inventory_hostname in groups.special
  • Execute a task if a host is NOT in the “special” inventory group
    - import_tasks: mytasks.yml
      when: inventory_hostname not in groups.special
  • Execute a task if the distribution major version is 7 (EL 7)
    # Enable and start service (EL7)
    - name: my_service|Enable and Start Service (EL7)
        name: myservice
        enabled: yes
        state: started
        daemon_reload: yes
      when: ansible_distribution_major_version == "7"
  • Execute a task when an inventory group_var variable matches
    - import_tasks: mytasks.yml
      when: env == "prod"

Adding a yum repo with the yum_repository module.


  • Apache Cassandra
    # Apache Cassandra Repo
    - name: cassandra|Add Repo
        name: cassandra
        description: Apache Cassandra
        baseurl: https://www.apache.org/dist/cassandra/redhat/311x/
        enabled: yes
        gpgcheck: yes
        repo_gpgcheck: yes
        gpgkey: https://www.apache.org/dist/cassandra/KEYS

  • linux_wiki/ansible_playbook_downloads.txt
  • Last modified: 2019/06/25 03:41
  • by billdozor