# Ansible Essentials Workshop

## What You Will Learn

Ansible is capable of handling many powerful automation tasks with the flexibility to adapt to many environments and workflows. With Ansible, users can very quickly get up and running to do real work.

- What is Ansible and The Ansible Way
- Installing Ansible
- How Ansible Works and its Key Components
- Ad-Hoc Commands
- Playbook Basics
- Reuse and Redistribution of Ansible Content with Roles

This deck is designed to provide students with direct introductory instruction and guidance to beginning to automate with Ansible. It is the starting point for students intent on becoming more proficient with Ansible through other Lightbulb modules and their own usage.

This deck supports lecture and hands-on forms of presenting this material.

Allow 2 hours to deliver the lecture-based form and 4 hours for stopping to do the workshop assignments. To access the additional slides for delivering the workshops, navigate down when available.

See the Ansible Lightbulb facilitator’s guide for more details on using this deck and it’s associated material.

## What is Ansible?

It's a simple automation language that can perfectly describe an IT application infrastructure in Ansible Playbooks.

It's an automation engine that runs Ansible Playbooks.

Ansible Tower is an enterprise framework for controlling, securing and managing your Ansible automation with a UI and RESTful API.

Ansible is an automation platform:

- Playbooks make up the automation language
- The code base is the automation engine.
- Ansible Tower manages existing automation

## Ansible Is...

Ansible has a number of qualities that make it the most rapidly growing automation platform in the world.

Ansible is simple. Playbooks are human and machine readable, no special coding skills required – and even people in your IT organization that don’t know Ansible can read an Ansible playbook and understand what’s happening.

This simplicity also means that it’s easy to install and get started to do real work with it quickly – usually in just minutes.

Ansible also works like you think – tasks are always executed in order. All together, the simplicity ensures that you can get started quickly.

Ansible is powerful. Simplicity is great, but to be really useful, you also need the powerful features that ensure you can model even the most complex of IT workflows.

Ansible is complete automation, able to deploy apps, manage orchestration, and configure the infrastructure, networks, operating systems, and services that you’re already using today.

Together, Ansible’s capabilities allow you to orchestrate the entire application and environment lifecycle, regardless of where It's deployed.

Ansible is Agentless. Ansible relies on industry-standard and trusted SSH and WinRM protocols to automate. There are no agents or other software to install, and no additional firewall ports to open. With no need to separately stand up a management infrastructure, Ansible further reduces the activation energy required from your team to start automating today.

In a world where IT complexity stymies even the most basic of IT tasks, Ansible provides a much needed respite – and path forward enabling teams to crush productivity-stealing complexity and overhead.

</aisde>

## The Ansible Way

CROSS PLATFORM – Linux, Windows, UNIX Agentless support for all major OS variants, physical, virtual, cloud and network

HUMAN READABLE – YAML Perfectly describe and document every aspect of your application environment

PERFECT DESCRIPTION OF APPLICATION Every change can be made by playbooks, ensuring everyone is on the same page

VERSION CONTROLLED Playbooks are plain-text. Treat them like code in your existing version control.

DYNAMIC INVENTORIES Capture all the servers 100% of the time, regardless of infrastructure, location, etc.

ORCHESTRATION THAT PLAYS WELL WITH OTHERS – HP SA, Puppet, Jenkins, RHNSS, etc. Homogenize existing environments by leveraging current toolsets and update mechanisms.

## Ansible: The Language of DevOps

COMMUNICATION IS THE KEY TO DEVOPS.

Ansible is the first automation language
that can be read and written across IT.

Ansible is the only automation engine
that can automate the entire application lifecycle
and continuous delivery pipeline.

## Batteries Included

Ansible comes bundled with hundreds of modules for a wide variety of automation tasks

- cloud
- containers
- database
- files
- messaging
- monitoring
- network

- notifications
- packaging
- source control
- system
- testing
- utilities
- web infrastructure

Ansible Modules control the things that you’re automating. They can do everything from acting on system files, installing packages, or making API calls to a service framework. Ansible ships with over 1300 today -- and this number is always expanding with every release.

## Community

THE MOST POPULAR OPEN-SOURCE AUTOMATION COMMUNITY ON GITHUB

- 28,000+ stars & 10,000+ forks on GitHub
- 3200+ GitHub Contributors
- Over 1300 modules shipped with Ansible
- New contributors added every day
- 1200+ users on IRC channel
- Top 10 open source projects in 2017
- World-wide meetups taking place every week
- Ansible Galaxy: over 18,000 subscribers
- 250,000+ downloads a month
- AnsibleFest and Ansible Automates events across the globe

http://ansible.com/community

Ansible is open source. Created with contributions from an active open source community and built for the people who use it every day. At its heart, Ansible was made to help more people experience the power of automation so they could work better and faster together.

## Complete Automation

Ansible is complete automation. It's not just configuration management, It's provisioning infrastructure, deploying applications, and orchestrating actions against all layers of IT infrastructure in a single tool.

Ansible's capabilities allow you to orchestrate the entire application and environment lifecycle, regardless of where It's deployed.

## Use Cases

What can you do with Ansible? Nearly anything. Ansible is the Swiss Army knife of DevOps, capable of handling many powerful automation tasks with the flexibility to adapt to many environments and workflows.

Many folks like to categorize Ansible as a configuration manager, and although yes, Ansible can do that, it"s just the tip of the iceberg. When you couple configuration management with orchestration, you can start to model complicated multi-tier deployments with ease.

With Ansible, once someone on your team automates something, everyone on the team now knows how to do it.

## Installing Ansible

    # the most common and preferred way of
    # installation
    $ sudo pip install ansible

    # you will need the extras repo configured on
    # CentOS, RHEL, or Scientific Linux
    $ sudo yum install ansible

    # you will need the PPA repo configured on
    # Debian or Ubuntu
    $ sudo apt-get install ansible

As open source, Ansible is freely-available thru numerous means and can be installed in minutes with only a few requirements that most system already have. The installation methods listed here are the most commonly used.

Currently Ansible can be run from any machine with Python 2.6 or 2.7 installed. Python 3 support is in tech preview as of version 2.2. Windows isn't supported for the control machine.

The requirements of nodes being managed by Ansible vary based on the type and access used to work with them. Ansible needs a way to communicate, which is normally ssh or winrm though other means such as RESTful APIs and specialized connection types may be necessary. Linux servers will need Python 2.6 or later. Windows serves need PowerShell 3.

For more details see the Installation page in the Ansible documentation.

# Demo Time:
Installing Ansible

To demonstrate how easy it is to install Ansible, open an SSH session to your control host and install Ansible using one of the methods in the previous slide. Once complete do a `$ ansible --version`.

# Workshop:
Installing Ansible

This brief exercise demonstrates how easy it can be to install and configure Ansible and begin automating.

See `workshops/ansible_install` in the Ansible Lightbulb repo for this workshop's assignment. It's solution and addition details can be found in `facilitator/solutions/ansible_install.md`.

## How Ansible Works

The diagram on this slide shows the relationship between all the key components of Ansible starting with the user who writes an Ansible playbook.

## Plays & Playbooks

Playbooks are written in YAML and are used to invoke Ansible modules to perform tasks that are executed sequentially i.e top to bottom. They can describe a policy you want your remote systems to enforce, or a set of steps in a general IT workflow. Playbooks are like an instruction manual and describe the state of environment.

For more details see the Playbook page in the Ansible documentation.

## Modules & Tasks

If playbooks are the instruction manual for setting up and managing your infrastructure, Ansible modules are the tools in your toolkit.

Modules are executable bits of code that operate on hosts; however, we don’t need to understand the underlying implementation to get them to work. Modules do the heavy-lifting in Ansible and abstract users from the complexity of the underlying details.

For more details see the Introduction to Modules and Module Index page in the Ansible documentation.

## Plugins

Continuing our metaphor, plugins are the gears in the engine.

Plugins are pieces of code that extend Ansible’s core functionality. Ansible ships with a number of handy plugins, and you can easily write your own.

These are some of the more common plugin types:

- Action plugins manage the execution on the controller and deployment of modules to hosts.
- Callback plugins enable you to hook into Ansible events for display or logging purposes.
- Connection plugins define how to communicate with inventory hosts.
- Filters plugins allow you to manipulate data inside Ansible plays and/or templates. This is a Jinja2 feature; Ansible ships extra filter plugins.

For more details see the Developing Plugins page in the Ansible documentation.

## Inventory

Your inventory of hosts are your raw material. They are a list of nodes and associated meta data that Ansible can automate.

Inventory lists can be built and stored several different ways, including static files, or can be dynamically-generated from an external source.

You can also specify variables as part of an inventory list. For instance, set a particular host key that’s needed to log into that system remotely. Inventories are ultimately lists of things you want to automate across.

Here in this slide was see an example of a simple static inventory list of three hosts (webserver1, webserver2 and dbserver1) in two groups (web and db).

For more details see the Inventory page in the Ansible documentation.

## Inventory

In large-scale environment subject to constant change, synchronizing and maintaining inventory statically is tedious and error prone endeavor. That is why Ansible includes support of external sources such as public and private cloud providers and configuration management database (CMDB) systems.

For more details see the Dynamic Inventory page in the Ansible documentation.

## Modules

Modules are bits of code transferred to the target system and executed to satisfy the task declaration.

- apt/yum
- copy
- file
- get_url
- git
- ping
- debug

- service
- synchronize
- template
- uri
- user
- wait_for
- assert

If playbooks are the instruction manual for setting up and managing your infrastructure, Ansible modules are the tools in your toolkit.

We've already discussed, Ansible modules. They are the “batteries” and the “tools in a users toolkit.”

While there are hundreds of modules at your disposal out-of-the-box these are the most common ones.

Playbook tasks and how they relate to modules will be covered ahead. Tasks are the application of a module to perform a specific unit of work.

## Modules Documentation

http://docs.ansible.com/

A categorized index of included Ansible modules along with detailed documentation for the requirements, parameters and return values of each Ansible module can be found on the Ansible documentation site.

## Modules Documentation

    # List out all modules installed
    $ ansible-doc -l
    ...
    copy
    cron
    ...

    # Read documentation for installed module
    $ ansible-doc copy
    > COPY

      The [copy] module copies a file on the local box to remote locations. Use the [fetch] module to copy files from remote locations to the local
      box. If you need variable interpolation in copied files, use the [template] module.

      * note: This module has a corresponding action plugin.

    Options (= is mandatory):
    ...

Module documentation is also available from the commandline using the `ansible-doc`.

One noteworthy advantage, of ansible-doc is that it can display any custom module with it's own embedded documentation that you may have added to your Ansible environment.

## Modules: Run Commands

If Ansible doesn't have a module that suits your needs there are the “run command” modules:

- command: Takes the command and executes it on the host. The most secure and predictable.
- shell: Executes through a shell like `/bin/sh` so you can use pipes etc. Be careful.
- script: Runs a local script on a remote node after transferring it.
- raw: Executes a command without going through the Ansible module subsystem.

NOTE: Unlike standard modules, run commands have no concept of desired state and should only be used as a last resort.

"Run commands" are what we collectively call these modules that enable users to do command-line operations in different ways. They’re a great catch all mechanism for getting things done, but they should be used sparingly and as a last resort. The reasons are many and varied.

The overuse of run commands is common amongst those just becoming familiar with Ansible for automating their work. They use `shell` to fire off a bash command they already know without stopping to look at the Ansible docs. That works well enough initially, but it undermines the value of automating with Ansible and sets things up for problems down the road. As a best practice, always check the hundreds of Ansible shipping modules for what you need and use those first and run commands as a last resort.

NOTE: `shell` allows for IO redirection such as pipes. This is why It's best practice to use `command` unless they need to pipe something. It also best practice to never pass user input or variables thru a run command.

## Inventory

Inventory is a collection of hosts (nodes) with associated data and groupings that Ansible can connect and manage.

- Hosts (nodes)
- Groups
- Inventory-specific data (variables)
- Static or dynamic sources

We've already discussed inventory in our review of Ansible's key components.

Inventory consists of hosts, groups, inventory specific data. Inventory can either be static or dynamic.

Inventory is a collection of the hosts (nodes) with associated metadata and groupings that Ansible can connect and manage. An inventory source can be static files or dynamically retrieved from an external system.

You can specify a different inventory file using the `-i <path>` option on the command-line or your Ansible configuration file.

## Static Inventory Example

    10.42.0.2
    10.42.0.6
    10.42.0.7
    10.42.0.8
    10.42.0.100
    host.example.com

Static inventory is the easiest source to get started with. This example shows a static inventory source in It’s simplest form – a single file with a list of IP addresses or hostnames.

NOTE: Ansible infers a localhost is present even if it is not explicitly listed. This is why you can actually run Ansible without a inventory source. Ansible will only be able to operate on the localhost where it is being run.

## Static Inventory Example

    [control]
    control ansible_host=10.42.0.2

    [web]
    node-[1:3] ansible_host=10.42.0.[6:8]

    [haproxy]
    haproxy ansible_host=10.42.0.100

    [all:vars]
    ansible_user=vagrant
    ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key

The example shown here is a more practical and common example of a static inventory file.

Static inventory files are expressed in INI format. The headings in brackets are group names, which are used in classifying systems and deciding what systems you are controlling at what times and for what purpose. Hosts can belong to multiple groups and groups can be members of other groups. (The latter is not shown here.)

NOTE: This example contains variables, a topic we haven't touched on just yet. We'll go into them on the next slide.

Other noteworthy attributes in our example:

- `ansible_host` is an example of a host variable.
- Hosts can be assigned arbitrary human-meaningful names or aliases such as "control" and "haproxy". Ansible will instead use the value of `ansible_host` (one of several "magic" inventory variables) as the network address to connect.
- Static inventory files can support character ranges such as "node-[1:3]"
- Like localhost, Ansible infers an "all" group is present. As its name implies, all inventory hosts are members of this group.
- The heading "all:vars" is an example of group variable assignment using two more "magic" variables, `ansible_ssh_private_key_file` and `ansible_user`.

This example just covers the basics. There's a lot more to inventory that is not covered here. See the Ansible inventory documentation for more details.

## Ad-Hoc Commands

An ad-hoc command is a single Ansible task to perform quickly, but don’t want to save for later.

Ansible ad-hoc commands is a good place to start to understand the basics of what Ansible can do before learning how to use playbooks – ad-hoc commands can also be used to do quick things that you might not necessarily want to write a full playbook for.

Generally speaking, the true power of Ansible lies in playbooks. So why would you use ad-hoc tasks versus playbooks?

For instance, if you wanted to restart a service on all of your lab nodes, you could execute a quick one-liner in Ansible without writing a playbook.

## Ad-Hoc Commands: Common Options

- -m MODULE_NAME, --module-name=MODULE_NAME
  Module name to execute the ad-hoc command
- -a MODULE_ARGS, --args=MODULE_ARGS
  Module arguments for the ad-hoc command
- -b, --become
  Run ad-hoc command with elevated rights such as sudo, the default method
- -e EXTRA_VARS, --extra-vars=EXTRA_VARS
  Set additional variables as key=value or YAML/JSON
- --version
  Display the version of Ansible
- --help
  Display the MAN page for the Ansible tool

This slide shows essential command-line options for running ad-hoc commands that will be useful in our upcoming workshop assignment.

## Ad-Hoc Commands

    # check all my inventory hosts are ready to be
    # managed by Ansible
    $ ansible all -m ping

    # collect and display the discovered facts
    # for the localhost
    $ ansible localhost -m setup

    # run the uptime command on all hosts in the
    # web group
    $ ansible web -m command -a "uptime"

Ad-hoc commands are quick checks on your servers that you don’t want to preserve in an Ansible playbook.

An ad-hoc command can be used to do some tasks that you might not necessarily want to write a full playbook and save for later.

This is a good place to start to understand the basics of what Ansible can do prior to learning about playbooks where the true power of Ansible automation lies.

For more information see Introduction To Ad-Hoc Commands.

## Sidebar: Discovered Facts

Facts are bits of information derived from examining a host systems that are stored as variables for later use in a play.

    $ ansible localhost -m setup
    localhost | success >> {
      "ansible_facts": {
          "ansible_default_ipv4": {
              "address": "192.168.1.37",
              "alias": "wlan0",
              "gateway": "192.168.1.1",
              "interface": "wlan0",
              "macaddress": "c4:85:08:3b:a9:16",
              "mtu": 1500,
              "netmask": "255.255.255.0",
              "network": "192.168.1.0",
              "type": "ether"
          },

The second ad-hoc command example from the prior slide provides the following JSON output of a localhost facts run.

Facts are bits of information derived from examining a host systems that are stored as variables for later use. An example of this might be the IP address of the host, or what operating system it is running. The facts Ansible will discover about a host is extensive. What's shown here is just a small sample. Run `ansible localhost -m setup` for a more complete representation.

Ansible collects facts using the `setup` module. By default, Ansible will run the `setup` module before any other tasks are executed in a playbook. These facts can be referenced by subsequent automation tasks on a per host-basis during the playbook run.

# Demo Time:
Ad-Hoc Commands

To demonstrate ad-hoc commands in action, open an SSH session to your control host and run the ad-hoc commands in the previous slides.

    $ ansible all -m ping
    $ ansible localhost -m setup
    $ ansible web -m command -a "uptime"

# Workshop:
Ad-Hoc Commands

This brief exercise demonstrates Ansible in-action at it's most basic and simple level. Thru ad-hoc commands, students are exposed to Ansible modules and usage and will apply to their understanding of tasks and playbooks. This exercise also begins to expose students to the concepts of Ansible facts and inventory.

This workshop is also a good way to verify their lab environments are properly configured before going forward.

See `workshops/adhoc_commands` in the Ansible Lightbulb repo.

## Variables

Ansible can work with metadata from various sources and manage their context in the form of variables.

- Command line parameters
- Plays and tasks
- Files
- Inventory
- Discovered facts
- Roles

While automation exists to make it easier to make things repeatable, all of your systems are not exactly alike.

Variables are used to store metadata for each host drawing from numerous sources. For example variable may be for things like facts or file paths or package versions.

## Variable Precedence

The order in which the same variable from different sources will override each other.

1. extra vars
2. task vars (only for the task)
3. block vars (only for tasks in block)
4. role and include vars
5. play vars_files
6. play vars_prompt
7. play vars
8. set_facts

9. registered vars
10. host facts
11. playbook host_vars
12. playbook group_vars
13. inventory host_vars
14. inventory group_vars
15. inventory vars
16. role defaults

If variables of the same name are defined in multiple sources, they get overwritten in a certain and specific order. This is why this variable precedence is important to understand.

There are 16 levels of variable precedence as of Ansible 2.x. The `extra_vars` (passed thru the command-line) always take precedence vs. role defaults which will always get overridden by any other source. The previous inventory example defines vars at 13 and 14 (highlighted in the list) in the variable precedence chain.

It's a good idea to limit the different sources where a specific variable is being set. While Ansible's variable precedence handling is comprehensive and well-defined, it can laborious to keep the resolution of multiple sources straight.

NOTE: The inventory variables sources showed in the static inventory example a couple of slides back are in bold type.

## Tasks

Tasks are the application of a module to perform a specific unit of work.

- file: A directory should exist
- yum: A package should be installed
- service: A service should be running
- template: Render a configuration file from a template
- get_url: Fetch an archive file from a URL
- git: Clone a source code repository

We've already reviewed modules, the batteries and tools Ansible provides. Tasks are the specific application of a module to perform a unit of automation.

Here we see a list of examples of common modules being applied to do something.

## Example Tasks in a Play

    tasks:
    - name: Ensure httpd package is present
      yum:
        name: httpd
        state: latest

    - name: Ensure latest index.html file is present
      copy:
        src: files/index.html
        dest: /var/www/html/

    - name: Restart httpd
      service:
        name: httpd
        state: restarted

This example shows the task list of an Ansible playbook.

1. The first task assures the latest nginx package is installed using yum.
2. The next uses the copy module to assure the latest version of a static home page file has been published.
3. The last task restarts the nginx service with the service module

## Handler Tasks

Handlers are special tasks that run at the end of a play if notified by another task when a change occurs.

> If a package gets installed or updated, notify a service restart task that it needs to run.

Normal tasks run sequentially; handler tasks run on notification of a change and will only run once at the end of a play.

For more information see Handler Tasks.

## Example Handler Task in a Play

    tasks:
    - name: Ensure httpd package is present
      yum:
        name: httpd
        state: latest
      notify: restart httpd

    - name: Ensure latest index.html file is present
      copy:
        src: files/index.html
        dest: /var/www/html/

    handlers:
    - name: Restart httpd
      service:
        name: httpd
        state: restarted

Here is our previous example with a few slight modifications that have been highlighted.

In this version of our example, we add a `notify` keyword to the first task to trigger a handler task if it returns "changed" as being true. The third tasks now is under a "handlers" section that signifies that the handler task will run on notification at the end of the play of change occurs during the first task.

## Plays & Playbooks

Plays are ordered sets of tasks to execute against host selections from your inventory. A playbook is a file containing one or more plays.

Playbooks are text files that contain one or more plays that are expressed in YAML. A play defines target hosts and a task list that are executed sequentially (i.e top to bottom) to achieve a certain state on those hosts.

For more details see the Playbook page in the Ansible documentation.

## Playbook Example

    ---
    - name: Ensure apache is installed and started
      hosts: web
      become: yes
      vars:
        http_port: 80

      tasks:
      - name: Ensure httpd package is present
        yum:
          name: httpd
          state: latest

      - name: Ensure latest index.html file is present
        copy:
          src: files/index.html
          dest: /var/www/html/

      - name: Ensure httpd is started
        service:
          name: httpd
          state: started

Here we can see an example of a simple but complete Ansible play. The slides that follow will explore each of these parts and what they do.

## Human-Meaningful Naming

     ---
     - name: install and start apache
       hosts: web
       become: yes
       vars:
         http_port: 80

       tasks:
       - name: httpd package is present
         yum:
           name: httpd
           state: latest

       - name: latest index.html file is present
         copy:
           src: files/index.html
           dest: /var/www/html/

       - name: httpd is started
         service:
            name: httpd
            state: started

Every play and each task in it can be assigned a name that describes its objective in the automation workflow and is output during execution.

It's best practice to always name your plays and tasks. Adding name with a human-meaningful description better communicates the intent to users when running a play.

## Host Selector

    ---
    - name: Ensure apache is installed and started
      hosts: web
      become: yes
      vars:
        http_port: 80

      tasks:
      - name: Ensure httpd package is present
        yum:
          name: httpd
          state: latest

      - name: Ensure latest index.html file is present
        copy:
          src: files/index.html
          dest: /var/www/html/

      - name: Ensure httpd is started
        service:
          name: httpd
          state: started

The Ansible play host selector defines which nodes in the inventory the automation is targeting.

In this example, a single group of "web" is being targeted. Ansible supports targeting intersections, unions and filters of multiple groups or hosts though.

For more details see the host selector Patterns page in the Ansible documentation.

## Privilege Escalation

    ---
    - name: Ensure apache is installed and started
      hosts: web
      become: yes
      vars:
        http_port: 80

      tasks:
      - name: Ensure httpd package is present
        yum:
          name: httpd
          state: latest

      - name: Ensure latest index.html file is present
        copy:
          src: files/index.html
          dest: /var/www/html/

      - name: Ensure httpd is started
        service:
          name: httpd
          state: started

Ansible allows you to "become" another user or with elevated rights to execute a task or an entire play (shown above). This is done using existing privilege escalation tools, which you probably already use or have configured, like sudo (the default), su, pfexec, doas, pbrun, dzdo, ksu and others.

For more details see the Privilege Escalation page in the Ansible documentation.

## Play Variables

    ---
    - name: Ensure apache is installed and started
      hosts: web
      become: yes
      vars:
        http_port: 80

      tasks:
      - name: Ensure httpd package is present
        yum:
          name: httpd
          state: latest

      - name: Ensure latest index.html file is present
        copy:
          src: files/index.html
          dest: /var/www/html/

      - name: Ensure httpd is started
        service:
          name: httpd
          state: started

Variables are used to store metadata for each host drawing from numerous sources. Here we see another one of those sources, a variable "http_port" that has been embedded in a play.

Recalling the previous variable precedence slide, play variables are number 7 in Ansible's the precedence chain.

## Tasks

    ---
    - name: Ensure apache is installed and started
      hosts: web
      become: yes
      vars:
        http_port: 80

      tasks:
      - name: Ensure latest httpd package is present
        yum:
          name: httpd
          state: latest

      - name: Ensure latest index.html file is present
        copy:
          src: files/index.html
          dest: /var/www/html/

      - name: Ensure httpd is started
        service:
          name: httpd
          state: started

Here we see modules, such as yum, being applied to a to perform a unit of automation such as to assure the latest httpd package is present on a host.

# Demo Time:
A Simple Playbook Run

To demonstrate how an Ansible, open an SSH session to your control host and run the playbook in `examples/apache-simple-playbook`. That example playbook is essentially the same one we just examined.

Don't forget to reverse what this playbook does before continuing to not interfere with later demos and workshops.

# Workshop:
Your First Playbook

This assignment provides a quick introduction to playbook structure to give them a feel for how Ansible works, but in practice is too simplistic to be useful.

See `workshops/simple_playbook` in the Ansible Lightbulb repo.

Note: If your time is limited, this is a workshop you can skip. We'll cover this and more topics in the next workshop.

## Doing More with Playbooks

Here are some more essential playbook features that you can apply:

- Templates
- Loops
- Conditionals
- Tags
- Blocks

We only have covered the most essential capabilities of what can be done with a playbook so far.

Here we list a few more though this is still far from all there is. There's many other powerful playbook features for handling less common though vital automation workflows. No need to learn everything at once. You can start small and pick up more features over time as you need them.

## Templates

Ansible embeds the Jinja2 templating engine that can be used to dynamically:

- Set and modify play variables
- Conditional logic
- Generate files such as configurations from variables

Templates are a vital feature provided by the Jinja2 template engine, a powerful piece of software independent of Ansible. Ansible makes this usage as seamless and transparent as possible. Most will not realize they are doing templating when they develop plays with Ansible.

We don't show any specific template examples at the moment because we'll have plenty of opportunity to see templates in action as we cover other topics.

In all actuality, what is covered here only touches upon a few of its most basic features. To go deeper see these docs:

- Jinja2 Template Designer Documentation
- Ansible Jinja2 Filters
- Ansible Jinja2 Tests

## Loops

Loops can do one task on multiple things, such as create a lot of users, install a lot of packages, or repeat a polling step until a certain result is reached.

    - yum:
        name: "{{ item }}"
        state: latest
      with_items:
      - httpd
      - mod_wsgi

This example demonstrates a basic loop with `with_items`. The loop sets a variable called "item", a template variable courtesy of the embedded Jinja2 template engine, with the list value that is in context.

There are many different and specialized types of task loops to work with. See the Loops documentation to go deeper.

## Conditionals

Ansible supports the conditional execution of a task based on the run-time evaluation of variable, fact, or previous task result.

    - yum:
        name: httpd
        state: latest
      when: ansible_os_family == "RedHat"

Conditionals are another instance of Jinja2 in action within Ansible plays themselves. In the provided example "ansible_os_family" is a fact variable Ansible will set.

There are other forms of conditional clauses, but `when` is usually all that is needed.

NOTE: Conditional clauses are considered to be raw Jinja2 expression without double curly braces.

## Tags

Tags are useful to be able to run a subset of a playbook on-demand.

    - yum:
        name: "{{ item }}"
        state: latest
      with_items:
      - httpd
      - mod_wsgi
      tags:
         - packages

     - template:
         src: templates/httpd.conf.j2
         dest: /etc/httpd/conf/httpd.conf
      tags:
         - configuration

In the provided example, if the playbook were run with `--tags "packages"` the yum task would execute and the template task would be skipped. If the playbook were run with `--tags "configuration"` the opposite would happen. Without a `--tags` both tasks would execute like normal.

Tags can be seen as a simple though specialized form of conditional statement designed to enable the execution of a subset tasks. Tags are a bit more than simple boolean flags though. To dig deeper see the playbook Tags documentation.

## Blocks

Blocks cut down on repetitive task directives, allow for logical grouping of tasks and even in play error handling.

    - block:
      - yum:
          name: "{{ item }}"
          state: latest
        with_items:
        - httpd
        - mod_wsgi

      - template:
          src: templates/httpd.conf.j2
          dest: /etc/httpd/conf/httpd.conf
      when: ansible_os_family == "RedHat"

In the provided example we use a block to group two tasks that are to be conditional executed if a host is running a Red Hat family linux using one conditional clause. In practice, we could have copied the `when` clause onto each task and gotten same result. Using a block, there is less clutter thereby less to maintain and nothing to keep in sync. The utility of using a block increases the more tasks and clauses are in use.

Blocks have a play in error handling and automating roll backs that we won't get into here given the scope of that topic.

See the documentation on blocks to dig deeper.

# Demo Time:
A More Practical Playbook

The simple playbook we examined gave us a sense of the structure of a playbook and how they work, but in reality was too simplistic to be practical. Here we look at a basic playbook that it more complete to what users will commonly do with Ansible.

Walk thru the site.yml playbook in `examples/apache-basic-playbook` and note the added logic and its function. Then, run the playbook on the control host.

Don't forget to reverse what this playbook does before continuing to not interfere with later demos and workshops.

# Workshop:
Practical Playbook Development

In this workshop assignment students are tasked with developing their first complete playbook. The assignment approximates the tasks they will typical need to take in order to deploy and configure a single application service using Nginx.

See `workshops/basic_playbook/` in the Ansible Lightbulb repo.

Tip: Don't rush this workshop. Give students ample time to do this workshop themselves to completion. This workshop covers the essential concepts and features of effectively automation with Ansible and builds up their core skills for further exploration.

## Roles

Roles are a packages of closely related Ansible content that can be shared more easily than plays alone.

- Improves readability and maintainability of complex plays
- Eases sharing, reuse and standardization of automation processes
- Enables Ansible content to exist independently of playbooks, projects -- even organizations
- Provides functional conveniences such as file path resolution and default values

Roles are closely related Ansible content that are organized into a pre-defined directory structure, making them easier to reuse and share among groups.

## Project with Embedded Roles Example

    site.yml
    roles/
       common/
         files/
         templates/
         tasks/
         handlers/
         vars/
         defaults/
         meta/
       apache/
         files/
         templates/
         tasks/
         handlers/
         vars/
         defaults/
         meta/

This slide shows an example file system with a top-level playbook (site.yml) and two sample roles (common and apache) embedded in the project. Notice how the file structure under each role are similar to what we find in a play. Role deconstruct the content we'd put in a play and package it up in such a way that it is portable and easily shared and reused.

## Project with Embedded Roles Example

    # site.yml
    ---
    - name: Execute common and apache role
      hosts: web
      roles:
         - common
         - apache

This slide shows the site.yml playbook using the roles in our example project. Notice that it is much more concise than what we've seen.

## Ansible Galaxy

http://galaxy.ansible.com

Ansible Galaxy is a hub for finding, reusing and sharing Ansible content.

Jump-start your automation project with content contributed and reviewed by the Ansible community.

Ansible Galaxy refers to the Galaxy website, a hub for finding, downloading, and sharing community developed roles. Downloading roles from Galaxy is a great way to jump-start your automation projects.

Galaxy also refers to a command line tool, `ansible-galaxy`, for installing, creating and managing roles from the Galaxy website or directly from a git based SCM. You can also use it to create a new role, remove roles, or perform tasks on the Galaxy website.

# Demo Time:
A Playbook Using Roles

Walk thru the site.yml playbook and the contents of `roles/apache` in `examples/apache-role`. Note how the tasks, variables and handlers from the basic Ansible playbook we've been examined and have been refactored into a role.

Run the playbook on the control host. Notice anything different? Other than a few subtle display changes, you shouldn't. What's important is how roles let you better organize, share and reuse Ansible content that will be vital as the scope and sophistication of your automation accelerates.

# Workshop:
Your First Roles

Here students are tasked with refactoring their previous work from the Practical Playbook workshop into a role and modifying their playbook accordingly. We intentionally avoid introducing any new tasks or functionality otherwise. The objective here is to focus students specifically on how roles are structured and develop.

You should emphasize the value of roles in better organizing playbooks as they grow in sophistication and making Ansible automation more portable and reusable than a basic playbook.

See `workshops/roles` in the Ansible Lightbulb repo.

## Next Steps

- It's easy to get started
  ansible.com/get-started
- Join the Ansible community
  ansible.com/community
- Would you like to learn a lot more?
  redhat.com/en/services/training/do407-automation-ansible