Thursday, January 3, 2019

Ansible Examples

Ansible is an excellent tool for system automation. It’s similar in some ways to Puppet, Chef, and Salt. However, unlike Puppet and Chef, Ansible doesn’t require a local agent to be running on the system being managed. This is an advantage as it saves time and initial configuration (of course, there are reasons that you might want a local agent running…). By the way, the name Ansible comes from the book Rocannon’s World by Ursula K LeGuin.

Ansible uses the idea of playbooks to coordinate activities - a playbook might have several plays and they could be chosen individually or in some combination. Plays contain tasks which contain modules. Roles are another fundamental concept in Ansible and refer to the way a system might be used or configured. Thirdly, there are hosts. So, a playbook like “webservers.yml” would use the “webservers” role to make the “webservers” hosts (the target hosts) into web servers. You might also have a “base” role that you’d want to be applied to the “webservers” first to get them into a basic configuration.

Let’s start with listing out the hosts that we want to manage. Create an ansible directory and cd into it:
mkdir ansible && cd ansible

Create and edit a host file and put in entries like this:

That adds two hosts to our list - localhost and another server at

To make sure that’s right, run this command to list the hosts:
ansible all --list-hosts -i ./hosts #list all hosts using the hosts file

Normally, Ansible likes to use /etc/ansible/hosts as its file, but I’d like to keep it local to the work.

To make sure that everything can communicate correctly, try running this:
ansible all -m ping -i ./hosts #this runs an ad hoc ansible command using the ping module
Output: | SUCCESS => {
       “ansible_facts”: {
                “discovered_interpreter_python”: “/usr/bin/python”
       “changed”: false,
       “ping”: “pong”
and another (uses the default command module):
ansible all -a /bin/date -i ./hosts #this runs a single command rather than a module

By the way, if you haven’t set up your SSH keys and want to use a simple username and password pair, try this:
ansible all -a /bin/date -i ./hosts -u username -k #set username to the username you want to use

When the remote system doesn’t have Python installed, it's useful to use the raw module:
ansible all -m raw -a “ls -l”

One that shows all of the ansible_facts visible by default is:
ansible all -m setup -i ./hosts #loads of info (use as {{ ansible_facts[‘node’] }}

Ansible also has a flag to test the actions without running them: -C. The above example with /bin/date
ansible all -C -a /bin/date -i ./hosts
Instead of connecting to the remote system and showing the date, it produces: | SKIPPED

Let’s update the hosts file to group the host(s).

Test this if you want by running something like this:
ansible cloudserver -m ping -i ./hosts

One-off commands are fun, but the power of ansible comes from the playbooks. Here’s a simple playbook, let’s call it simple_playbook.yml
- name: check ping and date
   hosts: cloudserver
   remote_user: username
            file_value: “Here are the file contents”
      - name: get date
           command: /bin/date

       - name: copy file to remote server using template
         template: src=template/play_file.j2 dest=./play_file.txt

        - name: list files
          shell: ls -l play_file.txt

         - name: start http
           service: name=httpd state=running

Create a local directory called template and add a file to it called play_file.j2. In that file, add a Jinja2 variable placeholder:
{{ file_value }}

Run this playbook:
ansible-playbook simple_playbook.yml -i ./hosts -k #adding the -k option in case SSH keys aren’t set

If you want to check the syntax first, run this:
ansible-playbook simple_playbook.yml -i ./hosts --syntax-check

There’s also a --verbose option that will add much more detail to the output.

That is it; a short set of examples of Ansible.

No comments:

Post a Comment