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

Ansible workshop

Avatar for David Bull David Bull
September 13, 2017

Ansible workshop

Avatar for David Bull

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