/pedantically_commented_playbook.yml
Forked from marktheunissen/pedantically_commented_playbook.yml
Created May 23, 2016
Insanely complete Ansible playbook, showing off all the options
--- | |
# ^^^ YAML documents must begin with the document separator "---" | |
# | |
#### Example docblock, I like to put a descriptive comment at the top of my | |
#### playbooks. | |
# | |
# Overview: Playbook to bootstrap a new host for configuration management. | |
# Applies to: production | |
# Description: | |
# Ensures that a host is configured for management with Ansible. | |
# | |
########### | |
# | |
# | |
# Note: | |
# YAML, like Python, cares about whitespace. Indent consistently throughout. | |
# Be aware! Unlike Python, YAML refuses to allow the tab character for | |
# indentation, so always use spaces. | |
# | |
# Two-space indents feel comfortable to me, but do whatever you like. | |
# vim:ff=unix ts=2 sw=2 ai expandtab | |
# | |
# If you're new to YAML, keep in mind that YAML documents, like XML | |
# documents, represent a tree-like structure of nodes and text. More | |
# familiar with JSON? Think of YAML as a strict and more flexible JSON | |
# with fewer significant characters (e.g., :, "", {}, []) | |
# | |
# The curious may read more about YAML at: | |
# http://www.yaml.org/spec/1.2/spec.html | |
# | |
### | |
# Notice the minus on the line below -- this starts the playbook's record | |
# in the YAML document. Only one playbook is allowed per YAML file. Indent | |
# the body of the playbook. | |
- | |
hosts: all | |
########### | |
# Playbook attribute: hosts | |
# Required: yes | |
# Description: | |
# The name of a host or group of hosts that this playbook should apply to. | |
# | |
## Example values: | |
# hosts: all -- applies to all hosts | |
# hosts: hostname -- apply ONLY to the host 'hostname' | |
# hosts: groupname -- apply to all hosts in groupname | |
# hosts: group1,group2 -- apply to hosts in group1 & group2 | |
# hosts: group1,host1 -- mix and match hosts | |
# hosts: *.mars.nasa.gov wildcard matches work as expected | |
# | |
## Using a variable value for 'hosts' | |
# | |
# You can, in fact, set hosts to a variable, for example: | |
# | |
# hosts: $groups -- apply to all hosts specified in the variable $groups | |
# | |
# This is handy for testing playbooks, running the same playbook against a | |
# staging environment before running it against production, occasional | |
# maintenance tasks, and other cases where you want to run the playbook | |
# against just a few systems rather than a whole group. | |
# | |
# If you set hosts as shown above, then you can specify which hosts to | |
# apply the playbook to on each run as so: | |
# | |
# ansible-playbook playbook.yml --extra-vars="groups=staging" | |
# | |
# Use --extra-vars to set $groups to any combination of groups, hostnames, | |
# or wildcards just like the examples in the previous section. | |
# | |
sudo: True | |
########### | |
# Playbook attribute: sudo | |
# Default: False | |
# Required: no | |
# Description: | |
# If True, always use sudo to run this playbook, just like passing the | |
# --sudo (or -s) flag to ansible or ansible-playbook. | |
user: remoteuser | |
########### | |
# Playbook attribute: user | |
# Default: "root' | |
# Required: no | |
# Description | |
# Remote user to execute the playbook as | |
########### | |
# Playbook attribute: vars | |
# Default: none | |
# Required: no | |
# Description: | |
# Set configuration variables passed to templates & included playbooks | |
# and handlers. See below for examples. | |
vars: | |
color: brown | |
web: | |
memcache: 192.168.1.2 | |
httpd: apache | |
# Tree-like structures work as expected, but be careful to surround | |
# the variable name with ${} when using. | |
# | |
# For this example, ${web.memcache} and ${web.apache} are both usable | |
# variables. | |
######## | |
# The following works in Ansible 0.5 and later, and will set $config_path | |
# "/etc/ntpd.conf" as expected. | |
# | |
# In older versions, $config_path will be set to the string "/etc/$config" | |
# | |
config: ntpd.conf | |
config_path: /etc/$config | |
######## | |
# Variables can be set conditionally. This is actually a tiny snippet | |
# of Python that will get filled in and evaluated during playbook execution. | |
# This expressioun should always evaluate to True or False. | |
# | |
# In this playbook, this will always evaluate to False, because 'color' | |
# is set to 'brown' above. | |
# | |
# When ansible interprets the following, it will first expand $color to | |
# 'brown' and then evaluate 'brown' == 'blue' as a Python expression. | |
is_color_blue: "'$color' == 'blue'" | |
##### | |
# Builtin Variables | |
# | |
# Everything that the 'setup' module provides can be used in the | |
# vars section. Ansible native, Facter, and Ohai facts can all be | |
# used. | |
# | |
# Run the setup module to see what else you can use: | |
# ansible -m setup -i /path/to/hosts.ini host1 | |
main_vhost: ${ansible_fqdn} | |
public_ip: ${ansible_eth0.ipv4.address} | |
# vars_files is better suited for distro-specific settings, however... | |
is_ubuntu: "'${ansible_distribution}' == 'ubuntu'" | |
########## | |
# Playbook attribute: vars_files | |
# Required: no | |
# Description: | |
# Specifies a list of YAML files to load variables from. | |
# | |
# Always evaluated after the 'vars' section, no matter which section | |
# occurs first in the playbook. Examples are below. | |
# | |
# Example YAML for a file to be included by vars_files: | |
# --- | |
# monitored_by: phobos.mars.nasa.gov | |
# fish_sticks: "good with custard" | |
# # (END OF DOCUMENT) | |
# | |
# A 'vars' YAML file represents a list of variables. Don't use playbook | |
# YAML for a 'vars' file. | |
# | |
# Remove the indentation & comments of course, the '---' should be at | |
# the left margin in the variables file. | |
# | |
vars_files: | |
# Include a file from this absolute path | |
- /srv/ansible/vars/vars_file.yml | |
# Include a file from a path relative to this playbook | |
- vars/vars_file.yml | |
# By the way, variables set in 'vars' are available here. | |
- vars/$hostname.yml | |
# It's also possible to pass an array of files, in which case | |
# Ansible will loop over the array and include the first file that | |
# exists. If none exist, ansible-playbook will halt with an error. | |
# | |
# An excellent way to handle platform-specific differences. | |
- [ vars/$platform.yml, vars/default.yml ] | |
# Files in vars_files process in order, so later files can | |
# provide more specific configuration: | |
- [ vars/$host.yml ] | |
# Hey, but if you're doing host-specific variable files, you might | |
# consider setting the variable for a group in your hosts.ini and | |
# adding your host to that group. Just a thought. | |
########## | |
# Playbook attribute: vars_prompt | |
# Required: no | |
# Description: | |
# A list of variables that must be manually input each time this playbook | |
# runs. Used for sensitive data and also things like release numbers that | |
# vary on each deployment. Ansible always prompts for this value, even | |
# if it's passed in through the inventory or --extra-vars. | |
# | |
# The input won't be echoed back to the terminal. Ansible will always | |
# prompt for the variables in vars_prompt, even if they're passed in via | |
# --extra-vars or group variables. | |
# | |
# TODO: I think that the value is supposed to show as a prompt but this | |
# doesn't work in the latest devel | |
# | |
vars_prompt: | |
passphrase: "Please enter the passphrase for the SSL certificate" | |
# Not sensitive, but something that should vary on each playbook run. | |
release_version: "Please enter a release tag" | |
########## | |
# Playbook attribute: tasks | |
# Required: yes | |
# Description: | |
# A list of tasks to perform in this playbook. | |
tasks: | |
########## | |
# The simplest task | |
# Each task must have a name & action. | |
- name: Check that the server's alive | |
action: ping | |
########## | |
# Ansible modules do the work! | |
- name: Enforce permissions on /tmp/secret | |
action: file path=/tmp/secret mode=0600 owner=root group=root | |
# | |
# Format 'action' like above: | |
# <modulename> <module parameters> | |
# | |
# Test your parameters using: | |
# ansible -m <module> -a "<module parameters>" | |
# | |
# Documentation for the stock modules: | |
# http://ansible.github.com/modules.html | |
########## | |
# Use variables in the task! | |
# | |
# Variables expand in both name and action | |
- name: Paint the server $color | |
action: command echo $color | |
########## | |
# Trigger handlers when things change! | |
# | |
# Ansible detects when an action changes something. For example, the | |
# file permissions change, a file's content changed, a package was | |
# just installed (or removed), a user was created (or removed). When | |
# a change is detected, Ansible can optionally notify one or more | |
# Handlers. Handlers can take any action that a Task can. Most | |
# commonly they are used to restart a service when its configuration | |
# changes. See "Handlers" below for more about handlers. | |
# | |
# Handlers are called by their name, which is very human friendly. | |
# This will call the "Restart Apache" handler whenever 'copy' alters | |
# the remote httpd.conf. | |
- name: Update the Apache config | |
action: copy src=httpd.conf dest=/etc/httpd/httpd.conf | |
notify: Restart Apache | |
# Here's how to specify more than one handler | |
- name: Update our app's configuration | |
action: copy src=myapp.conf dest=/etc/myapp/production.conf | |
notify: | |
- Restart Apache | |
- Restart Redis | |
########## | |
# Include tasks from another file! | |
# | |
# Ansible can include a list of tasks from another file. The included file | |
# must represent a list of tasks, which is different than a playbook. | |
# | |
# Task list format: | |
# --- | |
# - name: create user | |
# action: user name=$user color=$color | |
# | |
# - name: add user to group | |
# action: user name=$user groups=$group append=true | |
# # (END OF DOCUMENT) | |
# | |
# A 'tasks' YAML file represents a list of tasks. Don't use playbook | |
# YAML for a 'tasks' file. | |
# | |
# Remove the indentation & comments of course, the '---' should be at | |
# the left margin in the variables file. | |
# In this example $user will be 'sklar' | |
# and $color will be 'red' inside new_user.yml | |
- include: tasks/new_user.yml user=sklar color=red | |
# In this example $user will be 'mosh' | |
# and $color will be 'mauve' inside new_user.yml | |
- include: tasks/new_user.yml user=mosh color=mauve | |
# Variables expand before the include is evaluated: | |
- include: tasks/new_user.yml user=chris color=$color | |
########## | |
# Run a task on each thing in a list! | |
# | |
# Ansible provides a simple loop facility. If 'with_items' is provided for | |
# a task, then the task will be run once for each item in the 'with_items' | |
# list. $item changes each time through the loop. | |
- name: Create a file named $item in /tmp | |
action: command touch /tmp/$item | |
with_items: | |
- tangerine | |
- lemon | |
########## | |
# Choose between files or templates! | |
# | |
# Sometimes you want to choose between local files depending on the | |
# value of the variable. first_available_file checks for each file | |
# and, if the file exists calls the action with $item={filename}. | |
# | |
# Mostly useful for 'template' and 'copy' actions. Only examines local | |
# files. | |
# | |
- name: Template a file | |
action: template src=$item dest=/etc/myapp/foo.conf | |
first_available_file: | |
# ansible_distribution will be "ubuntu", "debian", "rhel5", etc. | |
- templates/myapp/${ansible_distribution}.conf | |
# If we couldn't find a distribution-specific file, use default.conf: | |
- templates/myapp/default.conf | |
########## | |
# Conditionally execute tasks! | |
# | |
# Sometimes you only want to run an action when a under certain conditions. | |
# Ansible will 'only_if' as a Python expression and will only run the | |
# action when the expression evaluates to True. | |
# | |
# If you're trying to run an task only when a value changes, | |
# consider rewriting the task as a handler and using 'notify' (see below). | |
# | |
- name: "shutdown all ubuntu" | |
action: command /sbin/shutdown -t now | |
only_if: "$is_ubuntu" | |
- name: "shutdown the government" | |
action: command /sbin/shutdown -t now | |
only_if: "'$ansible_hostname' == 'the_government'" | |
########## | |
# Notify handlers when things change! | |
# | |
# Each task can optionally have one or more handlers that get called | |
# when the task changes something -- creates a user, updates a file, | |
# etc. | |
# | |
# Handlers have human-readable names and are defined in the 'handlers' | |
# section of a playbook. See below for the definitions of 'Restart nginx' | |
# and 'Restart application' | |
- name: update nginx config | |
action: file src=nginx.conf dest=/etc/nginx/nginx.conf | |
notify: Restart nginx | |
- name: roll out new code | |
action: git repo=git://codeserver/myapp.git dest=/srv/myapp version=HEAD branch=release | |
notify: | |
- Restart nginx | |
- Restart application | |
########## | |
# Run things as other users! | |
# | |
# Each task has an optional 'user' and 'sudo' flag to indicate which | |
# user a task should run as and whether or not to use 'sudo' to switch | |
# to that user. | |
- name: dump all postgres databases | |
action: pg_dumpall -w -f /tmp/backup.psql | |
user: postgres | |
sudo: False | |
########## | |
# Run things locally! | |
# | |
# Each task also has a 'connection' setting to control whether a local | |
# or remote connection is used. The only valid options now are 'local' | |
# or 'paramiko'. 'paramiko' is assumed by the command line tools. | |
# | |
# This can also be set at the top level of the playbook. | |
- name: create tempfile | |
action: dd if=/dev/urandom of=/tmp/random.txt count=100 | |
connection: local | |
########## | |
# Playbook attribute: handlers | |
# Required: no | |
# Description: | |
# Handlers are tasks that run when another task has changed something. | |
# See above for examples. The format is exactly the same as for tasks. | |
# Note that if multiple tasks notify the same handler in a playbook run | |
# that handler will only run once. | |
# | |
# Handlers are referred to by name. They will be run in the order declared | |
# in the playbook. For example: if a task were to notify the | |
# handlers in reverse order like so: | |
# | |
# - task: touch a file | |
# action: file name=/tmp/lock.txt | |
# notify: | |
# - Restart application | |
# - Restart nginx | |
# | |
# The "Restart nginx" handler will still run before the "Restart | |
# application" handler because it is declared first in this playbook. | |
handlers: | |
- name: Restart nginx | |
action: service name=nginx state=restarted | |
# Any module can be used for the handler action | |
- name: Restart application | |
action: command /srv/myapp/restart.sh | |
# It's also possible to include handlers from another file. Structure is | |
# the same as a tasks file, see the tasks section above for an example. | |
- include: handlers/site.yml |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment