====== 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
----