Ansible Cheatsheet

Published on Author gryzli

The idea of this post is to make something like a cheatsheet, which I can refer in a future (after I forget almost everything I have learned so far).

So I will try to add the most useful things I’ve found about Ansible.

Short Ansible Tasks Examples

 

Task Example Comment
- name: Enable and start Nginx  
  service: 
   name: nginx  
   state: restarted 
   enabled: yes 

Install nginx with yum 

  • enable it for auto-start
  • start it 
- name: Upload multiple files to /root
  copy: src=files/{{item}} dest="/root/{{item}}" force=yes
  with_items:
        - "file1.conf"
        - "file2.conf"
        - "file3.conf"
Upload multiple files to remote directory
- name: Find matching config files
  shell: "find /usr/local/some_dir/ -type f -name *.cfg"
  register: modify_files

- name: Add line to matching files 
  lineinfile: 
    path: {{item}} 
    line: 'Some new line'
  with_items: "{{modify_files.stdout_lines}}"

Add line to a multiple files matching a find criteria.

While reading the documentation I found there is “with_fileglob”  condition, but it works only for local files.

# vars: 
# Generate random mysql_pass
mysql_pass_random: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') }}"
# Inside task file 
# -------
# Copy the temporary generated password 
- set_fact:
    mysql_pass: "{{ mysql_pass_random }}"

Generate random password with Ansible 

- name: Download file with checksum url (sha256)
  get_url:
    url: http://example.com/path/file.conf
    dest: /etc/foo.conf
    checksum: 'sha256:http://example.com/path/sha256sum.txt'

- name: Download file from a file path
  get_url:
    url: file:///tmp/afile.txt
    dest: /tmp/afilecopy.txt

 

Ansible download file from URL

- name: Synchronize by using additional rsync parameters 
  synchronize:
    src: /some/local_folder
    dest: /some/dest_folder
    rsync_opts:
      - "--no-motd"
      - "--exclude=.git"

Ansible rsync with synchronize module

- name: Recursive chown of multiple root directories 
  file: 
    dest: "/root/{{item}}"
    owner: root 
    group: root 
    recurse: yes
  with_items:
    - dir1
    - dir2
    - dir3     

 

Making recursive file/directory chown/chmod

 

- name: Ensure group "somegroup" exists
  group:
    name: somegroup
    state: present
# Create system user gryzli
- name: Add gryzli user 
  user:
    name: gryzli
    shell: /bin/bash
    groups: developers

 

Create system user/group

 

- name: Run a command as nobody
  command: somecommand
  become: true
  become_method: su
  become_user: nobody
  become_flags: '-s /bin/bash'

 

Execute command with su by different user

 

Ansible Command Line(CLI) Options

There are short list of options, which are very handy to be used as a command line arguments, so I’m going to describe them here.

Ansible – Define playbook variable on command line

You can define (or re-define) playbook variables by using command line options , and the syntax is as follows :

ansible-playbook -e"variable=value" -e"variable1=value2" some_playbook.yml

The good think is that all variables defined by the command line, have the highest priority. So whatever you define by this way is going to be the one seen inside your playbook tasks.

 

Ansible – Doing dry run of a playbook without actual executing it

Doing dry-run executions of a playbook, could be done by using the "--check" option.

Keep in mind that if you have tasks, which depends on previous tasks successfull execution, then most probably  “–check” will fail there ( because no tasks is getting actually executed ) .

 

Ansible – Executing playbook upon limited number of hosts

I have already written about –limit option and limiting task execution on a certain hosts.

Pay attention to the "--list-hosts" command line option, which gives you the ability to just list the hosts upon which the playbook is going to execute, without actually executing anything.

By using "--list-hosts" you could learn the ‘nice way’ if your –limit option does not include the hosts you wanted to.

 

Ansible – Executing only specific tasks in a playbook

This is another topic I have already written about, and could be found here

Pay attention on the examples given for using '--tags' and '--skip-tags' which really really useful command line options.

 

Ansible – Define Execution Host On Command Line / Running ansible-playbook without specifying inventory file /

With ansible-playbook you are able to define the hostname on the fly.

Here is how to do the trick:

# Supply host on the fly (without inventory file) 
# The comma (,) after the host is very important !
ansible-playbook -i some-host.com,  test-playbook.yml 

# Supplying IP 
ansible-playbook -i 192.168.1.2,  test-playbook.yml 

# Supplying SSH port as well 
# If we assume your custom SSH port is '2345'
ansible-playbook -i some-host.com:2345, test-playbook.yml 

 

In the same manner you could specify multiple hosts:

# Supply host on the fly (without inventory file) 
# The comma (,) after the host is very important !
ansible-playbook -i some-host.com,host2-test.com,  test-playbook.yml 

# Supplying IP 
ansible-playbook -i 192.168.1.2,192.168.3.3,   test-playbook.yml 

 

Ansible – Change the parallelism execution level pf a playbook

By default Ansible is configured to use “5” forks, which means it will spawn 5 parallel executing SSH sessions for your tasks. (unless you have changed your default ansible.cfg file).

Executing playbooks/tasks on big number of hosts could become really slow operation with this low parallelism level.

Assuming you don’t want to change your default settings, you could provide command line setting to change the fork level:

# Increasing the fork number to 20 
ansible-playbook -f 20  example-playbook.yml

If you want to change the default setting, you could edit your “~/.ansible.cfg” and modify the following setting:

forks = 20

One more thing you can do for speeding up your playbook (in case you don’t rely on ‘facts’) is to disable the facts gathering.

This could be done by adding the following in your playbook file:

- hosts: all
  gather_facts: no

 

 

 

Ansible-Playbook Tips And Tricks

Making tests in Ansible playbook

Some time you may need to create playbook specifically to run certain tests.

Here are some examples for different types of testing

Test if multiple files exists

If some of the defined files does not exist, the playbook will fail, because of the “failed_when” condition.

- name: Testing playbook
  user: root
  hosts: all
  gather_facts: no
  vars: 
        files_to_check: 
                - /root/file1
                - /root/file2
                - /root/file3
  tasks:
   - name: Check if all files exists 
     stat: 
       path: "{{item}}"
     with_items: "{{files_to_check }}" 
     register: file_check
     failed_when: file_check.stat.exists == False 

 

Test if a given process is running

Another simple test is to check if a given process is running.

This will check if a process with name ‘some-proc’ is in the `ps fax` output and fail if not.

   - name: Check if process some-proc is running
     shell: ps fax
     register: r
     failed_when: "('some-proc' not in r.stdout)"
     changed_when: false 

 

Ansible execute task locally

Executing task locally is pretty easy, you need to do the following

1) Add localhost to your inventory file

vim hosts.inventory

localhost       ansible_connection=local

2) Define your task with delegate_to

- name: Local task
  command: "php local_script.php " 

 

Ansible conditional execution of multiple tasks

You could make conditional execution of a task by using the “when” statement.

Sometimes you may want to execute multiple task conditionally. Adding when to each and every task is not the most optimal way of doing this (even that it will work).

For the purpose you could use block {} , which has the following syntax

- name: Conditional execution of multiple task 
  block:
    - name: Task1
      command:blabla

    - name: Task2
      command:hahaha

    - name: Task3
      command:gagaga

  when: some_variable == true 

Using block: , if your “some_variable” is true, all the defined tasks will get executed.

 

Ansible decode json output and use it as a variable later

Let say you have a script, which returns JSON output and you want to parse it. Not only to parse it , but use the result of the parse as a variable for later use.

This could be done with something like following code:

1) First lets create some simple php script, which returns JSON output

vim json.php

<?php 

$array =array( 
         "var1" => "Value1", 
         "var2" => "Value2", 
 ) ; 

print json_encode($array); 

?>

 

2) Now create the playbook, that will read the output and parse it

vim tester.yml

--- 
# This is the playbook for adding new domains 

- hosts: localhost
  tasks:
          - name: Execute command locally
            delegate_to: localhost 
            command: php json.php 
            register: json_output 

          - set_fact: json_decoded="{{json_output.stdout | from_json }}"

          - debug:
              var: json_decoded

          - name: We have var1 equal to Value1 
            debug: 
              msg: Our var1 is equal to Value1 
            when: json_decoded.var1 == "Value1"

 

Here is the output of executing:

ansible-playbook tester.yml

 

Ansible Ad-Hoc Commands Examples

Ansible ad-hoc commands are useful and effective way for executing command or upload files to group of remote hosts, without the need of writing playbooks.

It is very similar to using “pssh , prsync or pscp” ,but is way more powerful.

 

Uploading directory to a group of hosts

This will upload “directory_for_upload” on all servers defined inside “server_list.txt” to the destination of /root;

 ansible all -i server_list.txt -m copy -a "src=directory_for_upload  dest=/root/ " 

 

Add line to a file

The following ad-hoc command will add the line “some_text” to /root/some_file, for the manually defined host: 192.168.1.1

ansible -i 192.168.1.1, -m lineinfile -a 'dest=/root/some_file line="some_text"'  all 

 

 

Ansible Debugging

Ansible debug print variables to command line 

Ansible debug dump variables to remote file 

 
Debug playbook by running in verbose mode:
ansible-playbook -vvvvv some_playbook.yml

 

Debugging Ansible play-book execution by setting ANSIBLE_DEBUG=1

ANSIBLE_DEBUG=1  ansible-playbook some_playbook.yml

 

 

Ansible Useful Resources

Examples of using Ansible “when” conditional 

Optimizing Ansible Performance

Using Ansible With Older Hosts