• Notifications
  • Fork

/lightbulb

Permalink
Switch branches/tags
Nothing to show
Find file
1139 lines (1090 sloc) 62.6 KB
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Ansible Essentials Workshop</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/css/reveal.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/css/print/pdf.css' : 'https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<link rel="stylesheet" href="css/theme/ansible.css">
<!-- Theme used for syntax highlighting of code -->
<!--link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/lib/css/zenburn.css"-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/themes/prism.min.css">
</head>
<body>
<div class="ans-mark">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-449 450 125 125" style="enable-background:new -449 450 125 125;" xml:space="preserve">
<g id="XMLID_3_">
<circle id="XMLID_7_" class="circle" cx="-386.5" cy="512.5" r="62"/>
<path id="XMLID_4_" class="a-mark" d="M-356.9,537.1l-24.7-59.4c-0.7-1.7-2.1-2.6-3.9-2.6c-1.7,0-3.2,0.9-4,2.6l-27.1,65.2h9.2 l10.7-26.9l32,25.9c1.3,1,2.2,1.5,3.4,1.5c2.4,0,4.6-1.8,4.6-4.5C-356.5,538.5-356.6,537.8-356.9,537.1z M-385.4,488.4l16.1,39.6 l-24.2-19L-385.4,488.4z"/>
</g>
</svg>
</div>
<div class="reveal">
<div class="slides">
<section data-state="cover">
<p class="ans-logo"><img src="images/ansible-wordmark-white.svg" width="260" alt="" /></p>
<h1>Ansible Essentials Workshop</h1>
<!--p>NAME HERE, TITLE HERE</p>
<p>COMPANY HERE</p-->
</section>
<section>
<h2>What You Will Learn</h2>
<p>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.<br><br></p>
<ul>
<li>What is Ansible and The Ansible Way</li>
<li>Installing Ansible</li>
<li>How Ansible Works and its Key Components</li>
<li>Ad-Hoc Commands</li>
<li>Playbook Basics</li>
<li>Reuse and Redistribution of Ansible Content with Roles</li>
</ul>
<aside class="notes">
<p>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.</p>
<p>This deck supports lecture and hands-on forms of presenting this material. </p>
<p>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. </p>
<p>See the <a href="../facilitator/README.md">Ansible Lighttbulb facilitator&rsquo;s guide</a> for more details on using this deck and it&rsquo;s associated material.</p>
</aside>
</section>
<section>
<h2>What is Ansible?</h2>
<p>It&apos;s a <b>simple automation language</b> that can perfectly describe an IT application infrastructure in Ansible Playbooks.</p>
<p>It&apos;s an <b>automation engine</b> that runs Ansible Playbooks.</p>
<p>Ansible Tower is an <b>enterprise framework</b> for controlling, securing and managing your Ansible automation with a <b>UI and RESTful API</b>.</p>
<aside class="notes speaker">
<p>Ansible is an automation platform:
<ul>
<li>Playbooks make up the automation language</li>
<li>The code base is the automation engine.</li>
<li>Ansible Tower manages existing automation</li>
</ul>
</p>
</aside>
</section>
<section>
<h2>Ansible Is...</h2>
<img src="images/simple-powerful-agentless-diagram.svg" />
<aside class="notes">
<p>Ansible has a number of qualities that make it the most rapidly growing automation platform in the world. </p>
<p><strong>Ansible is simple.</strong> Playbooks are human and machine readable, no special coding skills required &ndash; and even people in your IT organization that don’t know Ansible can read an Ansible playbook and understand what’s happening.</p>
<p>This simplicity also means that it&rsquo;s easy to install and get startedto do real work with it quickly &ndash; usually in just minutes. </p>
<p>Ansible also works like you think &ndash; tasks are always executed in order. All together, the simplicity ensures that you can get started quickly.</p>
<p><strong>Ansible is powerful.</strong> 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.</p>
<p>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. </p>
<p>Together, Ansible’s capabilities allow you to orchestrate the entire application and environment lifecycle, regardless of where It&apos;s deployed.</p>
<p><strong>Ansible is Agentless.</strong> 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.</p>
<p>In a world where IT complexity stymies even the most basic of IT tasks, Ansible provides a much needed respite &ndash; and path forward enabling teams to crush productivity-stealing complexity and overhead.</p>
</aisde>
</section>
<section>
<h2>The Ansible Way</h2>
<div style="font-size: 0.75em;"><br>
<p><strong>CROSS PLATFORM</strong> – Linux, Windows, UNIX</br>
Agentless support for all major OS variants, physical, virtual, cloud and network</p>
<p><strong>HUMAN READABLE</strong> – YAML</br>
Perfectly describe and document every aspect of your application environment</p>
<p><strong>PERFECT DESCRIPTION OF APPLICATION</strong></br>
Every change can be made by playbooks, ensuring everyone is on the same page</p>
<p><strong>VERSION CONTROLLED</strong></br>
Playbooks are plain-text. Treat them like code in your existing version control.</p>
<p><strong>DYNAMIC INVENTORIES</strong></br>
Capture all the servers 100% of the time, regardless of infrastructure, location, etc.</p>
<p><strong>ORCHESTRATION THAT PLAYS WELL WITH OTHERS</strong> – HP SA, Puppet, Jenkins, RHNSS, etc. Homogenize existing environments by leveraging current toolsets and update mechanisms.</p>
</div>
<aside class="notes">
</aside>
</section>
<section>
<h2>Ansible: The Language of DevOps</h2>
<div style="font-size: 0.75em; text-align:center;">
<img src="images/devops-language-diagram.svg" width="60%" height="60%" style="padding-top: 20px;"/>
<p class="fullwidth"><strong>COMMUNICATION IS THE KEY TO DEVOPS.</strong></p>
<p class="fullwidth">Ansible is the first <strong>automation language</strong><br/>that can be read and written across IT.</p>
<p class="fullwidth">Ansible is the only <strong>automation engine</strong><br/>that can automate the entire <strong>application lifecycle</strong><br/>and <strong>continuous delivery pipeline</strong>.</p>
</div>
<aside class="notes">
</aside>
</section>
<section>
<h2>Batteries Included</h2>
<p>Ansible comes bundled with hundreds of modules for a wide variety of automation tasks</p>
<div class="columns">
<div class="col">
<ul>
<li>cloud</li>
<li>containers</li>
<li>database</li>
<li>files</li>
<li>messaging</li>
<li>monitoring</li>
<li>network</li>
</ul>
</div>
<div class="col">
<ul>
<li>notifications</li>
<li>packaging</li>
<li>source control</li>
<li>system</li>
<li>testing</li>
<li>utilities</li>
<li>web infrastructure</li>
</ul>
</div>
<div class="col">
</div>
</div>
<aside notes="notes">
<p>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 900 today -- and this number is always expanding with every release.</p>
</aside>
</section>
<section>
<h2>Community</h2>
<div style="font-size: 0.75em;">
<p><strong>THE MOST POPULAR OPEN-SOURCE AUTOMATION COMMUNITY ON GITHUB<br><br></strong></p>
<div class="columns">
<div class="col">
<ul>
<li>13,000+ stars &amp; 4,000+ forks on GitHub</li>
<li>2000+ GitHub Contributors</li>
<li>Over 900 modules shipped with Ansible</li>
<li>New contributors added every day</li>
<li>1200+ users on IRC channel</li>
<li>Top 10 open source projects in 2014</li>
<li>World-wide meetups taking place every week</li>
<li>Ansible Galaxy: over 18,000 subscribers</li>
<li>250,000+ downloads a month</li>
<li>AnsibleFests in NYC, SF, London</li>
</ul>
<p>http://ansible.com/community</p>
</div>
<div class="col">
<img src="images/ansibe-up-and-running-ebook.png"/>
</div>
</div>
</div>
<aside class="notes">
<p>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.</p>
</aside>
</section>
<section>
<h2>Complete Automation</h2>
<img src="images/ansible-automation-diagram.svg"/>
<aside class="notes">
<p>Ansible is complete automation. It&apos;s not just configuration management, It&apos;s provisioning infrastructure, deploying applications, and orchestrating actions against all layers of IT infrastructure in a single tool.</p>
<p>Ansibles capabilities allow you to orchestrate the entire application and environment lifecycle, regardless of where It&apos;s deployed.</p>
</aside>
</section>
<section>
<h2>Use Cases</h2>
<img src="images/ansible-use-case-diagram.svg" />
<aside class="notes">
<p>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.</p>
<p>Many folks like to categorize Ansible as a configuration manager, and although yes, Ansible can do that, it&quot;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.</p>
<p>With Ansible, once soneone on your team automates something, everyone on the team now knows how to do it.</p>
</aside>
</section>
<section>
<h2>Installing Ansible</h2>
<pre class="language-yaml"><code>
# 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
</code></pre>
<aside class="notes">
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>For more details see <a href="http://docs.ansible.com/ansible/intro_installation.html">the Installation page</a> in the Ansible documenation.
</aside>
</section>
<section>
<section data-state="title alt">
<h1>Demo Time: <br/>Installing Ansible</h1>
<aside class="notes">
<p>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 <code>$ ansible --version</code>.</p>
</aside>
</section>
<section data-state="title alt">
<h1>Workshop: <br/>Installing Ansible</h1>
<aside class="notes">
<p>This brief exercise demonstrates how easy it can be to install and configure ansible and begin automating.</p>
<p>See <code>workshops/ansible_install</code> in the Ansible Lightbulb repo for this workshop&apos;s assignment. It's solution and addition details can be found in <code>facilitator/solutions/ansible_install.md</code>.</p>
</aside>
</section>
</section>
<section>
<h2>How Ansible Works</h2>
<img src="images/how-ansible-works-diagram-01.svg" />
<aside class="notes">
<p>The diagram on this slide shows the relationship between all the key components of Ansible starting with the user who writes an Ansible playbook.</p>
</aside>
</section>
<section>
<h2>Plays &amp; Playbooks</h2>
<img src="images/how-ansible-works-diagram-02.svg" />
<aside class="notes">
<p>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.</p>
<p>For more details see <a href="http://docs.ansible.com/ansible/playbooks.html">the Playbook page</a> in the Ansible documenation.</p>
</aside>
</section>
<section>
<h2>Modules &amp; Tasks</h2>
<img src="images/how-ansible-works-diagram-03.svg" />
<aside class="notes">
<p>If playbooks are the instruction manual for setting up and managing your infrastructure, Ansible modules are the tools in your toolkit.</p>
<p>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.</p>
<p>For more details see the <a href="http://docs.ansible.com/ansible/modules_intro.html">Introduction to Modules</a> and <a href="http://docs.ansible.com/ansible/modules_by_category.html">Module Index</a> page in the Ansible documentation.</p>
</aside>
</section>
<section>
<h2>Plugins</h2>
<img src="images/how-ansible-works-diagram-04.svg" />
<aside class="notes">
<p>Continuing our metaphor, plugins are the gears in the engine.</p>
<p>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.</p>
<p>These are some of the more common plugin types:</p>
<ul>
<li>Action plugins manage the execution on the controller and deployment of modules to hosts.</li>
<li>Callback plugins enable you to hook into Ansible events for display or logging purposes.</li>
<li>Connection plugins define how to communicate with inventory hosts.</li>
<li>Filters plugins allow you to manipulate data inside Ansible plays and/or templates. This is a Jinja2 feature; Ansible ships extra filter plugins.</li>
</ul>
<p>For more details see the <a href="http://docs.ansible.com/ansible/dev_guide/developing_plugins.html">Developing Plugins</a> page in the Ansible documentation.</p>
</aside>
</section>
<section>
<h2>Inventory</h2>
<img src="images/how-ansible-works-diagram-05.svg" />
<aside class="notes">
<p>Your inventory of hosts are your raw material. They are a list of nodes and associated meta data that Ansible can automate.</p>
<p>Inventory lists can be built and stored several different ways, including static files, or can be dynamically-generated from an an external source.</p>
<p>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.</p>
<p>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).</p>
<p>For more details see the <a href="http://docs.ansible.com/ansible/intro_inventory.html">Inventory</a> page in the Ansible documentation.</p>
</aside>
</section>
<section>
<h2>Inventory</h2>
<img src="images/how-ansible-works-diagram-06.svg" />
<aside class="notes">
<p>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.</p>
<p>For more details see the <a href="http://docs.ansible.com/ansible/intro_dynamic_inventory.html">Dynamic Inventory</a> page in the Ansible documentation.</p>
</aside>
</section>
<section>
<h2>Modules</h2>
<p>Modules are bits of code transferred to the target system and executed to satisfy the task declaration.</p>
<div class="columns">
<div class="col">
<ul>
<li>apt/yum</li>
<li>copy</li>
<li>file</li>
<li>get_url</li>
<li>git</li>
<li>ping</li>
<li>debug</li>
</ul>
</div>
<div class="col">
<ul>
<li>service</li>
<li>synchronize</li>
<li>template</li>
<li>uri</li>
<li>user</li>
<li>wait_for</li>
<li>assert</li>
</ul>
</div>
<div class="col">
</div>
</div>
<aside class="notes">
<p>If playbooks are the instruction manual for setting up and managing your infrastructure, Ansible modules are the tools in your toolkit.</p>
<p>We&rsquo;ve already discussed, Ansible modules. They are the &ldquo;batteries&rdquo; and the &ldquo;tools in a users toolkit.&rdquo;</p>
<p>While there are hundreds of modules at your disposal out-of-the-box these are the most common ones.</p>
<p>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.</p>
</aside>
</section>
<section>
<h2>Modules Documentation</h2>
<div class="columns">
<div class="col">
<p><strong>http://docs.ansible.com/</strong></p>
</div>
<div class="col">
<img src="images/modules-doc-screenshots.png" />
</div>
</div>
<aside class="notes">
<p><a href="http://docs.ansible.com/ansible/modules_by_category.html">A categorized index of included Ansible modules</a> along with detailed documentation for the requirements, parameters and return values of each Ansible module can be found on the <a href="http://docs.ansible.com/ansible/">Ansible documentation site</a>. </p>
</aside>
</section>
<section>
<h2>Modules Documentation</h2>
<pre class="language-yaml"><code>
# 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):
...
</code></pre>
</section>
<aside class="notes">
<p>Module documentation is also available from the commandline using the <code>ansible-doc</code>.</p>
<p>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.</p>
</aside>
<section>
<h2>Modules: Run Commands</h2>
<p>If Ansible doesn’t have a module that suits your needs there are the “run command” modules:</p><br>
<ul>
<li><b>command</b>: Takes the command and executes it on the host. The most secure and predictable.</li>
<li><b>shell</b>: Executes through a shell like <code>/bin/sh</code> so you can use pipes etc. Be careful.</li>
<li><b>script</b>: Runs a local script on a remote node after transferring it.</li>
<li><b>raw</b>: Executes a command without going through the Ansible module subsystem.</li>
</ul>
<p><br><b>NOTE:</b> Unlike standard modules, run commands have no concept of desired state and should only be used as a last resort.</p>
<aside class="notes">
<p>&quot;Run commands&quot; are what we collectively call these modules that enable users to do commandline 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.</p>
<p>The overuse of run commands is common amongst those just becoming familiar with Ansible for automating their work. They use <code>shell</code> 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. <b>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.</b></p>
<p><b>NOTE:</b> <code>shell</code> allows for IO redirection such as pipes. This is why It&apos;s best practice to use <code>command</code> unless they need to pipe something. It also best practice to <strong>never</strong> pass user input or variables thru a run command.</p>
</aside>
</section>
<section>
<h2>Inventory</h2>
<p>Inventory is a collection of hosts (nodes) with associated data and groupings that Ansible can connect and manage.</p>
<ul>
<li>Hosts (nodes)</li>
<li>Groups</li>
<li>Inventory-specific data (variables)</li>
<li>Static or dynamic sources</li>
</ul>
<aside class="notes">
<p>We've already discussed inventory in our review of Ansible's key components.</p>
<p>Inventory consists of hosts, groups, inventory specific data. Inventory can either be static or dynamic.</p>
<p>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 retreived from an external system.</p>
<p>You can specify a different inventory file using the <code>-i &lt;path&gt;</code> option on the commandline or your Ansible configuration file.</p>
</aside>
</section>
<section>
<h2>Static Inventory Example</h2>
<pre class="language-yaml"><code>
10.42.0.2
10.42.0.6
10.42.0.7
10.42.0.8
10.42.0.100
host.example.com
</code></pre>
<aside class="notes">
<p>Static inventory is the easiest source to get started with. This example shows a static inventory source in It&rsquo;s simplist form &ndash; a single file with a list of IP addresses or hostnames.</p>
<p><strong>NOTE:</strong> Ansible infers a localhost is present even if it is not explictly 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.</p>
</aside>
</section>
<section>
<h2>Static Inventory Example</h2>
<pre class="language-yaml"><code>
[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
</code></pre>
<aside class="notes">
<p>The example shown here is a more practical and common example of a static inventory file.</p>
<p>Static inventory files are expresed 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.)</p>
<p>NOTE: This example contains variables, a topic we haven't touched on just yet. We'll go into them on the next slide.</p>
<p>Other noteworthy attributes in our example:</p>
<ul>
<li><code>ansible_host</code> is an example of a host variable.</li>
<li>Hosts can be assigned arbitrary human-meaningful names or aliases such as "control" and "haproxy". Ansible will instead use the value of <code>ansible_host</code> (one of several <a href="http://docs.ansible.com/ansible/playbooks_variables.html#magic-variables-and-how-to-access-information-about-other-hosts">&quot;magic&quot; inventory variables</a>) as the network address to connect.</li>
<li>Static inventory files can support character ranges such as &quot;node-[1:3]&quot;</li>
<li>Like localhost, Ansible infers an &quot;all&quot; group is present. As its name implies, all inventory hosts are memebers of this group.</li>
<li>The heading &quot;all:vars&quot; is an example of group variable assignment using two more &quot;magic&quot; variables, <code>ansible_ssh_private_key_file</code> and <code>ansible_user</code>.</li>
</ul>
<p>This example just covers the basics. There's a lot more to inventory that is not covered here. See the <a href="http://docs.ansible.com/ansible/intro_inventory.html">Ansible inventory documentation</a> for more details.</p>
</aside>
</section>
<section>
<section>
<h2>Ad-Hoc Commands</h2>
<p>An ad-hoc command is a single Ansible task to perform quickly, but don’t want to save for later.</p>
<aside class="notes">
<p>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 &ndash; ad-hoc commands can also be used to do quick things that you might not necessarily want to write a full playbook for.</p>
<p>Generally speaking, the true power of Ansible lies in playbooks. So why would you use ad-hoc tasks versus playbooks?</p>
<p>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.</p>
</aside>
</section>
<section>
<h2>Ad-Hoc Commands: Common Options</h2>
<ul style="font-size: 0.75em;">
<li><b>-m MODULE_NAME, --module-name=MODULE_NAME</b><br/>Module name to execute the ad-hoc command</li>
<li><b>-a MODULE_ARGS, --args=MODULE_ARGS</b><br/>Module arguments for the ad-hoc command</li>
<li><b>-b, --become</b><br/>Run ad-hoc command with elevated rights such as sudo, the default method</li>
<li><b>-e EXTRA_VARS, --extra-vars=EXTRA_VARS</b><br/>Set additional variables as key=value or YAML/JSON</li>
<li><b>--version</b><br/>Display the version of Ansible</li>
<li><b>--help</b><br/>Display the MAN page for the ansible tool</li>
</ul>
<aside class="notes">
<p>This slide shows essential commanline options for running ad-hoc commands that will be useful in our upcoming workshop assignment.</p>
</aside>
</section>
</section>
<section>
<h2>Ad-Hoc Commands</h2>
<pre class="language-yaml"><code>
# 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 &quot;uptime&quot;
</code></pre>
<aside class="notes">
<p>Ad-hoc commands are quick checks on your servers that you don’t want to preserve in an Ansible playbook.</p>
<p>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.</p>
<p>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.</p>
<p>For more information see <a href="http://docs.ansible.com/ansible/intro_adhoc.html">Introduction To Ad-Hoc Commands</a>.</p>
</aside>
</section>
<section>
<h2>Sidebar: Discovered Facts</h2>
<p>Facts are bits of information derived from examining a host systems that are stored as variables for later use in a play.</p>
<pre class="language-yaml"><code>
$ 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"
},
</code></pre>
<aside class="notes">
<p>The second ad-hoc command example from the prior slide provides the following JSON output of a localhost facts run.</p>
<p>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 <code>ansible localhost -m setup</code> for a more complete represenation.</p>
<p>Ansible collects facts using the <code>setup</code> module. By default, Ansible will run the <code>setup</code> 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.</p>
</aside>
</section>
<section>
<section data-state="title alt">
<h1>Demo Time: <br/>Ad-Hoc Commands</h1>
<aside class="notes">
<p>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.</p>
<pre class="language-yaml"><code>
$ ansible all -m ping
$ ansible localhost -m setup
$ ansible web -m command -a &quot;uptime&quot;
</code></pre>
</aside>
</section>
<section data-state="title alt">
<h1>Workshop: <br/>Ad-Hoc Commands</h1>
<aside class="notes">
<p>This brief exercise demonstrates Ansible in-action at it&apos;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.</p>
<p>This workshop is also a good way to verify their lab environments are properly configured before going forward.</p>
<p>See <code>workshops/adhoc_commands</code> in the Ansible Lightbulb repo.</p>
</aside>
</section>
</section>
<section>
<h2>Variables</h2>
<p>Ansible can work with metadata from various sources and manage their context in the form of variables.</p>
<ul>
<li>Command line parameters</li>
<li>Plays and tasks</li>
<li>Files</li>
<li>Inventory</li>
<li>Discovered facts</li>
<li>Roles</li>
</ul>
</section>
<aside class="notes">
<p>While automation exists to make it easier to make things repeatable, all of your systems are not exactly alike.</p>
<p>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.</p>
</aside>
<section>
<h2>Variable Precedence</h2>
<p>The order in which the same variable from different sources will override each other.</p>
<div class="columns">
<div class="col">
<ol>
<li>extra vars</li>
<li>task vars (only for the task)</li>
<li>block vars (only for tasks in block)</li>
<li>role and include vars</li>
<li>play vars_files</li>
<li>play vars_prompt</li>
<li>play vars</li>
<li>set_facts</li>
</ol>
</div>
<div class="col">
<ol start="9" class="col">
<li>registered vars</li>
<li>host facts</li>
<li>playbook host_vars</li>
<li>playbook group_vars</li>
<li><strong>inventory host_vars</strong></li>
<li><strong>inventory group_vars</strong></li>
<li>inventory vars</li>
<li>role defaults</li>
</ol>
</div>
</div>
<aside class="notes">
<p>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.</p>
<p>There are 16 levels of variable precedence as of Ansible 2.x. The <code>extra_vars</code> (passed thru the commandline) 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 (higlighted in the list) in the variable precedence chain.</p>
<p>It&apos;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.</p>
<p>NOTE: The inventory variables sources showed in the static inventory example a couple of slides back are in bold type.</p>
</aside>
</section>
<section>
<h2>Tasks</h2>
<p>Tasks are the application of a module to perform a specific unit of work.</p>
<ul>
<li><b>file</b>: A directory should exist</li>
<li><b>yum</b>: A package should be installed</li>
<li><b>service</b>: A service should be running</li>
<li><b>template</b>: Render a configuration file from a template</li>
<li><b>get_url</b>: Fetch an archive file from a URL</li>
<li><b>git</b>: Clone a source code repository</li>
</ul>
<aside class="notes">
<p>We&apos;ve already reviewed modules, the batteries and tools Ansible provides. Tasks are the specific application of a module to perform a unit of automation.</p>
<p>Here we see a list of examples of common modules being applied to do something.</p>
<aside>
</section>
<section>
<h2>Example Tasks in a Play</h2>
<pre class="language-yaml"><code>
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: restart httpd
service:
name: httpd
state: restarted
</code></pre>
<aside class="notes">
<p>This example shows the task list of an Ansible playbook.</p>
<p>
<ol>
<li>The first task assures the latest nginx package is installed using yum.</li>
<li>The next uses the copy module to assure the latest version of a static home page file has been published.</li>
<li>The last task restarts the nginx service with the service module</li>
</ol>
</p>
</aside>
</section>
<section>
<h2>Handler Tasks</h2>
<p>Handlers are special tasks that run at the end of a play if notified by another task when a change occurs.</p>
<blockquote>If a package gets installed or updated, notify a service restart task that it needs to run.</blockquote>
<aside class="notes">
<p>Normal tasks run sequentially; handler tasks run on notification of a change and will only run once at the end of a play.</p>
<p>For more information see <a href="http://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change">Handler Tasks</a>.</p>
</aside>
</section>
<section>
<h2>Example Handler Task in a Play</h2>
<pre class="language-yaml"><code data-noescape>
tasks:
- name: httpd package is present
yum:
name: httpd
state: latest
<mark>notify: restart httpd</mark>
- name: latest index.html file is present
copy:
src: files/index.html
dest: /var/www/html/
<mark>handlers:</mark>
- name: restart httpd
service:
name: httpd
state: restarted
</code></pre>
<aside class="notes">
<p>Here is our previous example with a few slight modifications that have bene highlighted.</p>
<p>In this version of our example, we add a <code>notify</code> keyword to the first task to trigger a handler task if it returns &quot;changed&quot; as being true. The third tasks now is under a &quot;handlers&quot; section that signifies that the handler task will run on notification at the end of the play of change occurs during the first task.</p>
</aside>
</section>
<section>
<h2>Plays &amp; Playbooks</h2>
<p>Plays are ordered sets of tasks to execute against host selections from your inventory. A playbook is a file containing one or more plays.</p>
<aside class="notes">
<p>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.</p>
<p>For more details see <a href="http://docs.ansible.com/ansible/playbooks.html">the Playbook page</a> in the Ansible documenation.</p>
</aside>
</section>
<section>
<h2>Playbook Example</h2>
<pre class="language-yaml"><code data-noescape>
---
- 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
</code></pre>
<aside class="notes">
<p>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.</p>
</aside>
</section>
<section>
<h2>Human-Meaningful Naming</h2>
<pre class="language-yaml"><code data-noescape>
---
- <mark>name: install and start apache</mark>
hosts: web
become: yes
vars:
http_port: 80
tasks:
- <mark>name: httpd package is present</mark>
yum:
name: httpd
state: latest
- <mark>name: latest index.html file is present</mark>
copy:
src: files/index.html
dest: /var/www/html/
- <mark>name: httpd is started</mark>
service:
name: httpd
state: started
</code></pre>
<aside class="notes">
<p>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.</p>
<p>It&apos;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.</p>
</aside>
</section>
<section>
<h2>Host Selector</h2>
<pre class="language-yaml"><code data-noescape>
---
- name: install and start apache
<mark>hosts: web</mark>
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
</code></pre>
<aside class="notes">
<p>The Ansible play host selector defines which nodes in the inventory the automation is targetting.</p>
<p>In this example, a single group of &quot;web&quot; is being targetted. Ansible supports targetting intersections, unions and filters of multiple groups or hosts though.</p>
<p>For more details see <a href="http://docs.ansible.com/ansible/intro_patterns.html">the host selector Patterns page</a> in the Ansible documenation.</p>
</aside>
</section>
<section>
<h2>Privilege Escalation</h2>
<pre class="language-yaml"><code data-noescape>
---
- name: install and start apache
hosts: web
<mark>become: yes</mark>
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
</code></pre>
<aside class="notes">
<p>Ansible allows you to &quot;become&quot; 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.</p>
<p>For more details see <a href="http://docs.ansible.com/ansible/become.html">the Privilege Escalation page</a> in the Ansible documenation.</p>
</aside>
</section>
<section>
<h2>Play Variables</h2>
<pre class="language-yaml"><code data-noescape>
---
- name: install and start apache
hosts: web
become: yes
<mark>vars:</mark>
<mark>http_port: 80</mark>
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
</code></pre>
<aside class="notes">
<p>Variables are used to store metadata for each host drawing from numerous sources. Here we see another one of those sources, a variable &quot;http_port&quot; that has been embedded in a play.</p>
<p>Recalling the previous variable precedence slide, play variables are number 7 in Ansible&apos;s the precedence chain.</p>
</aside>
</section>
<section>
<h2>Tasks</h2>
<pre class="language-yaml"><code data-noescape>
---
- name: install and start apache
hosts: web
become: yes
vars:
http_port: 80
tasks:
- name: latest httpd package is present
<mark>yum:</mark>
<mark>name: httpd</mark>
<mark>state: latest</mark>
- name: latest index.html file is present
<mark>copy:</mark>
<mark>src: files/index.html</mark>
<mark>dest: /var/www/html/</mark>
- name: httpd is started
<mark>service:</mark>
<mark>name: httpd</mark>
<mark>state: started</mark>
</code></pre>
<aside class="notes">
<p>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.</p>
</aside>
</section>
<section>
<section data-state="title alt">
<h1>Demo Time: <br/>A Simple Playbook Run</h1>
<aside class="notes">
<p>To demonstrate how an Ansible, open an SSH session to your control host and run the playbook in <code>examples/apache-simple-playbook</code>. That example playbook is essentially the same one we just examined.</p>
<p>Don't forget to reverse what this playbook does before continuing to not interfere with later demos and workshops.</p>
</aside>
</section>
<section data-state="title alt">
<h1>Workshop: <br/>Your First Playbook</h1>
<aside class="notes">
<p>This assignment provides a quick introduction to playbook structure to give them a feel for how Ansible works, but in pratice is too simplistic to be useful.</p>
<p>See <code>workshops/simple_playbook</code> in the Ansible Lightbulb repo.</p>
<p>Note: If your time is limited, this is a workshop you can skip. We'll cover this and more topics in the next workshop.</p>
</aside>
</section>
</section>
<section>
<section>
<h2>Doing More with Playbooks</h2>
<p>Here are some more essential playbook features that you can apply:</p>
<ul>
<li>Templates</li>
<li>Loops</li>
<li>Conditionals</li>
<li>Tags</li>
<li>Blocks</li>
</ul>
<aside class="notes">
<p>We only have covered the most essential capabiltites of what can be done with a playbook so far.</p>
<p>Here we list a few more though this is still far from all there is. There&apos;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.</p>
</aside>
</section>
<section>
<h2>Templates</h2>
<p>Ansible embeds the <a href="http://jinja.pocoo.org/docs/">Jinja2 templating engine</a> that can be used to dynamically:</p>
<ul>
<li>Set and modify play variables</li>
<li>Conditional logic</li>
<li>Generate files such as configurations from variables</li>
</ul>
<aside class="notes">
<p>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.</p>
<p>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.</p>
<p>In all actuality, what is covered here only touches upon a few of its most basic features. To go deeper see these docs:</p>
<ul>
<li><a href="http://jinja.pocoo.org/docs/dev/templates/">Jinja2 Template Designer Documentation</a></li>
<li><a href="http://docs.ansible.com/ansible/playbooks_filters.html">Ansible Jinja2 Filters</a></li>
<li><a href="http://docs.ansible.com/ansible/playbooks_tests.html">Ansible Jinja2 Tests</a></li>
</ul>
</aside>
</section>
<section>
<h2>Loops</h2>
<p>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.</p>
<pre class="language-yaml"><code data-noescape>
- yum:
name: <mark>&quot;{{ item }}&quot;</mark>
state: latest
<mark>with_items:</mark>
<mark>- httpd</mark>
<mark>- mod_wsgi</mark>
</code></pre>
<aside class="notes">
<p>This example demonstrates a basic loop with <code>with_items</code>. The loop sets a variable called &quot;item&quot;, a template variable courtesy of the embedded Jinja2 template engine, with the list value that is in context.</p>
<p>There are many different and specialized types of task loops to work with. See the <a href="http://docs.ansible.com/ansible/playbooks_loops.html">Loops documentation</a> to go deeper.</p>
</aside>
</section>
<section>
<h2>Conditionals</h2>
<p>Ansible supports the conditional execution of a task based on the run-time evaluation of variable, fact, or previous task result.</p>
<pre class="language-yaml"><code data-noescape>
- yum:
name: httpd
state: latest
<mark>when: ansible_os_family == &quot;RedHat&quot;</mark>
</code></pre>
<aside class="notes">
<p>Conditionals are another instance of Jinja2 in action within Ansible plays themselves. In the provided example &quot;ansible_os_family&quot; is a fact variable Ansible will set.</p>
<p>There are other forms of conditional clauses, but <code>when</code> is usually all that is needed.</p>
<p>NOTE: Conditional clauses are consdered to be raw Jinja2 expression without double curly braces.</p>
</aside>
</section>
<section>
<h2>Tags</h2>
<p>Tags are useful to be able to run a subset of a playbook on-demand.</p>
<pre class="language-yaml"><code data-noescape>
- yum:
name: &quot;{{ item }}&quot;
state: latest
with_items:
- httpd
- mod_wsgi
<mark>tags:</mark>
<mark>- packages</mark>
- template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
<mark>tags:</mark>
<mark>- configuration</mark>
</code></pre>
<aside class="notes">
<p>In the provided example, if the playbook were run with <code>--tags &quot;packages&quot;</code> the yum task would execute and the template task would be skipped. If the playbook were run with <code>--tags &quot;configuration&quot;</code> the opposite would happen. Without a <code>--tags</code> both tasks would execute like normal.</p>
<p>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 <a href="http://docs.ansible.com/ansible/playbooks_tags.html">playbook Tags documentation</a>.</p>
</aside>
</section>
<section>
<h2>Blocks</h2>
<p>Blocks cut down on repetitive task directives, allow for logical grouping of tasks and even in play error handling.</p>
<pre class="language-yaml"><code data-noescape>
- <mark>block:</mark>
- yum:
name: &quot;{{ item }}&quot;
state: latest
with_items:
- httpd
- mod_wsgi
- template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
when: ansible_os_family == &quot;RedHat&quot;
</code></pre>
<aside class="notes">
<p>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 <code>when</code> 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.</p>
<p>Blocks have a play in error handling and automating roll backs that we won't get into here given the scope of that topic.</p>
<p>See the <a href="http://docs.ansible.com/ansible/playbooks_blocks.html">documentation on blocks</a> to dig deeper.</p>
</section>
</section>
<section>
<section data-state="title alt">
<h1>Demo Time: <br/>A More Practical Playbook</h1>
<aside class="notes">
<p>The simple playbook we examined gave us a sense of the structure of a playbook and how they work, but in reality was too simlistic to be practical. Here we look at a basic playbook that it more complete to what users will commonly do with Ansible.</p>
<p>Walk thru the site.yml playbook in <code>examples/apache-basic-playbook</code> and note the added logic and its function. Then, run the playbook on the control host.</p>
<p>Don't forget to reverse what this playbook does before continuing to not interfere with later demos and workshops.</p>
</aside>
</section>
<section data-state="title alt">
<h1>Workshop: <br/>Practical Playbook Development</h1>
<aside class="notes">
<p>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.</p>
<p>See <code>workshops/basic_playbook/</code> in the Ansible Lightbulb repo.</p>
<p>Tip: Don&apos;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.</p>
</aside>
</section>
</section>
<section>
<h2>Roles</h2>
<p>Roles are a packages of closely related Ansible content that can be shared more easily than plays alone.</p>
<ul>
<li>Improves readability and maintainability of complex plays</li>
<li>Eases sharing, reuse and standardization of automation processes</li>
<li>Enables Ansible content to exist independently of playbooks, projects -- even organizations</li>
<li>Provides functional conveniences such as file path resolution and default values</li>
</ul>
<aside class="notes">
<p>Roles are closely related Ansible content that are organized into a pre-defined directory structure, making them easier to reuse and share among groups.</p>
</aside>
</section>
<section>
<h2>Project with Embedded Roles Example</h2>
<pre class="language-yaml"><code>
site.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
apache/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
</code></pre>
<aside class="notes">
<p>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.</p>
</aside>
</section>
<section>
<h2>Project with Embedded Roles Example</h2>
<pre class="language-yaml"><code>
# site.yml
---
- hosts: web
roles:
- common
- apache
</code></pre>
<aside class="notes">
<p>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.</p>
</aside>
</section>
<section>
<h2>Ansible Galaxy</h2>
<p><strong>http://galaxy.ansible.com</strong></p>
<p>Ansible Galaxy is a hub for finding, reusing and sharing Ansible content.</p>
<p>Jump-start your automation project with content contributed and reviewed by the Ansible community.</p>
<aside class="notes speaker">
<p>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 jumpstart your automation projects.
<p>Galaxy also refers to a command line tool, <code>ansible-galaxy</code>, 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.</p>
</aside>
</section>
<section>
<section data-state="title alt">
<h1>Demo Time: <br/>A Playbook Using Roles</h1>
<aside class="notes">
<p>Walk thru the site.yml playbook and the contents of <code>roles/apache</code> in <code>examples/apache-role</code>. Note how the tasks, variables and handlers from the basic Ansible playbook we've been examined and have been refactored into a role.</p>
<p>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.</p>
</aside>
</section>
<section data-state="title alt">
<h1>Workshop: <br/>Your First Roles</h1>
<aside class="notes">
<p>Here students are tasked with refactoring their previous work from the Practical Playbook workshop into a role and modifying their playbook accordingly. We intentioinally avoid introducing any new tasks or functionality otherwise. The objective here is to focus students specifically on how roles are structured and develop.</p>
<p>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.</p>
<p>See <code>workshops/roles</code> in the Ansible Lightbulb repo.</p>
</aside>
</section>
</section>
<section>
<h2>Next Steps</h2>
<ul>
<li><strong>It&apos;s easy to get started</strong><br/>ansible.com/get-started</li>
<li><strong>Join the Ansible community</strong><br/>ansible.com/community</li>
<li><strong>Would you like to learn a lot more?</strong><br/>redhat.com/en/services/training/do407-automation-ansible</li>
</ul>
</section>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/lib/js/head.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/js/reveal.js"></script>
<script>
// More info https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
history: true,
width: "85%",
height: "90%",
transition: "fade",
// More info https://github.com/hakimel/reveal.js#dependencies
// Notes plugin must remain local for now.
// See https://github.com/ansible/lightbulb/issues/125
dependencies: [
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/plugin/markdown/marked.js' },
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/prism.min.js'},
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/components/prism-yaml.min.js'}
//{ src: 'https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.4.1/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }
]
});
</script>
</body>
</html>