====== Ansible Playbook Downloads ====== **General Information** This page will contain Ansible playbook/role downloads. \\ In order to install/configure Ansible, [[linux_wiki:ansible|see this page first]]. **Checklist** * 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 ---- ===== ACLs ===== ACL module. **Examples** * 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 acl: path: "/etc/myapp" entity: awesome etype: group default: yes permissions: rw state: present ---- ===== Copy Module ===== Copy module examples. **Examples** * Copy a kernel tuning drop in file and load settings if file changes- name: tuning|MyApp kernel tuning copy: 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 copy: 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 copy: 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 service: name: autofs state: restarted ---- ===== File Module ===== Some file module examples. **Examples** * Recursively remove a list of directories- name: my_app|Remove MyApp directories file: path: "{{ item }}" state: absent with_items: - "/opt/MyApp/" - "/var/log/myapp/" - "/usr/local/lib/myapp/" * Recursively set ownership to myappdaemon:awesome- name: my_description|Ownership of MyApp Log dir file: 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 find: paths: "/" patterns: 'data*' recurse: no file_type: directory register: dirs_data # Set ownership of all /data* directories - name: my_description|Ownership of Data dirs file: path: "{{item.path}}" owner: myappdaemon group: awesome recurse: no with_items: "{{dirs_data.files}}" ---- ===== Pre Req Tests ===== 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. **Examples** * 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 fail: 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 (172.16.1.0/24) 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 (172.16.1.0/24) interface not found fail: msg: "Storage Network (172.16.1.0/24) 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) systemd: name: myapp state: stopped when: - myapp_rpm_exists.rc == 0 - ansible_distribution_major_version == "7" ---- ===== Python: Install Pip ===== 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 stat: 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 copy: 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 file: path: "/root/get-pip.py" state: absent when: pip_path.stat.exists == False ---- ===== Python: Install Packages ===== Installing Python packages via pip. * Install virtualenv# Install virtualenv python package - name: software|Install virtualenv python package via pip pip: executable: "/usr/bin/pip" name: "virtualenv" ---- ===== Remote Scripts ===== Running remote scripts and capturing results. **Examples** * 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 copy: 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 }}" environment: 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 ---- ===== SSH Keys ===== Manipulating SSH keys on remote hosts. **Examples** * Add a public key to a user's authorized_keys- name: ssh-access|Copy a public key to a remote users authorized_keys authorized_key: user: "{{ app_user }}" state: present key: "{{ item }}" with_file: - "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 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 fetch: 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 authorized_key: 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 }}" with_items: - "localhost" - "127.0.0.1" - "{{ 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 file: path: "/home/{{ app_user }}/.ssh/known_hosts" state: file owner: "{{ app_user }}" group: "{{ app_group }}" mode: 0644 ---- ===== Unarchive ===== 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 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 unarchive: src: "/var/opt/myapp/myapp_current.tar" dest: "/var/opt/myapp/" copy: no when: - myapp_new_archive is changed ---- ===== User ===== The user module. **Examples** * Add a list of users to a local group.# Local "awesome" group - name: my_description|Add users to the local awesome group user: name: "{{item}}" groups: awesome append: yes with_items: "{{awesome_users}}" # Variable file (../vars/main.yml) # Awesome Group Users awesome_users: - yoda - vader - rjones ---- ===== When Conditional ===== Only execute certain tasks under certain conditions. **Examples** * Do not execute any of the imported "mytasks.yml" if host is "server01" or "server02"- import_tasks: mytasks.yml when: - 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) systemd: 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" ---- ===== Yum Repository ===== Adding a yum repo with the yum_repository module. **Examples** * Apache Cassandra# Apache Cassandra Repo - name: cassandra|Add Repo yum_repository: 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 ----