ready to be managed by Ansible $ ansible all -i hosts -m ping # Run the uptime command on all hosts in the web servers group $ ansible webservers -i hosts -m command -a "uptime" # Collect and display the discovered facts for web1 $ ansible web1 -i hosts -m setup # Install Apache on all hosts in the web servers group $ ansible webservers -i hosts -m package -a "name=httpd state=present" -b
git clone https://github.com/ukdave/ansible-workshop $ cd ansible-workshop/exercise1 # Use Vagrant to create some virtual machines $ vagrant up # Check Ansible can connect to the virtual machines $ ansible all -i hosts -m ping # Run some ad-hoc commands $ cat README.md
template files. ▸ Can be used to specify things like file paths, package versions, etc. ▸ Used to account for differences between servers, e.g. only run a particular task on Ubuntu servers. ▸ Variables can come from various sources, including: ▸ inventory file ▸ host_vars files ▸ group_vars files ▸ facts from the setup module, e.g. ansible_distribution
inventory INI or script group vars 3. inventory group_vars/all 4. playbook group_vars/all 5. inventory group_vars/* 6. playbook group_vars/* 7. inventory INI or script host vars 8. inventory host_vars/* 9. playbook host_vars/* 10. host facts 11. play vars 12. play vars_prompt 13. play vars_files 14. role vars (defined in role/vars/main.yml) 15. block vars (only for tasks in block) 16. task vars (only for the task) 17. role (and include_role) params 18. include params 19. include_vars 20. set_facts / registered vars 21. extra vars (always win precedence)
any sensitive information such as usernames and passwords. ▸ ansible-vault is a command-line tool to manage encrypted var files. # Create a new, encrypted file ansible-vault create secrets.yml # Edit an encrypted file ansible-vault edit secrets.yml
combine an action (a module and its arguments) with a name and optionally some other keywords. tasks: - name: add cache dir file: path: /opt/cache state: directory - name: install httpd package: name: httpd state: present - name: restart http service: name: httpd state: restarted
the end of a play if notified by another task. ▸ For example, if a config file is changed, then the task modifying the config file may notify a service restart handler. ▸ This means services can be bounced only if they need to be restarted. tasks: - name: add cache dir file: path: /opt/cache state: directory - name: install httpd package: name: httpd state: present notify: restart httpd handlers: - name: restart httpd service: name: httpd state: restarted
../exercise2 # Rebuild the Vagrant VMs to ensure everything is in a clean state $ vagrant destroy $ vagrant up # Create a playbook that will install Apache on both web servers # and display a custom message. $ cat README.md
to run a playbook against a subset of hosts in the inventory: # Limit the playbook to a single host ansible-playbook site.yml -i hosts -l web1 # Limit the playbook to a group of hosts ansible-playbook site.yml -i hosts -l webservers
run specific parts of a playbook. ▸ Tags can be applied to plays, roles, and tasks. tasks: - package: name={{ item }} state=present with_items: - httpd - memcached tags: - packages - template: src=templates/src.j2 dest=/etc/foo.conf tags: - configuration # Just run the “configuration” tasks ansible-playbook site.yml -i hosts -t configuration
../exercise3 # Rebuild the Vagrant VMs to ensure everything is in a clean state $ vagrant destroy $ vagrant up # Take the list of tasks in the site.yml playbook and split them # into a “common” role and an “apache” role. $ cat README.md
changes, but reports what Ansible thinks it would need to change. ▸ Lets you know if there is any need to deploy to the given system. ▸ Note: Ordinarily scripts and commands don’t run in check mode! ▸ ansible-playbook site.yml -i hosts --check
could potentially be improved, e.g.: ▸ Tasks without names ▸ Using tasks that run when changed instead of using handlers ▸ Executing a command rather than using an Ansible module (e.g. curl instead of uri) ▸ https://github.com/willthames/ansible-lint ▸ brew install ansible-lint ansible-lint site.yml
a web page: tasks: - uri: url=http://localhost return_content=yes register: webpage - fail: msg="service is not happy" when: "'AWESOME' not in webpage.content" ▸ Check the output of a command: tasks: - command: /usr/bin/some-command --parameter value register: cmd_result - assert: that: - "'not ready’ not in cmd_result.stderr" - "'gizmo enabled’ in cmd_result.stdout"
Tests your server’s actual state by executing commands locally, via SSH. ▸ No special software required on target hosts. ▸ Helps with refactoring infrastructure code. ▸ http://serverspec.org
end describe service("httpd") do it { should be_enabled } it { should be_running } end describe port(80) do it { should be_listening } end describe file("/var/www/html/index.html") do its(:content) { should match(/Hello/) } end