Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ansible workshop

David Bull
September 13, 2017

Ansible workshop

David Bull

September 13, 2017
Tweet

More Decks by David Bull

Other Decks in Technology

Transcript

  1. AGENDA ▸ Introduction ▸ Ad-hoc commands ▸ Playbooks ▸ Testing

    ▸ Git repo for exercises:
 https://github.com/ukdave/ansible-workshop
  2. INTRODUCTION WHAT IS ANSIBLE? ▸ An automation and configuration management

    technology. ▸ Used to provision, deploy, and manage compute infrastructure across cloud, virtual, and physical environments.
  3. INTRODUCTION WHY ANSIBLE? ▸ Human readable automation ▸ No special

    coding skills required ▸ Tasks executed in order ▸ Idempotent ▸ Agentless ▸ Can manage Linux hosts, Windows hosts, and network devices
  4. INTRODUCTION INSTALLING ANSIBLE # Install the epel-release RPM on CentOS

    / RHEL $ sudo yum install ansible # Install on Debian / Ubuntu $ sudo apt-get install ansible # Install on Mac using Homebrew $ brew install ansible
  5. INTRODUCTION INSTALLING ANSIBLE $ ansible --version ansible 2.3.2.0 config file

    = configured module search path = Default w/o overrides python version = 2.7.13
  6. INTRODUCTION ARCHITECTURE ▸ Bundled with over 450 modules: https://docs.ansible.com/ansible/latest/modules_by_category.html ▸

    Cloud ▸ Containers ▸ Databases ▸ Files ▸ Messaging ▸ Monitoring ▸ Network ▸ Notifications ▸ Packaging ▸ Source Control ▸ System ▸ Testing ▸ Utilities ▸ Web Infrastructure
  7. AD-HOC COMMANDS OVERVIEW ▸ Issue one-off commands to your hosts

    ▸ Quick checks that you don’t want to save for later
  8. AD-HOC COMMANDS INVENTORY ▸ Inventory is a collection of hosts

    against which Ansible can work with. ▸ Example: [webservers]
 web1.example.com
 web2.example.com
 
 [dbservers]
 db1.example.com
  9. AD-HOC COMMANDS EXAMPLES # Check all my inventory hosts are

    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
  10. AD-HOC COMMANDS EXERCISE # Clone the ansible-workshop git repository $

    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
  11. PLAYBOOKS VARIABLES ▸ Used as arguments to modules, and in

    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
  12. PLAYBOOKS VARIABLE PRECEDENCE (LEAST TO MOST) 1. role defaults 2.

    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)
  13. PLAYBOOKS KEEPING SECRETS ▸ It’s a good idea to encrypt

    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
  14. PLAYBOOKS TASKS ▸ Playbooks exist to run tasks. ▸ Tasks

    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
  15. PLAYBOOKS TASKS - MORE EXAMPLES - name: Download and extract

    an archive unarchive: src: http://example.com/foo-1.0.tar.gz dest: /opt/ creates: /opt/foo-1.0/foo remote_src: yes
 - name: POST some JSON data to a REST API uri: url: https://example.com/api/things method: POST user: "{{ api_username }}" password: "{{ api_password }}" body: { "name": "foo", "colour": "red" } body_format: json
  16. PLAYBOOKS TASKS - MORE EXAMPLES - name: Create a system

    group group: name=myservice system=yes - name: Create system user user: name: myservice group: myservice shell: /sbin/nologin system: yes createhome: no - name: Install a bunch of packages package: name={{ item }} state=present with_items: - httpd - mysql-server
  17. PLAYBOOKS TASKS - ERROR HANDLING - name: Ingore command failure

    command: /bin/false
 ignore_errors: yes - name: Fail task when the command error output prints FAILED command: /usr/bin/example-command -x -y -z register: command_result failed_when: "'FAILED' in command_result.stderr” - name: Report changed when exit code != 2 command: /usr/bin/example-command -x -y -z register: command_result changed_when: command_result.rc != 2
  18. PLAYBOOKS HANDLERS ▸ Handlers are special tasks that run at

    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
  19. PLAYBOOKS PLAYS ▸ Plays are ordered sets of tasks to

    execute against host selections from your inventory. ▸ A playbook is a file containing one or more plays.
  20. PLAYBOOKS PLAYBOOK EXAMPLE --- - name: install and start apache

    hosts: web vars: http_port: 80 max_clients: 200 become: yes tasks: - name: install httpd package: name=httpd state=present - name: write the apache config file template: src=httpd.conf.j2 dest=/etc/httpd.conf - name: start httpd service: name=httpd state=started enabled=yes
  21. PLAYBOOKS EXERCISE # Change to the exercise2 directory $ cd

    ../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
  22. PLAYBOOKS LIMITING YOUR PLAYBOOKS ▸ It can sometimes be useful

    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
  23. PLAYBOOKS LIMITING YOUR PLAYBOOKS ▸ Tags can be used to

    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
  24. PLAYBOOKS ROLES ▸ Roles are a package of closely related

    Ansible content that can be shared more easily than plays alone. # site.yml
 --- - hosts: webservers roles: - common - apache ./ "## hosts "## site.yml $## roles/ "## common/ % "## defaults/ % "## files/ % "## handlers/ % "## meta/ % "## tasks/ % "## templates/ % $## vars/ $## apache/ "## defaults/ "## files/ "## handlers/ "## meta/ "## tasks/ "## templates/ $## vars/
  25. PLAYBOOKS EXERCISE # Change to the exercise3 directory $ cd

    ../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
  26. PLAYBOOKS EXERCISE (PART 2) # Change to the exercise4 directory

    $ cd ../exercise4 # Update the common role to install and configure NTP. # Add a new role to install and configure HAProxy on lb1. $ cat README.md
  27. TESTING CHECK MODE / DRY RUN ▸ Does not make

    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
  28. TESTING SYNTAX CHECK ▸ Looks for syntax errors in the

    playbook, but doesn’t run anything. ▸ ansible-playbook site.yml -i hosts --syntax-check
  29. TESTING ANSIBLE-LINT ▸ Checks playbooks for practices and behaviour that

    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
  30. TESTING BASIC HEALTH CHECK TASKS ▸ Check the contents of

    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"
  31. TESTING SERVERSPEC ▸ RSpec (ruby) tests for your servers ▸

    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
  32. TESTING SERVERSPEC describe package("httpd") do it { should be_installed }

    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
  33. TESTING EXERCISE # Change to the exercise5 directory $ cd

    ../exercise5 # Use Serverspec to check that NTP, HAProxy, and Apache are # installed and configured correctly. $ cat README.md