Ansible Automation on Ubuntu 22.04 – Basic Playbook

Last time we took a look at getting ansible set up and “pinging” (it’s not a network ping, but an SSH login) all the managed nodes, aka inventory. This time let’s run a really basic playbook.

The playbook concept is pretty simple, it’s just a bunch of tasks to complete, written out in a YAML file. Each task is performed via SSH, which is how Ansible does most of its magic. One of Ansible’s shining features is that you don’t need to install an agent, a little thingy that runs on a managed node that waits for commands. Some other automation tools such as Puppet and Chef use the master-agent model, but Ansible does not!


We’re going to a really simple topology as usual to keep thing really simple, as usual. Our lab will consist of only two servers, the Ansible Controller at, and the managed node at

Create inventory

We’re going to skip installation (check the link at the top for installation instructions). First thing is to create an inventory file. The default (for Ubuntu) is at /etc/ansible/hosts, but it might not exist if depending on how you installed (pip installation seems to not set up /etc/ansible). So just pick any directory, and write a hosts file, mine is called hosts looks like this:

      ansible_user: james
      ansible_password: james

We can test the inventory and SSH connection with a ping. Make sure the program sshpass is installed for insecurely specifying the ansible_password like this. In production this would be done with public/private key authentication:

ansible all -i ./hosts -m ping

ubuntu | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    "changed": false,
    "ping": "pong"

This time We’ve specified the hosts file with the option -i. Our inventory is ready to go!

Writing a basic playbook

A playbook, as I said, is just a bunch of tasks to complete. Specifically, they’re in a list called “tasks”. At the top of the playbook file you define a few things before listing tasks to complete, such as what hosts you want to run the tasks on. My YAML file is called hello.yml and looks like this:

- hosts: all
  become: false #don't run as root
  gather_facts: false #I don't need to gather extra variables about my servers
    - name: Write hello world!
      shell: echo "Hello, Ansible world!" >> hello_world.txt
        chdir: /home/james

You might be able to guess what this does, it just writes the string "Hello, Ansible world!" to a text file called hello_world.txt in my home directory of /home/james. The shell Ansible module simply runs commands in a shell on the host. There are some other ways to do this, but this is a nice and simple one.

If we run this playbook from the controller, it will hopefully create a text file on the managed node. Let’s try:

ansible-playbook -i hosts hello.yml 

PLAY [all] *********************************************************************

TASK [Write hello world!] ******************************************************
changed: [ubuntu]

PLAY RECAP *********************************************************************
ubuntu                     : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

If we manually log into the managed node and check, we’ll see our text file!

ls -l

total 4
-rw-rw-r-- 1 james james 22 Sep 30 07:14 hello_world.txt

cat hello_world.txt

Hello, Ansible world!

Thanks for stopping by!

Leave a Reply

Your email address will not be published. Required fields are marked *