Ansible Cheat Sheet
CONDITIONALS
y file to n
VARIABLES
include global variables for all Roles
sample playbook
splunk/
setup_splunk_playbook.yaml
roles/base
/tasks/main.yaml
/tasks/install.yaml
search_head
/tasks/configure.yaml
indexer
/tasks/configure.yaml
some_other_role
/tasks/some_task.yaml
hosts
config.yaml
Place your vars into config.yaml
cat splunk/config.yaml
--- # global Splunk variables splunk_version: 7.0.0
in your playbook, include the Roles
cat setup_splunk_playbook.yaml
- hosts: "search_heads"
become_user: root
become: true
gather_facts: true
roles:
- base
- search_head
in your Role, include the Global Vars inside a Task
cat roles/base/tasks/main.yaml
--- # install Splunk Base
- name: include vars
include_vars: "{{ playbook_dir }}/config.yaml"
- include: install.yaml
vars are accessible in tasks now,
cat roles/base/tasks/install.yaml
- name: echo version
debug: splunk version is {{ splunk_version }}
Loop through a Dict variable inside a playbook
cluster:
members:
splunk01: 10.123.1.0
splunk02: 10.123.1.1
splunk03: 10.123.1.2
in the playbook,
- debug: msg="{{ cluster.members.values() | map('regex_replace', '(.*)', 'https://\\1:8089') | join(',') }}"
>> https://10.123,1.0:8089, https://10.123.1.1:8089, etc etc
Use Inventory file variables inside a playbook
cat hosts
[apache]
nycweb01
playbook
debug: msg="IP: {{ hostvars[groups['apache'][0]]['ansible_default_ipv4']['address'] }}"
debug: msg="Hostname: {{ hostvars[groups['apache'][0]]['inventory_hostname'] }}"
register a List/Array to be used for later,
- name: parse all hostnames in group WebServer and get their IPs, place them in a list
command: echo {{ hostvars[item]['ansible_ssh_host'] }}"
with_items: "{{ groups['webserver'] }}"
register: ip_list
- name: show the IPs
debug: msg={{ ip_list.results | map(attribute='item') | list }}"
export an Environment variable
- name: yum install
yum: name=somepkg state=present
environment:
SOME_VAR: abc
Variables inside Inventory Hosts file
cat hosts
[web]
nycweb01.company.local
[web:vars]
role="super duper web server"
now get the "role" variable inside the playbook,
- hosts: web
gather_facts: true
tasks:
- name: print Role var
debug: msg={{ role }}
// super duper web server
MODULES
service: name=httpd state=[started, stopped, restarted, reloaded] enabled=[yes,no]
user: name=joe state=[present,absent] uid=1001 groups=wheel shell=/bin/bash
group: name=splunk gid=6600 state=[present,absent] system=[yes/no]
yum: name=apache state=[present, latest, absent, removed]
file: path=/etc/file state=[file, link, directory, hard, touch, absent] group=x owner=x recurse=yes
JOBS AND PROCESS CONTROL
run Ansible ad hoc with 10 parallel forks
ansible -i hosts testnode1 -a "uname -a" -f 10
show human readable output
add this line to ansible.cfg
stdout_callback=yaml
SERVER DIAGNOSTICS
Test Connection
ansible -i hosts all -m ping -u root
Diagnostics
manage nodes via "/etc/ansible/hosts" file
Debug (debug output for playbook)
- debug: var=result verbosity=2
PACKAGES AND INSTALLATION
install multiple packages
yum: name="{{ item }}" state=present
with_items:
- http
- htop
- myapp
SSH Setup
Copy your Ansible Master's public key to the managed node
ssh-keygen ## generate public key
ssh-copy-id <name of node> # copy key, provide password to node
configure Hosts file
/etc/ansible/hosts
[production]
prod1.prod.local
prod2.prod.local
[dev]
devweb1.dev.local
devweb2.dev.local
REMOTE CMD (Ad Hoc)
Ping specific node
ansible -i hosts nycweb01.prod.local -m ping
Ping with wildcard
ansible -i hosts "nycweb*" -m ping
Ping all nodes with SSH user 'root'
ansible -i hosts all -m ping -u root
run a command
ansible -i hosts dev -a 'uname -a'
check Yum packages
ansible -i hosts dev -m yum
check if Docker rpm is installed
ansible -i hosts web01.nyc.local -m shell -a "rpm -qa | grep docker"
Get facts about a box
ansible -i hosts web01.nyc.local -m setup -a 'filter=facter_*'
run command with sudo
ansible -i hosts target-host -m shell -a "cat /etc/sudoers" --sudo
limit command to a certain group or server: add --limit *.nyc
GALAXY
install Role (Module)
ansible-galaxy install geerlingguy.nginx
PLAYBOOKS
run playbook with sudo
ansible-playbook -v config-users.yaml --sudo --sudo-user=joe --ask-sudo-pass
use different Hosts file
ansible-playbook -v -i /path/to/hosts
run playbook but only a specific task (tag)
ansible-playbook playbooks/restore_bitbucket.yaml -i hosts --tags rsync
or to skip: (--skip-tags tag1, tag2)
store output of a command as a variable
shell: cat /etc/network | grep eth0
register: address
debug: msg="address is {{ address.stdout }}"
configure multiple items with one task
- name: more complex items to add several users
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
groups: "{{ item.groups }}"
state: present
with_items:
- { name: testuser1, uid: 1002, groups: "wheel, staff" }
- { name: testuser2, uid: 1003, groups: staff }
get path location of current Playbook (pwd)
{{ playbook_dir }}
Set playbook to be verbose by default - hosts: blah strategy: debug
run playbook with verbose traceback
ansible-playbook -i hosts myPlaybook.yaml -vvv
run playbook on multiple Host groups
- hosts: "search_head, deployer"
Run playbook locally on host
hosts: 127.0.0.1
connection: local
Prompt for password during Playbook run
# Playbook to change user password
- name: pw change
hosts: target
become: true
become_user: root
vars_prompt:
- name: username
prompt: "enter username for which to change the pw"
- name: password
prompt: "enter new password"
private: yes
tasks:
- name: change pw
user: "name={{ username }} password={{ password }} update_password=always"
run playbook with "dry run" / NOOP / simulate
ansible-playbook foo.yml --check
Run task on different target,
- name: run something on some other server
debug: msg="running stuff"
delegate_to: someserver
Delegate task to a host group
- name: restart web servers
service: name=memcached state=restarted
delegate_to: "{{ item }}"
with_items: "{{ groups['webservers'] }}"
Get IP or facter of a remote host
- name: get IP
debug: msg="{{ hostvars['nycweb01']['ansible_default_ipv4']['address'] }}"
or
debug: msg="{{ hostvars[item]['ansible_ssh_host'] }}"
with_items: "{{ groups['webservers'] }}"
synchronize file (copy file from Ansible host to target)
- synchronize:
src: "{{ playbook_dir }}/files/vscode.repo"
dest: /etc/yum.repos.d/
synchronize from server A to server B with a wildcard
- name: copy Splunk Apps
synchronize:
src: "/opt/splunk/etc/apps/{{ item }}" (server A)
dest: "/opt/splunk/etc/shcluster/apps/" (server B)
with_items:
- item1
- item2
delegate_to: server A
wget a file to a location
- get_url:
url: 'https://dl.google.com/go/go1.10.linux-amd64.tar.gz'
dest: '/tmp'
force: no # dont download if file already exists
untar tar.gz
USER AND GROUP MGMT
change user password for user Joe (user Fred running the cmd as sudo on the target box)
# 1 install passlib
pip install passlib
#2 update the pw, using a hash
ansible targethost -s -m user -a "name=joe update_password=always password={{ 'MyNewPassword' | password_hash('sha512') }}" -u fred --ask-sudo-pass
copy public ssh key to remote authorized_keys file
- hosts: targetHost
tasks:
- name: update nessus SSH keys
become_user: root
become_method: sudo
become: true
authorized_key:
user: nessus
key: "{{ lookup('pipe','cat ../files/ssh_keys/nessus.pub') }}"
state: present
FILES & DIRS
delete all files and hidden files in a directory
vars:
app_home: /var/opt/application
tasks:
- name: clear home dir
- shell: "ls -la {{ app_home }}/"
register: files_to_delete
- file: path="{{ app_home }}/{{ item }}" state=absent
with_items: "{{ files_to_delete.stdout_lines }}"
get files from node
ansible node1 -s -m fetch -a "src=/etc/hosts dest=/tmp"
copy file to node
ansible node1 -m copy -a "src=/etc/hosts dest=/tmp/hosts"
remove all files matching a wildcard
file: path={{ item }} state=absent
with_fileglob: /tmp/*.rpm
FACTER
get all facts from a node (ad hoc)
ansible -i hosts targetName -m setup -a "filter="facter_*"
use fact in a playbook
include fact as {{ ansible_factname }}
add fact to Hosts file
[group]
host1 admin_user=jane
host2 admin_user=jack
host3
[group:vars]
admin_user=john
get default IPV4 address
ansible_default_ipv4.address
Local facts
place .fact file into /etc/ansible/facts.d on target node
vim /etc/ansible/facts.d/fruits.fact
[fruits]
sweet=banana, apple, grapes
bitter=grapefruit
get Local facts
ansible -i hosts mrx -m setup -a "filter=ansible_local"