---
title: How to Create Your First Ansible Playbook
description: Learn how to create your first Ansible playbook, including a simple Hello World example, and understand the basics of YAML and Ansible commands.
image: https://blog.rheinwerk-computing.com/hubfs/How%20to%20Create%20Your%20First%20Ansible%20Playbook.jpg
---

[![Rheinwerk Computing Logo](https://blog.rheinwerk-computing.com/hubfs/computing_logo-header.svg)](https://blog.rheinwerk-computing.com/) [Blog](https://blog.rheinwerk-computing.com)

- Books 
    - Get an overview of our wide selection of books on every relevant computing topic. 
          - [General Computing](https://www.sap-press.com/rheinwerk-computing/general-computing/)
          - [DevOps](https://www.sap-press.com/rheinwerk-computing/devops/)
          - [Programming Languages](https://www.sap-press.com/rheinwerk-computing/programming-languages/)
          - [Security](https://www.sap-press.com/rheinwerk-computing/security/)
          - [Software Development](https://www.sap-press.com/rheinwerk-computing/software-development/)
- Book Subscription 
    - Get unlimited access to all Rheinwerk Computing books! 
          - [Programming Subscription](https://sap-press.com/subscriptions/)

[DevOps](https://blog.rheinwerk-computing.com/tag/devops)

# How to Create Your First Ansible Playbook

![Rheinwerk Computing](https://blog.rheinwerk-computing.com/hubfs/RW-logo-300x300.png)  by [Rheinwerk Computing](https://blog.rheinwerk-computing.com/author/rheinwerk-computing)

*Playbooks* are the entry points for any Ansible project.

 

In the simplest case, they contain an ordered set of individual steps (*tasks*) that describe how to achieve the desired configuration of the target hosts.

Although Ansible is not a programming language in the strictest sense, we want to follow the good-old tradition and create a “Hello World” playbook as our first official act. Playbooks are written in YAML, and they conventionally have the.yml or .yaml file extension. The playbook below is pretty much the simplest one possible:

 

`---`

`- hosts: localhost`

 

`tasks:`

`     - debug: msg="Hello Ansible!"`

To ensure that your project folder isn’t cluttered over time, I suggest that you create a *playbooks/* folder for playbooks as follows:

 

`$ cd ~/ansible/projects/start`

`$ mkdir playbooks`

 

Then, you should store the playbook file in this new folder.

 

Before we start the whole thing, we’ll explain the content:

- The three dashes are a known YAML marker that indicates the beginning of the document. Many Ansible users omit them, and that’s not a problem since having multiple YAML documents in one file is not possible with Ansible anyway. For completeness, Ansible uses the Python PyYAML module as a parser, which currently implements YAML version 1.1.
- The hosts keyword specifies the target hosts to address. You can use any pattern instead of localhost, and very often, you’ll see the group name all to address all inventory hosts.

You can also provide a list of patterns, like this one:

`- hosts:`

`   - debian`

`    - rocky`

 

Or you can provide a list of patterns in the compact YAML list form:

 

`- hosts: [debian, rocky]`

 

Or you can even provide a list of patterns as one Ansible pattern string:

 

`- hosts: debian, rocky`

- The tasks keyword indicates that the subsequent steps transform the target hosts into the desired state.
- The call to the debug module is currently our only task; the msg parameter provides the desired output.

At first glance, it might not be entirely clear to you why the playbook begins with a list. (Technically speaking in YAML, the content of our playbook is a list with a single element!) The explanation is that a playbook can consist of several so-called *plays*, each of which consists of a set of hosts to which certain tasks are assigned. However, you will not need playbooks with more than one play until much later.

 

To start the whole thing (at last), you use the ansible-playbook command and pass the path to the playbook as a parameter. If your current working directory is the root folder of your project, then it looks like this:

 

`$ ansible-playbook playbooks/hello-ansible.yml`

 

`PLAY [localhost] ************************************************************`

 

`TASK [Gathering Facts] ******************************************************`

`ok: [localhost]`

`TASK [debug] ****************************************************************`

`ok: [localhost] => {`

`   "msg": "Hello Ansible!"`

`}`

 

`PLAY RECAP ******************************************************************`

`localhost :    ok=2  changed=0  unreachable=0  failed=0`

`       skipped=0  rescued=0  ignored=0`

 

The output requires some clarification:

- The output begins with PLAY and the list of the corresponding target systems (in our example, this is only localhost). You can also provide a name: attribute to a play, and the value of this attribute would be displayed here. However, if the playbook contains only a single play, then you’d typically skip providing a name: attribute.
- The tasks follow with a brief description and a corresponding result.
- We didn’t request the Gathering Facts task, but it is Ansible’s default behavior to gather information about the involved target systems at the beginning of a play. In most real playbooks, you need these facts, but in our simple example, you could save some time by specifying gather\_ facts: no or gather\_facts: false to skip this step, as follows:

`- hosts: localhost`

`gather_facts: no`

- The last line provides a summary report: in the localhost target system, two tasks were completed with the desired (successful) result (as indicated by ok=2), there were no changes (changed=0), the target system was reachable (unreachable=0), and no tasks failed (failed=0). For now, you can ignore the skipped, rescued, and ignored fields.

## Relative Paths in Playbook Calls

In our chosen directory structure, you must live with the minor inconvenience of having to make all calls from the root folder of the project, as follows:

 

`$ ansible-playbook playbooks/hello-ansible.yml`

 

You must do this unless you use the *direnv* software or a similar clever method that gives you more flexibility. From now on, I will omit the *playbooks/* path component in the examples to spare you this redundancy:

 

`$ ansible-playbook hello-ansible.yml`

 

## Addressing the Actual Target Hosts

The fact is that localhost is not a common target for administrative tasks, so let’s address all the actual targets in the test lab:

 

`---`

`- hosts: all`

 

`   tasks:`

`       - debug: msg="Hello Ansible!"`

And to make things a bit more exciting, you can shut down a machine (e.g., suse) beforehand (by using vagrant halt suse in the *vagrant/* folder). The result will be something like this:

 

`$ ansible-playbook hello-all.yml`

 

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

 

`TASK [Gathering Facts] ******************************************************`

`ok: [rocky]`

`ok: [debian]`

`ok: [ubuntu]`

`fatal: [suse]: UNREACHABLE! => {"changed": false, "msg":`

`"Failed to connect to the host via ssh: ssh: connect to host suse port 22:`

`Connection timed out”: "unreachable": true}`

 

`TASK [debug] ****************************************************************`

`ok: [debian] => {`

`   "msg": "Hello Ansible!"`

`}`

`ok: [rocky] => {`

`   "msg": "Hello Ansible!"`

`}`

`ok: [ubuntu] => {`

`   "msg": "Hello Ansible!"`

`}`

 

`PLAY RECAP ******************************************************************`

`debian :  ok=2   changed=0   unreachable=0   failed=0`

`rocky :   ok=2   changed=0   unreachable=0   failed=0`

`suse :    ok=0   changed=0   unreachable=1   failed=0`

`ubuntu :  ok=2   changed=0   unreachable=0   failed=0`

 

First, you’ll notice that there seems to be no fixed order of target systems per task. Due to parallel processing, the order is indeed quite random.

 

You should also note that suse was completely out of the game after its inaccessibility was determined, as the second task did not even attempt to contact this host.

 

Finally, the concluding statistics should not pose any puzzles here either. (I have abbreviated the output slightly to save space.) If you have followed the example in the lab, then remember to let the powered-off machine participate again (by using vagrant up suse).

 

Editor’s note: This post has been adapted from a section of the book *[Ansible: The Practical Guide for Administrators and DevOps Teams](https://www.sap-press.com/ansible_6068/?utm_source=sappressblog&utm_medium=referral&utm_campaign=Blogs&utm_term=2702_chapter2&utm_content=2702) *by Axel Miesen. Axel is an Ansible coach. His interest in Linux systems began with his studies at the University of Kaiserslautern, where he studied mathematics and computer science. After graduating in 1998, he began working as a consultant and trainer and has passed on his Linux knowledge and experience to numerous professionals.

This post was originally published 10/2025.

## Recommendation

[![Ansible](https://blog.rheinwerk-computing.com/hs-fs/hubfs/social-suggested-images/2702-1-2.jpg?width=170&name=2702-1-2.jpg)](https://www.sap-press.com/ansible_6068/?utm_source=sappressblog&utm_medium=referral&utm_campaign=Blogs&utm_term=2702_chapter5&utm_content=2702)

**Ansible**

If you want to keep your servers in order, Ansible is the tool of choice! In this practical guide, you’ll learn how to use Ansible to automate server configuration, software deployment, and more. Start by installing Ansible and setting up your initial inventory management process. Then, follow step-by-step instructions for system orchestration, from the basics of playbooks and tasks to using Ansible with Docker. With expert tips and best practices for testing, debugging, and more, this is your all-in-one guide to automating with Ansible!

[Learn More](https://www.sap-press.com/ansible_6068/?utm_source=sappressblog&utm_medium=referral&utm_campaign=Blogs&utm_term=2702_chapter5&utm_content=2702)

![Rheinwerk Computing](https://blog.rheinwerk-computing.com/hubfs/RW-logo-300x300.png)

**by [Rheinwerk Computing](https://blog.rheinwerk-computing.com/author/rheinwerk-computing)**

Rheinwerk Computing is an imprint of Rheinwerk Publishing and publishes books by leading experts in the fields of programming, administration, security, analytics, and more.

[DevOps](https://blog.rheinwerk-computing.com/tag/devops)

[![Share on facebook](https://7528309.fs1.hubspotusercontent-na1.net/hub/7528309/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/facebook-color.png?width=24&name=facebook-color.png)](https://www.facebook.com/share.php?u=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fhow-to-create-your-first-ansible-playbook%3Futm_medium%3Dsocial%26utm_source%3Dfacebook) [![Share on linkedin](https://7528302.fs1.hubspotusercontent-na1.net/hub/7528302/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/linkedin-color.png?width=24&name=linkedin-color.png)](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fhow-to-create-your-first-ansible-playbook%3Futm_medium%3Dsocial%26utm_source%3Dlinkedin) [![Share on twitter](https://7528304.fs1.hubspotusercontent-na1.net/hub/7528304/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/twitter-color.png?width=24&name=twitter-color.png)](https://twitter.com/intent/tweet?original_referer=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fhow-to-create-your-first-ansible-playbook%3Futm_medium%3Dsocial%26utm_source%3Dtwitter&url=https%3A%2F%2Fblog.rheinwerk-computing.com%2Fhow-to-create-your-first-ansible-playbook%3Futm_medium%3Dsocial%26utm_source%3Dtwitter&source=tweetbutton&text=) [![Share on email](https://7528311.fs1.hubspotusercontent-na1.net/hub/7528311/hubfs/raw_assets/public/mV0_d-web-default-modules_hubspot/img/email-color.png?width=24&name=email-color.png)](mailto:?subject=Check+out+https%3A%2F%2Fblog.rheinwerk-computing.com%2Fhow-to-create-your-first-ansible-playbook%3Futm_medium%3Dsocial%26utm_source%3Demail&body=Check+out+https%3A%2F%2Fblog.rheinwerk-computing.com%2Fhow-to-create-your-first-ansible-playbook%3Futm_medium%3Dsocial%26utm_source%3Demail)

### Comments

### Latest Blog Posts

[![What Are Registered Variables in Ansible?](https://blog.rheinwerk-computing.com/hs-fs/hubfs/What%20Are%20Registered%20Variables%20in%20Ansible_.jpg?height=600&name=What%20Are%20Registered%20Variables%20in%20Ansible_.jpg)](https://blog.rheinwerk-computing.com/what-are-registered-variables-in-ansible)

[DevOps](https://blog.rheinwerk-computing.com/tag/devops)

## [What Are Registered Variables in Ansible?](https://blog.rheinwerk-computing.com/what-are-registered-variables-in-ansible)

[Read More](https://blog.rheinwerk-computing.com/what-are-registered-variables-in-ansible)

[![How to Configure Ansible](https://blog.rheinwerk-computing.com/hs-fs/hubfs/How%20to%20Configure%20Ansible.jpg?height=600&name=How%20to%20Configure%20Ansible.jpg)](https://blog.rheinwerk-computing.com/how-to-configure-ansible)

[DevOps](https://blog.rheinwerk-computing.com/tag/devops)

## [How to Configure Ansible](https://blog.rheinwerk-computing.com/how-to-configure-ansible)

[Read More](https://blog.rheinwerk-computing.com/how-to-configure-ansible)

**Subscribe to our blog!**Get notified about future blog updates.

- <https://www.linkedin.com/showcase/rheinwerk-computing/>
- <https://www.youtube.com/channel/UChj-U-uWGM7qRlHXSFU93ew>
- <https://blog.rheinwerk-computing.com/rss.xml>

### The official Rheinwerk Computing Blog

Rheinwerk Computing is an imprint of Rheinwerk Publishing and publishes resources that will help you accelerate your computing journey. The Rheinwerk Computing Blog is designed to provide helpful, actionable information on a variety of topics, including programming, administration, security, and analytics!

### Blog Topics

- [All Topics](https://blog.rheinwerk-computing.com)
- [Programming Languages](https://blog.rheinwerk-computing.com/tag/programming-languages)
- [How To](https://blog.rheinwerk-computing.com/tag/how-to)
- [JavaScript](https://blog.rheinwerk-computing.com/tag/javascript)
- [DevOps](https://blog.rheinwerk-computing.com/tag/devops)
- [Web Development](https://blog.rheinwerk-computing.com/tag/web-development)
- [Python](https://blog.rheinwerk-computing.com/tag/python)
- [What Is?](https://blog.rheinwerk-computing.com/tag/what-is)
- [Cybersecurity](https://blog.rheinwerk-computing.com/tag/cybersecurity)
- [Software Development](https://blog.rheinwerk-computing.com/tag/software-development)
- [Featured](https://blog.rheinwerk-computing.com/tag/featured)

### Blog curated by

[![Rheinwerk Computing Logo](https://blog.rheinwerk-computing.com/hubfs/computing_logo-header.svg)](https://www.sap-press.com/rheinwerk-computing/) [Visit Rheinwerk Computing Store](https://www.sap-press.com/rheinwerk-computing/)

### About

- [Home](https://sap-press.com/)
- [About Us](https://sap-press.com/the-publisher/)
- [Contact](mailto:info@rheinwerk-publishing.com)
- [Legal Notes](https://sap-press.com/legal-notes/)
- [Privacy Policy](https://sap-press.com/privacy/)
- [Terms of Use](https://sap-press.com/terms/)

© 2026 Rheinwerk Publishing, Inc. | Change Privacy Options

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Rheinwerk Computing",
    "url" : "https://blog.rheinwerk-computing.com/author/rheinwerk-computing"
  },
  "dateModified" : "2025-12-17T13:56:03.984Z",
  "datePublished" : "2025-10-15T13:00:02.000Z",
  "headline" : "How to Create Your First Ansible Playbook",
  "image" : [ "https://blog.rheinwerk-computing.com/hubfs/How%20to%20Create%20Your%20First%20Ansible%20Playbook.jpg" ],
  "mainEntityOfPage" : {
    "@id" : "https://blog.rheinwerk-computing.com/how-to-create-your-first-ansible-playbook",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://blog.rheinwerk-computing.com/hubfs/Logo-1.jpg"
    },
    "name" : "Rheinwerk Publishing, Inc."
  }
}
```