Zero Downtime Deployment with Ansible Zero Downtime Deployment with - - PowerPoint PPT Presentation

zero downtime deployment with ansible zero downtime
SMART_READER_LITE
LIVE PREVIEW

Zero Downtime Deployment with Ansible Zero Downtime Deployment with - - PowerPoint PPT Presentation

Zero Downtime Deployment with Ansible Zero Downtime Deployment with Ansible DevOps Pro Moscow 2016 @steinim stein.inge.morisbak@BEKK.no OPEN Slides Slides http://steinim.github.io/slides/devopspro/zero-downtime-ansible/tutorial.html Source


slide-1
SLIDE 1

Zero Downtime Deployment with Ansible Zero Downtime Deployment with Ansible

DevOps Pro Moscow 2016

@steinim stein.inge.morisbak@BEKK.no

OPEN

slide-2
SLIDE 2

Slides Slides

http://steinim.github.io/slides/devopspro/zero-downtime-ansible/tutorial.html

Source code Source code

git@github.com:steinim/zero-downtime-ansible.git

slide-3
SLIDE 3

What's a provisioning framework? What's a provisioning framework?

Automated setup of servers Configuration as code Not immutable (in itself)

slide-4
SLIDE 4

Examples Examples

Create users Install software Generate and manipulate config files Start/stop/restart processes Set up dependencies between operations

slide-5
SLIDE 5

Describe what to do (imperative) Describe what to do (imperative)

#!/bin/bash if $( command -v vim >/dev/null 2>&1 ); then echo "vim is already installed." else apt-get install vim fi if $( grep -Fxq "filetype indent off" /etc/vim/vimrc ); then echo "set filetype indent off is already in /etc/vim/vimrc." else echo "filetype indent off" >> /etc/vim/vimrc # TODO: Do not continue if this fails. fi # TODO: Rollback if something fails.

slide-6
SLIDE 6

Describe state (declarative) Describe state (declarative)

  • name: Ensure installed vim

apt: pkg=vim state=present update_cache=no tags:

  • vim
  • name: set filetype indent off for vim

lineinfile: dest=/etc/vim/vimrc line='filetype indent off' state=present

slide-7
SLIDE 7

Pros Pros

In source control. Self documenting (it's code!). Refactoring. Less differences between environments. Deterministic. Prevents manual steps. Fast and easy to configure up a new environment. Easier to test server setup.

slide-8
SLIDE 8

Cons Cons

Unfamiliar to "old school operators". Operations is unfamiliar to developers. Startup cost. Training Migrating Isn't really immutable

slide-9
SLIDE 9

Ansible Ansible

SSH-based Client only (no server) YAML configuration Push (and pull) Supports more than setup and provisioning: Application deployment Remote command execution

slide-10
SLIDE 10

Bring up the boxes Bring up the boxes

vagrant up

slide-11
SLIDE 11

Layout (convention over configuration) Layout (convention over configuration)

├── ansible.cfg ├── hosts ├── site.yml ├── group_vars │ └── <group name> ├── host_vars │ └── <host name> ├── roles │ ├── <role> │ │ ├── files │ │ └── <file> │ │ └── templates │ │ └── <template>.j2 │ │ ├── handlers │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ ├── vars │ │ │ └── main.yml

slide-12
SLIDE 12

Play! Play!

ansible-playbook site.yml

slide-13
SLIDE 13

Facts Facts

Ansible by default gathers “facts” about the machines under management. These facts can be accessed in Playbooks and in templates.

ansible -m setup app1.local

slide-14
SLIDE 14

The task The task

An app user 'devops', with: Home directory: /home/devops ssh-key A PostgresSQL database. Nginx as a reverse proxy and loadbalancer. An init script installed as a service. Deploy an application that uses the provisioned infrastructure.

slide-15
SLIDE 15
slide-16
SLIDE 16

Help! Help!

http://docs.ansible.com/list_of_all_modules.html

slide-17
SLIDE 17

Task1: Install and configure software Task1: Install and configure software

git checkout start

Modify roles/common/tasks/main.yml. Install Vim. Insert the line 'filetype indent off' in /etc/vim/vimrc

Help: http://docs.ansible.com/apt_module.html http://docs.ansible.com/lineinfile_module.html

slide-18
SLIDE 18

Task1: Solution Task1: Solution

git diff HEAD origin/task1 git checkout task1 # or keep your own solution

slide-19
SLIDE 19

Run it! Run it!

ansible-playbook site.yml --tags vim ProTip: Use '--tags', '--skip-tags', '--limit' and/or 'gather_facts: False' to reduce execution time.

slide-20
SLIDE 20

Progress Progress

Installed software Manipulated files

slide-21
SLIDE 21

Variables Variables

Use variables! → Infrastructure as data. Where should variables be defined? Ansible has very many options. Inventory (./hosts) group_vars and host_vars Playbook (site.yml) Facts (local or server) Command line (as arguments) Access variables from playbooks: "{{ variable }}" http://docs.ansible.com/playbooks_variables.html

slide-22
SLIDE 22

Task2: Create an application user Task2: Create an application user

Create roles/users/tasks/main.yml Home directory: /home/devops ssh-key Use variables! (group_vars)

Help: (.ssh/authorized_keys) http://docs.ansible.com/group_module.html http://docs.ansible.com/user_module.html http://docs.ansible.com/lineinfile_module.html http://docs.ansible.com/playbooks_best_practices.html#group-and-host-variables

git checkout task2_help

slide-23
SLIDE 23

Task2: Solution Task2: Solution

git diff HEAD origin/task2 git checkout task2 # or keep your own solution

slide-24
SLIDE 24

Run it! Run it!

ansible-playbook site.yml --limit appservers --skip-tags vim,java

Try it! Try it!

ssh devops@app1.local

slide-25
SLIDE 25

Progress Progress

Installed software Manipulated files Created a user and set up a ssh-key

slide-26
SLIDE 26

Task3: Install and configure PostgreSQL Task3: Install and configure PostgreSQL

roles/postgresql ├── files │ └── postgresql.conf ├── handlers │ └── main.yml ├── tasks │ ├── main.yml │ └── ... └── templates └── pg_hba.conf.j2

Use variables (group_vars/all and/or group_vars/dbservers). Use handler to restart postgresql upon notification Template: git checkout task3 -- roles/postgresql/templates/pg_hba.conf.j2 Help: (pg_hba.conf.j2) http://docs.ansible.com/template_module.html http://docs.ansible.com/postgresql_user_module.html http://docs.ansible.com/postgresql_db_module.html http://docs.ansible.com/playbooks_intro.html#handlers-running-operations-on-change http://docs.ansible.com/playbooks_best_practices.html#group-and-host-variables

slide-27
SLIDE 27

Task3: Solution Task3: Solution

git diff HEAD origin/task3 git checkout task3 # or keep your own solution

slide-28
SLIDE 28

Run it! Run it!

ansible-playbook site.yml --limit dbservers --tags pg_install

Try it! Try it!

$ vagrant ssh db vagrant@db:~$ psql -d devops -U devops -W devops=> \q

slide-29
SLIDE 29

Progress Progress

Installed software Manipulated files Created a user and set up a ssh-key Installed and configured a database and a db user

slide-30
SLIDE 30

Task4: Deploy! Task4: Deploy!

roles/app ├── files │ └── init.sh ├── tasks │ └── main.yml └── templates └── config.properties.j2

NB! Use variables (./hosts). Set 'serial: 1' for appservers in the playbook (site.yml). Help: http://docs.ansible.com/service_module.html

slide-31
SLIDE 31

Task4: Solution Task4: Solution

git diff HEAD origin/task4 git checkout task4 # or keep your own solution

slide-32
SLIDE 32

Browse to

Run it! Run it!

ansible-playbook site.yml --limit appservers --tags deploy

Try it! Try it!

http://app1.local:1234/

slide-33
SLIDE 33

What just happened? What just happened?

/home/devops ├── config.properties ├── current -> /home/devops/devops_1416228023.jar ├── previous -> /home/devops/devops_1416221573.jar ├── devops_1416221573.jar ├── devops_1416228023.jar └── logs ├── stderr.log └── stdout.log /etc/init.d └── devops

slide-34
SLIDE 34

Progress Progress

Installed software Manipulated files Created a user and set up a ssh-key Installed and configured a database and a db user Deployed an application to two appservers and enabled it as a service

slide-35
SLIDE 35

Task5: Deploy database Task5: Deploy database

roles/db ├── files │ └── migrate_db.sql └── tasks └── main.yml

Help: http://docs.ansible.com/command_module.html

psql -d {{ db.name }} -q -f /tmp/migrate_db.sql become_user: postgres

slide-36
SLIDE 36

Task5: Solution Task5: Solution

git diff HEAD origin/task5 git checkout task5 # or keep your own solution

slide-37
SLIDE 37

Browse to

Run it! Run it!

ansible-playbook site.yml --limit dbservers --tags deploy

Try it! Try it!

$ vagrant ssh db vagrant@db:~$ psql -d devops -U devops -W devops=> \dt devops=> select * from hello; devops=> \q

http://app1.local:1234/

slide-38
SLIDE 38

Progress Progress

Installed software Manipulated files Created a user and set up a ssh-key Installed and configured a database and a db user Deployed an application to two appservers and enabled it as a service Migrated the database schema and fetched data from it through the application

slide-39
SLIDE 39

Task6: Set up proxy Task6: Set up proxy

roles/nginx ├── handlers │ └── main.yml ├── tasks │ ├── config_nginx.yml │ ├── install_nginx.yml │ └── main.yml └── templates └── devops.conf.j2

Help: http://wsgiarea.pocoo.org/jinja/docs/loops.html

slide-40
SLIDE 40

Task6: Solution Task6: Solution

git diff HEAD origin/task6 git checkout task6 # or keep your own solution

slide-41
SLIDE 41

Browse to # refresh me many times

Run it! Run it!

ansible-playbook site.yml --limit proxies --tags nginx

Try it! Try it!

http://proxy.local/

slide-42
SLIDE 42

Progress Progress

Installed software Manipulated files Created a user and set up a ssh-key Installed and configured a database and a db user Deployed an application to two appservers and enabled it as a service Migrated the database schema and fetched data from it through the application Set up a reverse proxy for automatic failover between the two appservers

slide-43
SLIDE 43

The Expand/Contract pattern The Expand/Contract pattern

Expand Contract Add tables Add columns Tweak indexes Remove tables Remove columns Remove/add constraints

slide-44
SLIDE 44
slide-45
SLIDE 45
slide-46
SLIDE 46
slide-47
SLIDE 47
slide-48
SLIDE 48
slide-49
SLIDE 49
slide-50
SLIDE 50

Play time :-) Play time :-)

Suggestions: Change database table name from HELLO to MESSAGES and deploy a new version without downtime. Implement automated rollback.

slide-51
SLIDE 51

I have been playing :-) I have been playing :-)

git checkout play ansible-playbook site.yml --limit appservers,dbservers --tags deploy ansible-playbook site.yml --limit appservers,dbservers --tags rollback

slide-52
SLIDE 52

Thank you! Thank you!

@steinim stein.inge.morisbak@BEKK.no

slide-53
SLIDE 53

Bonus tasks Bonus tasks

slide-54
SLIDE 54

Secrets using Ansible Vault Secrets using Ansible Vault

http://docs.ansible.com/ansible/playbooks_vault.html

slide-55
SLIDE 55

What Can Be Encrypted With Vault? What Can Be Encrypted With Vault?

Any structured data file used by Ansible group_vars/, host_vars/, inventory variables loaded by "include_vars" or "vars_files" variable files passed on the ansible-playbook command line with "-e @file.yml" or "-e @file.json" Also tasks, handlers, and so on arbitrary files, even binary files All will be decrypted on the target host (assuming a valid vault password is supplied when running the play)

slide-56
SLIDE 56

Task7: Put your secrets in the vault Task7: Put your secrets in the vault

ansible-vault create group_vars/vault ansible-playbook site.yml --ask-vault-pass

Help: http://docs.ansible.com/ansible/playbooks_vault.html

slide-57
SLIDE 57

What did we forget? What did we forget?

slide-58
SLIDE 58

To test! To test!

slide-59
SLIDE 59

ServerSpec ServerSpec

http://serverspec.org/ RSpec Tests your servers' actual state SSH access No agent software on your servers Use any configuration management tool The one we have talked about Even manual setup

slide-60
SLIDE 60

What are you waiting for? What are you waiting for?

Describe your existing infrastructure with ServerSpec Use Vagrant and VirtualBox to play around in a "real" environment. Use a provisioning framework to make your tests go green Go live!

slide-61
SLIDE 61

Thank you! Thank you!

@steinim stein.inge.morisbak@BEKK.no