Track2Agenda: first-playbook.htm

File first-playbook.htm, 35.0 KB (added by Brian Candler, 6 years ago)
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2<html xmlns="http://www.w3.org/1999/xhtml">
3<head>
4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5  <meta http-equiv="Content-Style-Type" content="text/css" />
6  <meta name="generator" content="pandoc" />
7  <title>First playbooks in Ansible</title>
8  <style type="text/css">code{white-space: pre;}</style>
9  <link href="data:text/css,%2F%2A%0A%20%20%20%20Buttondown%0A%20%20%20%20A%20Markdown%2FMultiMarkdown%2FPandoc%20HTML%20output%20CSS%20stylesheet%0A%20%20%20%20Author%3A%20Ryan%20Gray%0A%20%20%20%20Date%3A%2015%20Feb%202011%0A%20%20%20%20Revised%3A%2021%20Feb%202012%0A%20%20%20%0A%20%20%20%20General%20style%20is%20clean%2C%20with%20minimal%20re%2Ddefinition%20of%20the%20defaults%20or%20%0A%20%20%20%20overrides%20of%20user%20font%20settings%2E%20The%20body%20text%20and%20header%20styles%20are%20%0A%20%20%20%20left%20alone%20except%20title%2C%20author%20and%20date%20classes%20are%20centered%2E%20A%20Pandoc%20TOC%20%0A%20%20%20%20is%20not%20printed%2C%20URLs%20are%20printed%20after%20hyperlinks%20in%20parentheses%2E%20%0A%20%20%20%20Block%20quotes%20are%20italicized%2E%20Tables%20are%20lightly%20styled%20with%20lines%20above%20%0A%20%20%20%20and%20below%20the%20table%20and%20below%20the%20header%20with%20a%20boldface%20header%2E%20Code%20%0A%20%20%20%20blocks%20are%20line%20wrapped%2E%20%0A%20%0A%20%20%20%20All%20elements%20that%20Pandoc%20and%20MultiMarkdown%20use%20should%20be%20listed%20here%2C%20even%20%0A%20%20%20%20if%20the%20style%20is%20empty%20so%20you%20can%20easily%20add%20styling%20to%20anything%2E%0A%20%20%20%20%0A%20%20%20%20There%20are%20some%20elements%20in%20here%20for%20HTML5%20output%20of%20Pandoc%2C%20but%20I%20have%20not%20%0A%20%20%20%20gotten%20around%20to%20testing%20that%20yet%2E%0A%2A%2F%0A%20%0A%2F%2A%20NOTES%3A%0A%20%0A%20%20%20%20Stuff%20tried%20and%20failed%3A%0A%20%20%20%20%0A%20%20%20%20It%20seems%20that%20specifying%20font%2Dfamily%3Aserif%20in%20Safari%20will%20always%20use%20%0A%20%20%20%20Times%20New%20Roman%20rather%20than%20the%20user%27s%20preferences%20setting%2E%0A%20%20%20%20%0A%20%20%20%20Making%20the%20font%20size%20different%20or%20a%20fixed%20value%20for%20print%20in%20case%20the%20screen%20%0A%20%20%20%20font%20size%20is%20making%20the%20print%20font%20too%20big%3A%20Making%20font%2Dsize%20different%20for%20%0A%20%20%20%20print%20than%20for%20screen%20causes%20horizontal%20lines%20to%20disappear%20in%20math%20when%20using%20%0A%20%20%20%20MathJax%20under%20Safari%2E%0A%2A%2F%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Front%20Matter%20%2D%2D%2D%2D%20%2A%2F%0A%20%0A%2F%2A%20Pandoc%20header%20DIV%2E%20Contains%20%2Etitle%2C%20%2Eauthor%20and%20%2Edate%2E%20Comes%20before%20div%23TOC%2E%20%0A%20%20%20Only%20appears%20if%20one%20of%20those%20three%20are%20in%20the%20document%2E%0A%2A%2F%0A%20%0Adiv%23header%2C%20header%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Put%20border%20on%20bottom%2E%20Separates%20it%20from%20TOC%20or%20body%20that%20comes%20after%20it%2E%20%2A%2F%0A%20%20%20%20border%2Dbottom%3A%201px%20solid%20%23aaa%3B%0A%20%20%20%20margin%2Dbottom%3A%200%2E5em%3B%0A%20%20%20%20%7D%0A%20%0A%2Etitle%20%2F%2A%20Pandoc%20title%20header%20%28h1%2Etitle%29%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20text%2Dalign%3A%20center%3B%0A%20%20%20%20%7D%0A%20%0A%2Eauthor%2C%20%2Edate%20%2F%2A%20Pandoc%20author%28s%29%20and%20date%20headers%20%28h2%2Eauthor%20and%20h3%2Edate%29%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20text%2Dalign%3A%20center%3B%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20Pandoc%20table%20of%20contents%20DIV%20when%20using%20the%20%2D%2Dtoc%20option%2E%0A%20%20%20NOTE%3A%20this%20doesn%27t%20support%20Pandoc%27s%20%2D%2Did%2Dprefix%20option%20for%20%23TOC%20and%20%23header%2E%20%0A%20%20%20Probably%20would%20need%20to%20use%20div%5Bid%24%3D%27TOC%27%5D%20and%20div%5Bid%24%3D%27header%27%5D%20as%20selectors%2E%0A%2A%2F%0A%20%0Adiv%23TOC%2C%20nav%23TOC%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Put%20border%20on%20bottom%20to%20separate%20it%20from%20body%2E%20%2A%2F%0A%20%20%20%20border%2Dbottom%3A%201px%20solid%20%23aaa%3B%0A%20%20%20%20margin%2Dbottom%3A%200%2E5em%3B%0A%20%20%20%20%7D%0A%20%0A%40media%20print%0A%20%20%20%20%7B%0A%20%20%20%20div%23TOC%2C%20nav%23TOC%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2A%20Don%27t%20display%20TOC%20in%20print%20%2A%2F%0A%20%20%20%20%20%20%20%20display%3A%20none%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Headers%20and%20sections%20%2D%2D%2D%2D%20%2A%2F%0A%20%0Ah1%2C%20h2%2C%20h3%2C%20h4%2C%20h5%2C%20h6%0A%7B%0A%20%20%20%20font%2Dfamily%3A%20%22Helvetica%20Neue%22%2C%20Helvetica%2C%20%22Liberation%20Sans%22%2C%20Calibri%2C%20Arial%2C%20sans%2Dserif%3B%20%2F%2A%20Sans%2Dserif%20headers%20%2A%2F%0A%20%0A%20%20%20%20%2F%2A%20font%2Dfamily%3A%20%22Liberation%20Serif%22%2C%20%22Georgia%22%2C%20%22Times%20New%20Roman%22%2C%20serif%3B%20%2F%2A%20Serif%20headers%20%2A%2F%0A%20%0A%20%20%20%20page%2Dbreak%2Dafter%3A%20avoid%3B%20%2F%2A%20Firefox%2C%20Chrome%2C%20and%20Safari%20do%20not%20support%20the%20property%20value%20%22avoid%22%20%2A%2F%0A%7D%0A%20%0A%2F%2A%20Pandoc%20with%20%2D%2Dsection%2Ddivs%20option%20%2A%2F%0A%20%0Adiv%20div%2C%20section%20section%20%2F%2A%20Nested%20sections%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20margin%2Dleft%3A%202em%3B%20%2F%2A%20This%20will%20increasingly%20indent%20nested%20header%20sections%20%2A%2F%0A%20%20%20%20%7D%0A%20%0Ap%20%7B%7D%0A%20%0Ablockquote%0A%20%20%20%20%7B%20%0A%20%20%20%20font%2Dstyle%3A%20italic%3B%0A%20%20%20%20%7D%0A%20%0Ali%20%2F%2A%20All%20list%20items%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Ali%20%3E%20p%20%2F%2A%20Loosely%20spaced%20list%20item%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20margin%2Dtop%3A%201em%3B%20%2F%2A%20IE%3A%20lack%20of%20space%20above%20a%20%3Cli%3E%20when%20the%20item%20is%20inside%20a%20%3Cp%3E%20%2A%2F%0A%20%20%20%20%7D%0A%20%0Aul%20%2F%2A%20Whole%20unordered%20list%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Aul%20li%20%2F%2A%20Unordered%20list%20item%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Aol%20%2F%2A%20Whole%20ordered%20list%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Aol%20li%20%2F%2A%20Ordered%20list%20item%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Ahr%20%7B%7D%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Some%20span%20elements%20%2D%2D%2D%20%2A%2F%0A%20%0Asub%20%2F%2A%20Subscripts%2E%20Pandoc%3A%20H%7E2%7EO%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Asup%20%2F%2A%20Superscripts%2E%20Pandoc%3A%20The%202%5End%5E%20try%2E%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%20%20%20%0Aem%20%2F%2A%20Emphasis%2E%20Markdown%3A%20%2Aemphasis%2A%20or%20%5Femphasis%5F%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%20%20%20%0Aem%20%3E%20em%20%2F%2A%20Emphasis%20within%20emphasis%3A%20%2AThis%20is%20all%20%2Aemphasized%2A%20except%20that%2A%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20font%2Dstyle%3A%20normal%3B%0A%20%20%20%20%7D%0A%20%0Astrong%20%2F%2A%20Markdown%20%2A%2Astrong%2A%2A%20or%20%5F%5Fstrong%5F%5F%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Links%20%28anchors%29%20%2D%2D%2D%2D%20%2A%2F%0A%20%0Aa%20%2F%2A%20All%20links%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Keep%20links%20clean%2E%20On%20screen%2C%20they%20are%20colored%3B%20in%20print%2C%20they%20do%20nothing%20anyway%2E%20%2A%2F%0A%20%20%20%20text%2Ddecoration%3A%20none%3B%0A%20%20%20%20%7D%0A%20%0A%40media%20screen%0A%20%20%20%20%7B%0A%20%20%20%20a%3Ahover%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2A%20On%20hover%2C%20we%20indicate%20a%20bit%20more%20that%20it%20is%20a%20link%2E%20%2A%2F%0A%20%20%20%20%20%20%20%20text%2Ddecoration%3A%20underline%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%0A%40media%20print%0A%20%20%20%20%7B%0A%20%20%20%20a%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2A%20In%20print%2C%20a%20colored%20link%20is%20useless%2C%20so%20un%2Dstyle%20it%2E%20%2A%2F%0A%20%20%20%20%20%20%20%20color%3A%20black%3B%0A%20%20%20%20%20%20%20%20background%3A%20transparent%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20a%5Bhref%5E%3D%22http%3A%2F%2F%22%5D%3Aafter%2C%20a%5Bhref%5E%3D%22https%3A%2F%2F%22%5D%3Aafter%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2A%20However%2C%20links%20that%20go%20somewhere%20else%2C%20might%20be%20useful%20to%20the%20reader%2C%0A%20%20%20%20%20%20%20%20%20%20%20so%20for%20http%20and%20https%20links%2C%20print%20the%20URL%20after%20what%20was%20the%20link%20%0A%20%20%20%20%20%20%20%20%20%20%20text%20in%20parens%0A%20%20%20%20%20%20%20%20%2A%2F%0A%20%20%20%20%20%20%20%20content%3A%20%22%20%28%22%20attr%28href%29%20%22%29%20%22%3B%0A%20%20%20%20%20%20%20%20font%2Dsize%3A%2090%25%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Images%20%2D%2D%2D%2D%20%2A%2F%0A%20%0Aimg%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Let%20it%20be%20inline%20left%2Fright%20where%20it%20wants%20to%20be%2C%20but%20verticality%20make%20%0A%20%20%20%20%20%20%20it%20in%20the%20middle%20to%20look%20nicer%2C%20but%20opinions%20differ%2C%20and%20if%20in%20a%20multi%2Dline%20%0A%20%20%20%20%20%20%20paragraph%2C%20it%20might%20not%20be%20so%20great%2E%20%0A%20%20%20%20%2A%2F%0A%20%20%20%20vertical%2Dalign%3A%20middle%3B%0A%20%20%20%20%7D%0A%20%0Adiv%2Efigure%20%2F%2A%20Pandoc%20figure%2Dstyle%20image%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Center%20the%20image%20and%20caption%20%2A%2F%0A%20%20%20%20margin%2Dleft%3A%20auto%3B%0A%20%20%20%20margin%2Dright%3A%20auto%3B%0A%20%20%20%20text%2Dalign%3A%20center%3B%0A%20%20%20%20font%2Dstyle%3A%20italic%3B%0A%20%20%20%20%7D%0A%20%0Ap%2Ecaption%20%2F%2A%20Pandoc%20figure%2Dstyle%20caption%20within%20div%2Efigure%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Inherits%20div%2Efigure%20props%20by%20default%20%2A%2F%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Code%20blocks%20and%20spans%20%2D%2D%2D%2D%20%2A%2F%0A%20%0Apre%2C%20code%20%0A%20%20%20%20%7B%0A%20%20%20%20background%2Dcolor%3A%20%23fdf7ee%3B%0A%20%20%20%20%2F%2A%20BEGIN%20word%20wrap%20%2A%2F%0A%20%20%20%20%2F%2A%20Need%20all%20the%20following%20to%20word%20wrap%20instead%20of%20scroll%20box%20%2A%2F%0A%20%20%20%20%2F%2A%20This%20will%20override%20the%20overflow%3Aauto%20if%20present%20%2A%2F%0A%20%20%20%20white%2Dspace%3A%20pre%2Dwrap%3B%20%2F%2A%20css%2D3%20%2A%2F%0A%20%20%20%20white%2Dspace%3A%20%2Dmoz%2Dpre%2Dwrap%20%21important%3B%20%2F%2A%20Mozilla%2C%20since%201999%20%2A%2F%0A%20%20%20%20white%2Dspace%3A%20%2Dpre%2Dwrap%3B%20%2F%2A%20Opera%204%2D6%20%2A%2F%0A%20%20%20%20white%2Dspace%3A%20%2Do%2Dpre%2Dwrap%3B%20%2F%2A%20Opera%207%20%2A%2F%0A%20%20%20%20word%2Dwrap%3A%20break%2Dword%3B%20%2F%2A%20Internet%20Explorer%205%2E5%2B%20%2A%2F%0A%20%20%20%20%2F%2A%20END%20word%20wrap%20%2A%2F%0A%20%20%20%20%7D%0A%20%0Apre%20%2F%2A%20Code%20blocks%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Distinguish%20pre%20blocks%20from%20other%20text%20by%20more%20than%20the%20font%20with%20a%20background%20tint%2E%20%2A%2F%0A%20%20%20%20padding%3A%200%2E5em%3B%20%2F%2A%20Since%20we%20have%20a%20background%20color%20%2A%2F%0A%20%20%20%20border%2Dradius%3A%205px%3B%20%2F%2A%20Softens%20it%20%2A%2F%0A%20%20%20%20%2F%2A%20Give%20it%20a%20some%20definition%20%2A%2F%0A%20%20%20%20border%3A%201px%20solid%20%23aaa%3B%0A%20%20%20%20%2F%2A%20Set%20it%20off%20left%20and%20right%2C%20seems%20to%20look%20a%20bit%20nicer%20when%20we%20have%20a%20background%20%2A%2F%0A%20%20%20%20margin%2Dleft%3A%20%200%2E5em%3B%0A%20%20%20%20margin%2Dright%3A%200%2E5em%3B%0A%20%20%20%20%7D%0A%20%0A%40media%20screen%0A%20%20%20%20%7B%0A%20%20%20%20pre%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2A%20On%20screen%2C%20use%20an%20auto%20scroll%20box%20for%20long%20lines%2C%20unless%20word%2Dwrap%20is%20enabled%20%2A%2F%0A%20%20%20%20%20%20%20%20white%2Dspace%3A%20pre%3B%0A%20%20%20%20%20%20%20%20overflow%3A%20auto%3B%0A%20%20%20%20%20%20%20%20%2F%2A%20Dotted%20looks%20better%20on%20screen%20and%20solid%20seems%20to%20print%20better%2E%20%2A%2F%0A%20%20%20%20%20%20%20%20border%3A%201px%20dotted%20%23777%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%0Acode%20%2F%2A%20All%20inline%20code%20spans%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Ap%20%3E%20code%2C%20li%20%3E%20code%20%2F%2A%20Code%20spans%20in%20paragraphs%20and%20tight%20lists%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Pad%20a%20little%20from%20adjacent%20text%20%2A%2F%0A%20%20%20%20padding%2Dleft%3A%20%202px%3B%0A%20%20%20%20padding%2Dright%3A%202px%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0Ali%20%3E%20p%20code%20%2F%2A%20Code%20span%20in%20a%20loose%20list%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20We%20have%20room%20for%20some%20more%20background%20color%20above%20and%20below%20%2A%2F%0A%20%20%20%20padding%3A%202px%3B%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Math%20%2D%2D%2D%2D%20%2A%2F%0A%20%0Aspan%2Emath%20%2F%2A%20Pandoc%20inline%20math%20default%20and%20%2D%2Djsmath%20inline%20math%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%2F%2A%20Tried%20font%2Dstyle%3Aitalic%20here%2C%20and%20it%20messed%20up%20MathJax%20rendering%20in%20some%20browsers%2E%20Maybe%20don%27t%20mess%20with%20at%20all%2E%20%2A%2F%0A%20%20%20%20%7D%0A%20%20%20%20%0Adiv%2Emath%20%2F%2A%20Pandoc%20%2D%2Djsmath%20display%20math%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%20%20%20%0Aspan%2ELaTeX%20%2F%2A%20Pandoc%20%2D%2Dlatexmathml%20math%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%20%0A%20%0Aeq%20%2F%2A%20Pandoc%20%2D%2Dgladtex%20math%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%20%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Tables%20%2D%2D%2D%2D%20%2A%2F%0A%20%0A%2F%2A%20%20A%20clean%20textbook%2Dlike%20style%20with%20horizontal%20lines%20above%20and%20below%20and%20under%20%0A%20%20%20%20the%20header%2E%20Rows%20highlight%20on%20hover%20to%20help%20scanning%20the%20table%20on%20screen%2E%0A%2A%2F%0A%20%0Atable%0A%20%20%20%20%7B%0A%20%20%20%20border%2Dcollapse%3A%20collapse%3B%0A%20%20%20%20border%2Dspacing%3A%200%3B%20%2F%2A%20IE%206%20%2A%2F%0A%20%0A%20%20%20%20border%2Dbottom%3A%202pt%20solid%20%23000%3B%0A%20%20%20%20border%2Dtop%3A%202pt%20solid%20%23000%3B%20%2F%2A%20The%20caption%20on%20top%20will%20not%20have%20a%20bottom%2Dborder%20%2A%2F%0A%20%0A%20%20%20%20%2F%2A%20Center%20%2A%2F%0A%20%20%20%20margin%2Dleft%3A%20auto%3B%0A%20%20%20%20margin%2Dright%3A%20auto%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0Athead%20%2F%2A%20Entire%20table%20header%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20border%2Dbottom%3A%201pt%20solid%20%23000%3B%0A%20%20%20%20background%2Dcolor%3A%20%23eee%3B%20%2F%2A%20Does%20this%20BG%20print%20well%3F%20%2A%2F%0A%20%20%20%20%7D%0A%20%0Atr%2Eheader%20%2F%2A%20Each%20header%20row%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%20%0A%20%0Atbody%20%2F%2A%20Entire%20table%20%20body%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20Table%20body%20rows%20%2A%2F%0A%20%0Atr%20%20%7B%0A%20%20%20%20%7D%0Atr%2Eodd%3Ahover%2C%20tr%2Eeven%3Ahover%20%2F%2A%20Use%20%2Eodd%20and%20%2Eeven%20classes%20to%20avoid%20styling%20rows%20in%20other%20tables%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20background%2Dcolor%3A%20%23eee%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%2F%2A%20Odd%20and%20even%20rows%20%2A%2F%0Atr%2Eodd%20%7B%7D%0Atr%2Eeven%20%7B%7D%0A%20%0Atd%2C%20th%20%2F%2A%20Table%20cells%20and%20table%20header%20cells%20%2A%2F%0A%20%20%20%20%7B%20%0A%20%20%20%20vertical%2Dalign%3A%20top%3B%20%2F%2A%20Word%20%2A%2F%0A%20%20%20%20vertical%2Dalign%3A%20baseline%3B%20%2F%2A%20Others%20%2A%2F%0A%20%20%20%20padding%2Dleft%3A%20%20%200%2E5em%3B%0A%20%20%20%20padding%2Dright%3A%20%200%2E5em%3B%0A%20%20%20%20padding%2Dtop%3A%20%20%20%200%2E2em%3B%0A%20%20%20%20padding%2Dbottom%3A%200%2E2em%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0A%2F%2A%20Removes%20padding%20on%20left%20and%20right%20of%20table%20for%20a%20tight%20look%2E%20Good%20if%20thead%20has%20no%20background%20color%2A%2F%0A%2F%2A%0Atr%20td%3Alast%2Dchild%2C%20tr%20th%3Alast%2Dchild%0A%20%20%20%20%7B%0A%20%20%20%20padding%2Dright%3A%200%3B%0A%20%20%20%20%7D%0Atr%20td%3Afirst%2Dchild%2C%20tr%20th%3Afirst%2Dchild%20%0A%20%20%20%20%7B%0A%20%20%20%20padding%2Dleft%3A%200%3B%0A%20%20%20%20%7D%0A%2A%2F%0A%20%0Ath%20%2F%2A%20Table%20header%20cells%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20font%2Dweight%3A%20bold%3B%20%0A%20%20%20%20%7D%0A%20%0Atfoot%20%2F%2A%20Table%20footer%20%28what%20appears%20here%20if%20caption%20is%20on%20top%3F%29%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0Acaption%20%2F%2A%20This%20is%20for%20a%20table%20caption%20tag%2C%20not%20the%20p%2Ecaption%20Pandoc%20uses%20in%20a%20div%2Efigure%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20caption%2Dside%3A%20top%3B%0A%20%20%20%20border%3A%20none%3B%0A%20%20%20%20font%2Dsize%3A%200%2E9em%3B%0A%20%20%20%20font%2Dstyle%3A%20italic%3B%0A%20%20%20%20text%2Dalign%3A%20center%3B%0A%20%20%20%20margin%2Dbottom%3A%200%2E3em%3B%20%2F%2A%20Good%20for%20when%20on%20top%20%2A%2F%0A%20%20%20%20padding%2Dbottom%3A%200%2E2em%3B%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20%2D%2D%2D%2D%20Definition%20lists%20%2D%2D%2D%2D%20%2A%2F%0A%20%0Adl%20%2F%2A%20The%20whole%20list%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20border%2Dtop%3A%202pt%20solid%20black%3B%0A%20%20%20%20padding%2Dtop%3A%200%2E5em%3B%0A%20%20%20%20border%2Dbottom%3A%202pt%20solid%20black%3B%0A%20%20%20%20%7D%0A%20%0Adt%20%2F%2A%20Definition%20term%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20font%2Dweight%3A%20bold%3B%0A%20%20%20%20%7D%0A%20%0Add%2Bdt%20%2F%2A%202nd%20or%20greater%20term%20in%20the%20list%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20border%2Dtop%3A%201pt%20solid%20black%3B%0A%20%20%20%20padding%2Dtop%3A%200%2E5em%3B%0A%20%20%20%20%7D%0A%20%20%20%20%0Add%20%2F%2A%20A%20definition%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20margin%2Dbottom%3A%200%2E5em%3B%0A%20%20%20%20%7D%0A%20%0Add%2Bdd%20%2F%2A%202nd%20or%20greater%20definition%20of%20a%20term%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20border%2Dtop%3A%201px%20solid%20black%3B%20%2F%2A%20To%20separate%20multiple%20definitions%20%2A%2F%0A%20%20%20%20%7D%0A%20%20%20%20%0A%2F%2A%20%2D%2D%2D%2D%20Footnotes%20%2D%2D%2D%2D%20%2A%2F%0A%20%0Aa%2Efootnote%2C%20a%2EfootnoteRef%20%7B%20%2F%2A%20Pandoc%2C%20MultiMarkdown%20footnote%20links%20%2A%2F%0A%20%20%20%20font%2Dsize%3A%20small%3B%20%0A%20%20%20%20vertical%2Dalign%3A%20text%2Dtop%3B%0A%7D%0A%20%0Aa%5Bhref%5E%3D%22%23fnref%22%5D%2C%20a%2Ereversefootnote%20%2F%2A%20Pandoc%2C%20MultiMarkdown%2C%20%3F%3F%20footnote%20back%20links%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0A%40media%20print%0A%20%20%20%20%7B%0A%20%20%20%20a%5Bhref%5E%3D%22%23fnref%22%5D%2C%20a%2Ereversefootnote%20%2F%2A%20Pandoc%2C%20MultiMarkdown%20%2A%2F%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2A%20Don%27t%20display%20these%20at%20all%20in%20print%20since%20the%20arrow%20is%20only%20something%20to%20click%20on%20%2A%2F%0A%20%20%20%20%20%20%20%20display%3A%20none%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20%0Adiv%2Efootnotes%20%2F%2A%20Pandoc%20footnotes%20div%20at%20end%20of%20the%20document%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%20%20%20%0Adiv%2Efootnotes%20li%5Bid%5E%3D%22fn%22%5D%20%2F%2A%20A%20footnote%20item%20within%20that%20div%20%2A%2F%0A%20%20%20%20%7B%0A%20%20%20%20%7D%0A%20%0A%2F%2A%20You%20can%20class%20stuff%20as%20%22noprint%22%20to%20not%20print%2E%20%0A%20%20%20Useful%20since%20you%20can%27t%20set%20this%20media%20conditional%20inside%20an%20HTML%20element%27s%20%0A%20%20%20style%20attribute%20%28I%20think%29%2C%20and%20you%20don%27t%20want%20to%20make%20another%20stylesheet%20that%20%0A%20%20%20imports%20this%20one%20and%20adds%20a%20class%20just%20to%20do%20this%2E%0A%2A%2F%0A%20%0A%40media%20print%0A%20%20%20%20%7B%0A%20%20%20%20%2Enoprint%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20display%3Anone%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A" rel="stylesheet" type="text/css" />
10</head>
11<body>
12<div id="header">
13<h1 class="title">First playbooks in Ansible</h1>
14</div>
15<div id="TOC">
16<ul>
17<li><a href="#objective"><span class="toc-section-number">1</span> Objective</a></li>
18<li><a href="#setup"><span class="toc-section-number">2</span> Setup</a></li>
19<li><a href="#writing-a-playbook"><span class="toc-section-number">3</span> Writing a playbook</a><ul>
20<li><a href="#creating-a-first-playbook"><span class="toc-section-number">3.1</span> Creating a first playbook</a></li>
21</ul></li>
22<li><a href="#web-server-example"><span class="toc-section-number">4</span> Web server example</a><ul>
23<li><a href="#documentation"><span class="toc-section-number">4.1</span> Documentation</a></li>
24<li><a href="#alternate-syntax"><span class="toc-section-number">4.2</span> Alternate syntax</a></li>
25<li><a href="#copying-a-file"><span class="toc-section-number">4.3</span> Copying a file</a></li>
26<li><a href="#check-and-diff"><span class="toc-section-number">4.4</span> Check and diff</a></li>
27<li><a href="#handlers"><span class="toc-section-number">4.5</span> Handlers</a></li>
28<li><a href="#tags"><span class="toc-section-number">4.6</span> Tags</a></li>
29<li><a href="#limit-to-specific-hosts"><span class="toc-section-number">4.7</span> Limit to specific hosts</a></li>
30<li><a href="#adding-more-plays"><span class="toc-section-number">4.8</span> Adding more &quot;plays&quot;</a></li>
31<li><a href="#host-groups"><span class="toc-section-number">4.9</span> Host groups</a></li>
32<li><a href="#playbook-storage"><span class="toc-section-number">4.10</span> Playbook storage</a></li>
33</ul></li>
34<li><a href="#conclusion"><span class="toc-section-number">5</span> Conclusion</a></li>
35</ul>
36</div>
37<h1 id="objective"><a href="#objective"><span class="header-section-number">1</span> Objective</a></h1>
38<p>In this exercise you will be writing your first Ansible <em>playbooks</em> containing <em>tasks</em></p>
39<h1 id="setup"><a href="#setup"><span class="header-section-number">2</span> Setup</a></h1>
40<p>Make sure you are logged into your master ansible machine over SSH with agent forwarding enabled. You should be logged in as your normal non-root user (&quot;sysadm&quot;).</p>
41<p>Also make sure that from this host, ansible is able to login as root to all the other machines you are managing. To test this:</p>
42<pre><code>ansible all -m shell -a id</code></pre>
43<p>You should get a response like this:</p>
44<pre><code>hostXXX.ws.nsrc.org | success | rc=0 &gt;&gt;
45uid=0(root) gid=0(root) groups=0(root)</code></pre>
46<p>This shows that the login was successful (return code zero = OK) and that when the command &quot;id&quot; was run on the remote machines, it was running as user &quot;root&quot;.</p>
47<h1 id="writing-a-playbook"><a href="#writing-a-playbook"><span class="header-section-number">3</span> Writing a playbook</a></h1>
48<p>A playbook comprises of a list of hosts and tasks entries, like this:</p>
49<pre><code>- hosts: ...
50  tasks: ...
51- hosts: ...
52  tasks: ...
53- hosts: ...
54  tasks: ...</code></pre>
55<p>In each section, you define a set of task(s) to be run on a set of host(s). The playbook is run in sequence, although the same task can run on multiple hosts in parallel.</p>
56<h2 id="creating-a-first-playbook"><a href="#creating-a-first-playbook"><span class="header-section-number">3.1</span> Creating a first playbook</a></h2>
57<p>You will do the following as the &quot;sysadm&quot; user. Check you are in your home directory:</p>
58<pre><code>pwd   # should show /home/sysadm</code></pre>
59<p>If necessary, use &quot;cd&quot; to change to the right directory.</p>
60<p>Now use a text editor of your choice to create a file &quot;first.yml&quot;</p>
61<p>The contents of this file should look like this:</p>
62<pre><code>- hosts:
63    - all
64  tasks:
65    - action: ping</code></pre>
66<p>Now run the playbook like this:</p>
67<pre><code>ansible-playbook first.yml</code></pre>
68<p>Did it work? The output should have these sections:</p>
69<dl>
70<dt><code>GATHERING FACTS</code></dt>
71<dd><p>This is when the &quot;setup&quot; module is being run to collect information about the hosts you are connecting to</p>
72</dd>
73<dt><code>TASK: ping</code></dt>
74<dd><p>The task you defined in the playbook</p>
75</dd>
76<dt><code>PLAY RECAP</code></dt>
77<dd><p>Summarises which tasks were run, how many were success or failure, and how many changes were made</p>
78</dd>
79</dl>
80<p>So far your playbook is essentially doing what you did using the ansible command-line tool.</p>
81<p>(If you get bored of the cows, you can either uninstall the <code>cowsay</code> package, or uncomment <code>nocows = 1</code> in <code>/etc/ansible/ansible.cfg</code>)</p>
82<h1 id="web-server-example"><a href="#web-server-example"><span class="header-section-number">4</span> Web server example</a></h1>
83<p>To make a more realistic example, let's install a webserver (apache2) on two of your hosts.</p>
84<p>Create web.yml which looks like this:</p>
85<pre><code>- hosts:
86    - hostXXX.ws.nsrc.org
87    - hostYYY.ws.nsrc.org
88  tasks:
89    - action: apt update_cache=yes cache_valid_time=3600
90    - action: apt pkg=apache2 state=present</code></pre>
91<p>Replace hostXXX and hostYYY with two of the hosts you are managing; they must exist in your inventory.</p>
92<p>Run it (note that it may be slow the first time).</p>
93<pre><code>ansible-playbook web.yml</code></pre>
94<p>Did it work? Take a note of the &quot;ok&quot; and &quot;changed&quot; values.</p>
95<p>Run it again:</p>
96<pre><code>ansible-playbook web.yml</code></pre>
97<p>How do the &quot;ok&quot; and &quot;changed&quot; values look now?</p>
98<p>Explanation: there are two tasks involving the apt module. One updates the cache of available packages (like &quot;apt-get update&quot;) and the other ensures that apache2 is installed.</p>
99<p>At this point, a webserver should be running on both of those hosts. Test it by pointing your laptop's web browser to hostXXX.ws.nsrc.org and hostYYY.ws.nsrc.org</p>
100<p>You should see &quot;Apache2 Ubuntu Default Page&quot;</p>
101<h2 id="documentation"><a href="#documentation"><span class="header-section-number">4.1</span> Documentation</a></h2>
102<p>It would be helpful if the playbook could be self-documenting, so edit web.yml so it now looks like this:</p>
103<pre><code>- hosts:
104    - hostXXX.ws.nsrc.org
105    - hostYYY.ws.nsrc.org
106  tasks:
107    - name: ensure package cache is up to date
108      action: apt update_cache=yes cache_valid_time=3600
109    - name: install web server
110      action: apt pkg=apache2 state=present</code></pre>
111<p>Run it again. You should get more helpful TASK descriptions as it runs.</p>
112<h2 id="alternate-syntax"><a href="#alternate-syntax"><span class="header-section-number">4.2</span> Alternate syntax</a></h2>
113<p>As a shortcut, instead of writing</p>
114<pre><code>action: foo ....</code></pre>
115<p>you can write</p>
116<pre><code>foo: ....</code></pre>
117<p>This means you can slightly simplify that playbook to:</p>
118<pre><code>- hosts:
119    - hostXXX.ws.nsrc.org
120    - hostYYY.ws.nsrc.org
121  tasks:
122    - name: ensure package cache is up to date
123      apt: update_cache=yes cache_valid_time=3600
124    - name: install web server
125      apt: pkg=apache2 state=present</code></pre>
126<p>Which form you prefer is just a personal choice.</p>
127<p>From this point on, learning ansible is really just a case of getting to know the different modules that are available.</p>
128<h2 id="copying-a-file"><a href="#copying-a-file"><span class="header-section-number">4.3</span> Copying a file</a></h2>
129<p>Let's say we want to replace that Ubuntu default web page with our own.</p>
130<p>Still in your sysadm home directory, create a file <code>front.html</code> with some HTML text, e.g.</p>
131<pre><code>&lt;html&gt;
132&lt;head&gt;&lt;title&gt;Hello world&lt;/title&gt;&lt;/head&gt;
133&lt;body&gt;
134This is the page I installed
135&lt;/body&gt;
136&lt;/html&gt;</code></pre>
137<p>Now add a new task to our playbook:</p>
138<pre><code>- hosts:
139    - hostXXX.ws.nsrc.org
140    - hostYYY.ws.nsrc.org
141  tasks:
142    - name: ensure package cache is up to date
143      apt: update_cache=yes cache_valid_time=3600
144    - name: install web server
145      apt: pkg=apache2 state=present
146    - name: install index page
147      copy: src=front.html dest=/var/www/html/index.html backup=yes</code></pre>
148<p>After this has run successfully (check for &quot;changed=1&quot;), point your laptop's web browser at your two hosts and check you have a new index page.</p>
149<p>What about if we wanted to keep the original file? That is what <code>backup=yes</code> is for. If you log in to one of those hosts and look at the contents of that directory, you'll see that the original file is still there but renamed to a name containing its timestamp.</p>
150<pre><code># ls /var/www/html
151index.html  index.html.2015-05-04@13:21~</code></pre>
152<h2 id="check-and-diff"><a href="#check-and-diff"><span class="header-section-number">4.4</span> Check and diff</a></h2>
153<p>Suppose you want to know what changes ansible will make, before it makes them? Two flags are provided for this.</p>
154<ul>
155<li><code>--check</code> will tell you which changes would be made, without actually making them. (Not all modules support this)</li>
156<li><code>--diff</code> shows you the differences between the old and new files</li>
157</ul>
158<p>It is common to use both flags. Try changing the text in front.html, and then running this command:</p>
159<pre><code>ansible-playbook web.yml --check --diff</code></pre>
160<p>It should identify that index.html is going to be updated, and show you the differences.</p>
161<p>Run it again <em>without</em> the <code>--check</code> flag and then it will actually apply the change.</p>
162<h2 id="handlers"><a href="#handlers"><span class="header-section-number">4.5</span> Handlers</a></h2>
163<p>Sometimes when you make a configuration change it's necessary to restart the service. Ansible supports this though &quot;handlers&quot;.</p>
164<p>Imagine that whenever the index.html page changes you need to restart apache (although that's not actually true). You add a &quot;notify:&quot; statement to every action which needs the restart, and a &quot;handler:&quot; which performs the restart.</p>
165<pre><code>- hosts:
166    - hostXXX.ws.nsrc.org
167    - hostYYY.ws.nsrc.org
168  tasks:
169    - name: ensure package cache is up to date
170      apt: update_cache=yes cache_valid_time=3600
171    - name: install web server
172      apt: pkg=apache2 state=present
173    - name: install index page
174      copy: src=front.html dest=/var/www/html/index.html backup=yes
175      notify: restart apache2
176  handlers:
177    - name: restart apache2
178      service: name=apache2 state=restarted</code></pre>
179<p>Run your playbook again, firstly without changing front.html, and then after changing front.html.</p>
180<p>In the latter case you should see</p>
181<pre><code>NOTIFIED: [restart apache2]</code></pre>
182<p>which shows that the handler was triggered.</p>
183<h2 id="tags"><a href="#tags"><span class="header-section-number">4.6</span> Tags</a></h2>
184<p>As your playbook gets bigger, it may get slower to run, and you may wish to run only part of a playbook to bypass the earlier steps. The way to do this is using 'tags'. Example:</p>
185<pre><code>- hosts:
186    - hostXXX.ws.nsrc.org
187    - hostYYY.ws.nsrc.org
188  tasks:
189    - name: ensure package cache is up to date
190      apt: update_cache=yes cache_valid_time=3600
191      tags: install
192    - name: install web server
193      apt: pkg=apache2 state=present
194      tags: install
195    - name: install index page
196      copy: src=front.html dest=/var/www/html/index.html backup=yes
197      tags: configure
198      notify: restart apache2
199  handlers:
200    - name: restart apache2
201      service: name=apache2 state=restarted</code></pre>
202<p>Now try:</p>
203<pre><code>ansible-playbook web.yml -t configure</code></pre>
204<p>and it will run only the task which has been tagged as &quot;configure&quot;. When writing a playbook, you can assign whatever tags make sense to you.</p>
205<h2 id="limit-to-specific-hosts"><a href="#limit-to-specific-hosts"><span class="header-section-number">4.7</span> Limit to specific hosts</a></h2>
206<p>You can also tell the playbook to run against only a single host or a subset of hosts. The way to do this is with the '-l' (limit) option.</p>
207<pre><code>ansible-playbook web.yml -l hostYYY.ws.nsrc.org</code></pre>
208<p>This is particularly useful for testing and staged rollout; but note that the <code>-l</code> flag is only a filter against the hosts already listed in the playbook. It cannot cause the playbook to run against other hosts.</p>
209<p>For example:</p>
210<pre><code>ansible-playbook web.yml -l 'hostYYY.ws.nsrc.org;hostZZZ.ws.nsrc.org'</code></pre>
211<p>will only run those tasks which were already defined to run on either hostYYY or hostZZZ.</p>
212<h2 id="adding-more-plays"><a href="#adding-more-plays"><span class="header-section-number">4.8</span> Adding more &quot;plays&quot;</a></h2>
213<p>A &quot;play&quot; is one group of hosts and tasks, and a playbook can contain multiple instances of these.</p>
214<p>Let's say that in your web application cluster you need another host which is a mysql server. You can include this in the same playbook by adding another play. Add a new section to the end of your web.yml file so that it looks like this:</p>
215<pre><code>- hosts:
216    - hostXXX.ws.nsrc.org
217    - hostYYY.ws.nsrc.org
218  tasks:
219    - name: ensure package cache is up to date
220      apt: update_cache=yes cache_valid_time=3600
221      tags: install
222    - name: install web server
223      apt: pkg=apache2 state=present
224      tags: install
225    - name: install index page
226      copy: src=front.html dest=/var/www/html/index.html backup=yes
227      tags: configure
228      notify: restart apache2
229  handlers:
230    - name: restart apache2
231      service: name=apache2 state=restarted
232
233- hosts:
234    - hostZZZ.ws.nsrc.org
235  tasks:
236    - name: install mysql server
237      apt: pkg=mysql-server state=present</code></pre>
238<p>Run this playbook to confirm that it does what you expect.</p>
239<h2 id="host-groups"><a href="#host-groups"><span class="header-section-number">4.9</span> Host groups</a></h2>
240<p>Finally, a way to make your playbook easier to maintain is to make use of host groups in the inventory.</p>
241<p>Edit your inventory file (<code>/etc/ansible/hosts</code>), remembering you have to use <code>sudo</code> to do this. Divide it into groups by adding group headings surrounded by square brackets, so that it looks like this:</p>
242<pre><code>[app_web]
243hostXXX.ws.nsrc.org ansible_ssh_user=root
244hostYYY.ws.nsrc.org ansible_ssh_user=root
245
246[app_db]
247hostZZZ.ws.nsrc.org ansible_ssh_user=root</code></pre>
248<p>Then you can simplify your playbook by listing the groups instead of the individual hosts:</p>
249<pre><code>- hosts:
250    - app_web
251  tasks:
252    ... as before
253
254- hosts:
255    - app_db
256  tasks:
257    ... as before</code></pre>
258<p>Now test that everything still works:</p>
259<pre><code>ansible-playbook web.yml</code></pre>
260<p>You can also use groups on the command line, e.g.</p>
261<pre><code>ansible app_web -m shell -a 'ls /'</code></pre>
262<h2 id="playbook-storage"><a href="#playbook-storage"><span class="header-section-number">4.10</span> Playbook storage</a></h2>
263<p>Your <code>web.yml</code> file now documents exactly how you built your web servers, and can be used to create additional servers, or rebuild a server if its disk dies.</p>
264<p>This means that it's a valuable asset. You should store it somewhere safe, e.g. in a version control system like subversion or git, or in a backed-up file server.</p>
265<h1 id="conclusion"><a href="#conclusion"><span class="header-section-number">5</span> Conclusion</a></h1>
266<ul>
267<li>A playbook is a list of &quot;hosts&quot; and &quot;tasks&quot; to apply to those hosts, and optionally &quot;handlers&quot; which are tasks run only when notified by another task</li>
268<li>A playbook encapsulates all the logic needed to build and configure a system</li>
269</ul>
270</body>
271</html>