Getting Started With Ansible: Creating Your First Playbook

ansible automation internet information services nginx playbooks Sep 29, 2023

Introduction:

Imagine you're walking into a job interview or taking on a new role. During the interview, the hiring manager asks, "What sets you apart from the other twenty candidates I've interviewed?" How would you respond? If you've mastered Ansible and efficient automation, your answer might unfold like this:

I bring a unique advantage to the table. Through proficient use of Ansible, I've gained the ability to automate server management tasks. This means I can handle a workload equivalent to efficiently managing 100s of servers. Not only does this streamline operations and increase productivity, but it also significantly reduces the likelihood of human errors. The automation ensures consistent and reliable execution, setting me apart from others relying solely on manual approaches.  I've developed a reliable approach to pinpoint tasks suitable for automation by meticulously recording acivity data, analyzing time allocation, and evaluating repetitive tasks.  

Playbooks are a vital component of Ansible.  They provide a structured way to automate tasks, making it possible to manage complex infrastructures effortlessly.  Configuring dozens or even hundreds of servers manually is time-consuming and error-prone.  In this post, I'll cover the essential parts of a playbook, and we'll end with a demo.

Note:  This post builds on what we covered in the following posts:

What are Ansible Playbooks?

Ansible playbooks are structured YAML files that define a set of tasks or plays to be executed against specified hosts.  Each task consists of specific actions or modules that perform actions on the target hosts.  Playbooks can declare configurations, orchestrate steps of any manually ordered process, and launch tasks synchronously or asynchronously.  Check the additional resources section for examples.

Use Cases:

  • Automate server provisioning and configuration.
  • Managing a fleet of web servers that need Nginix installed.  Instead of connecting to each server manually and running installation commands, you can use a playbook to handle this task automatically.
  • Installing and configuring database servers.  
  • Patching / Updates
  • Deploy applications consistently across multiple environments.
  • Implement security policies across the infrastructure.
  • Configuring network devices.
  • Controlling Amazon Web Services, Microsoft Azure, Google Cloud, and virtual environments.

Benefits of Using Playbooks:

  • Consistency: Playbooks ensure that the same tasks are performed identically on all servers, reducing the risk of human error.
  • Reusability: Once you create a playbook, you can use it repeatedly for similar tasks.
  • Scalability: Ansible scales effortlessly, allowing you to manage a handful of servers or an entire data center.

Flexibility and Customization:

Playbooks are highly customizable.  You can define tasks to install software, configure settings, deploy applications, and more.  Being text base, their easy to store in source control, such as Github, and track changes.

YAML Syntax:

YAML is a human-readable data serialization format. If you're new to YAML don't worry; it's easy to understand.  YAML uses indentation to present data hierarchies, making it clean and intuitive.  I use the Anisble extension in Visual Studio Code to help validate the syntax.  The following playbook is an example that installs Google Chrome on hosts contained within the windowsservers group in the inventory file.

---

- name: "Chocolatey"

  hosts: windowsservers

  tasks:

     - name: Install Google Chrome

       win_chocolatey:

          name: googlechrome

          state: present   

  

Core Components of a Playbook:

The core components of an Ansible playbook are:

Hosts or Inventory:

The hosts section in a playbook specifies the target hosts or group of hosts where the tasks will be executed.  It can be a single host, or group of hosts, or a combination of both.  Ansible inventories define these hosts and their attributes.

Tasks:

The tasks section contains a list of actions or tasks that must be performed on the target hosts.  Each task typically involves invoking an Ansible module to perform a specific action, such as installing a package, copying a file, or managing services.  In our example above, we use the win_chocolatey module to install Google Chrome within the defined task.

Modules:

Modules are standalone scripts that Ansible uses to perform specific actions on the target hosts.  Each task in a playbook typically calls one or more modules to carry out tasks such as package installation, file management, or user administration.

Play:

A play is a set of tasks defined to run against a specific set of hosts.  A playbook can contain one or more plays, allowing you to execute different sets of tasks on different host groups or using different configurations.  In the example below, we're executing two plays, one to configure our web servers and one to configure our database servers.

---
- name: Configure Web Servers
  hosts: web_servers
  tasks:
    - name: Ensure Nginx is installed
      apt:
       name: nginx
       state: present
      become: yes

- name: Configure Database Servers
  hosts: db_servers
  tasks:
    - name: Ensure PostgreSQL is installed
     apt:
      name: postgresql
      state: present
     become: yes

Handlers:

Handlers are similar to tasks but are only executed when modified by other tasks.  Typically used to manage services, handlers ensure that certain actions are triggered only when needed.  For example, restarting a service after a configuration change.

---

- name: Restart Nginx
  systemd:
    name: nginx
    state: restarted
  become: yes

# Task that triggers the handler (this is a comment in YAML)
- name: Configure Nginx
  template:
    src: nginx.conf.j2
   dest: /etc/nginx/nginx.conf
 notify:
   - Restart Nginx

Variables:

Variables are used to store and manage data that can be reused and referenced throughout the playbook.  They allow for flexibility, enabling you to parameterize your playbook and make it more adaptable to different environments, hosts, or specific use cases.  Variables can be set in several ways:

  • Play-level Variables - Variables can be defined at the play level, affecting all tasks within that play.  You'll see an example of this in the playbook_install_IIS.yml playbook below.
  • Task-level Variables - Variables can also be defined at the task level, applying only to a specific task.  
  • Inventory Variables - Variables can be defined in the Ansible inventory file or associated with specific hosts or host groups.  These variables are accessible to all plays and tasks related to those hosts.
  • Command-line Variables - Variables can be passed directly from the command line using the '-e' option.  This is useful for providing dynamic values during playbook execution.
    • ansible-playbook -e "var-name=value" playbook.yml
  • Default Variables - Variables can be defined with a role's 'defaults/main.yml' file.  I'll cover roles in a later post.  Just remember, these variables act as default values and can be overridden when the role is included in a playbook.

Writing Your First Playbook:

The files we'll use can be downloaded from here.

Scenario -  You support a team of developers who must compare their web application performance on Windows, using Internet Information Services, to Nginx on Red Hat Enterprise Linux.  Our goal is to install IIS on two Windows Server 2022 managed nodes and install Nginx on two RHEL managed nodes.  Once installed, we'll copy over a static HTML page and browse to it to ensure both IIS and Nginx are functioning.  Our environment is described below. 

  • SRV1 - Ansible control node 
  • SRV2 - Windows Server 2022 managed node
  • SRV3 - Windows Server 2022 managed node
  • RHEL1 - Red Hat Enterprise Linux managed node

Playbooks - The following playbooks were created to accomplish this task.

Install IIS using playbook_install_IIS.yml.  This playbook also copies the default static site page, index.html, and the ansible_logo.jpg files to the managed node.

Install nginx using playbook_install_nginx.yml.  This playbook also copies the default static site page, index.html, the ansible_log.jpg file, and the nginx config file. In addition, it adds a firewall rule to allow traffic over port 80.

Demo:

Let's jump into the lab environment and see this process in action.

 

Conclusion:

Now that you've built your first playbook, it's time to dive in.  Start small, experiment, and gradually build your automation skills.  What do you plan to automate next?  Comment below.

Happy automating!

Additional Resources:

Whenever you're ready, there is one way I can help you gain hands-on experience: 

Automated Sandbox Fundamentals: I teach how to build a virtual lab using automation in this course. Learn how to create golden images, using both Windows and Linux, to easily spin up and add additional machines to your sandbox.  It's packed with 8 modules and the scripts you'll need to build your environment.  Start small, and scale as needed by easily changing the configuration file included with the course.

Give Me the Details