DevOps for Humans - Ansible for Drupal Deployment Victory!

Post on 27-Aug-2014

1.898 views 5 download

Tags:

description

Everyone knows it's a Good Idea™ to use a configuration management system (e.g. Puppet, Chef) to manage your Drupal infrastructure. But many people (myself included) have run into a wall of #wtfmoments when trying to learn the vagaries of traditional CM systems and their vendor-specific syntaxes. In 2012, Ansible was released, enabling normal human beings to manage their servers with an easy, but powerful, CM system that uses YAML (just like Drupal 8!) to define configuration and Jinja2 (very much like Twig!) for templates. Not only that, but Ansible is also an incredibly simple and very flexible Drupal deployment and continuous delivery tool. Learn how you can use Ansible to manage your infrastructure—including local development environments—and stop letting servers and deployments get in the way of development.

Transcript of DevOps for Humans - Ansible for Drupal Deployment Victory!

DEVOPS FOR HUMANSF O R D R U P A L D E P L O Y M E N T V I C T O R Y !

DevOps Track - Thursday, June 5, 2014

2014

Me

• geerlingguy / Jeff Geerling • Senior Application Developer, Mercy • Owner, Midwestern Mac, LLC

Ansible for DevOps

• For sale on LeanPub

• 50% complete

This presentation

1. Drupal deployments are hard

2. Ansible is simple and powerful

3. Ansible is great for Drupal deployments (and a lot more)

In the Beginning…

• Local Dev: MAMP/WAMP/XAMPP

• Deployments: git  pull  &&  drush  updb  

• Plus 15 other manual deployment steps…

• New servers: manual provisioning

http://devopsreactions.tumblr.com/

http://devopsreactions.tumblr.com/

 _______________________________________    /  I  once  had  to  go  to  a  sysadmin  with  a  \  \  bottle  of  whiskey  to  get  a  deploy.        /    -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐                    \      ^__^                    \    (oo)\_______                          (__)\              )\/\                                  ||-­‐-­‐-­‐-­‐w  |                                  ||          ||

@itababy at AnsibleFest NYC, 2014

Managed servers: 1

Managed servers: 1

circa

(Dries)

Managed servers: 50+

UAT

Test

Prod

Managed servers: 50+

UAT

Test

Prod

Dev

Managed servers: 50+

UAT

Test

Prod

circa Dev

The Simsons™ and © Fox and its related companies. All rights reserved.

DevOps

• Solving Modern Problems:

• multi-server infrastructure (beyond LAMP)

• cloud provisioning, auto-scaling

• testable infrastructure

 _______________________________________    /  It  should  take  less  time  to  rebuild  a  \  \  server  than  to  log  in  and  fix  it.          /    -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐                    \      ^__^                    \    (oo)\_______                          (__)\              )\/\                                  ||-­‐-­‐-­‐-­‐w  |                                  ||          ||

http://www.slideshare.net/ItamarHassin/monitordriven-development-using-ansible-34920480

Puppet Chef Salt Ansible

Initial release 2005 2009 2011 2012

Configuration Language DSL Ruby/DSL YAML YAML

Template Language ERB ERB Jinja2 Jinja2

Agentless ✓

Simple ad-hoc task execution ✓ ✓

GitHub ★s* 2,239 2,729 3,531 6,202

*As of 2014/06/02. Just a reference point. Stars don’t mean much in the grand scheme of things ;-)

Current solutions

Puppet Chef Salt Ansible

Initial release 2005 2009 2011 2012

Configuration Language DSL Ruby/DSL YAML YAML

Template Language ERB ERB Jinja2 Jinja2

Agentless ✓

Simple ad-hoc task execution ✓ ✓

GitHub ★s* 2,239 2,729 3,531 6,202

Just like Drupal 8!

Just like Twig!

*As of 2014/06/02. Just a reference point. Stars don’t mean much in the grand scheme of things ;-)

Current solutions

Puppet Chef Salt Ansible

Initial release 2005 2009 2011 2012

Configuration Language DSL Ruby/DSL YAML YAML

Template Language ERB ERB Jinja2 Jinja2

Agentless ✓

Simple ad-hoc task execution ✓ ✓

GitHub ★s* 2,239 2,729 3,531 6,202

Just like Drupal 8!

Just like Twig!

*As of 2014/06/02. Just a reference point. Stars don’t mean much in the grand scheme of things ;-)

#HugOps

Current solutions

Who uses ?

(and me: Server Check.in, Hosted Apache Solr, Midwestern Mac, LLC)

First Steps with

Inventory

Inventory

[lamp]  example.com  ![lamp:vars]  ansible_ssh_user=johndoe  ansible_ssh_port=2222

(save in /etc/ansible/hosts)

Inventory

[lamp]  example.com  ![lamp:vars]  ansible_ssh_user=johndoe  ansible_ssh_port=2222

(save in /etc/ansible/hosts)

Group name

Inventory

[lamp]  example.com  ![lamp:vars]  ansible_ssh_user=johndoe  ansible_ssh_port=2222

(save in /etc/ansible/hosts)

Group nameHosts in group (just one, for now)

Inventory

[lamp]  example.com  ![lamp:vars]  ansible_ssh_user=johndoe  ansible_ssh_port=2222

(save in /etc/ansible/hosts)

Group nameHosts in group (just one, for now)

Variables(for all hosts in group)

Playbook Task

Playbook Task

-­‐  name:  Ensure  Apache  is  installed.      apt:  pkg=apache2  state=latest

Playbook Task

-­‐  name:  Ensure  Apache  is  installed.      apt:  pkg=apache2  state=latest

Documentation

Playbook Task

-­‐  name:  Ensure  Apache  is  installed.      apt:  pkg=apache2  state=latest

Documentation

Module

Playbook Task

-­‐  name:  Ensure  Apache  is  installed.      apt:  pkg=apache2  state=latest

Documentation

ArgumentsModule

Playbook-­‐-­‐-­‐  -­‐  name:  Ensure  Apache/PHP  is  installed.      apt:  "pkg={{  item  }}  state=latest"      with_items:          -­‐  apache2          -­‐  php5-­‐common          -­‐  libapache2-­‐mod-­‐php5          -­‐  php5-­‐cli  !-­‐  name:  Ensure  Apache  is  started.      service:  name=apache2  state=started

(save as web.yml)

Playbook

-­‐-­‐-­‐  -­‐  hosts:  lamp      sudo:  yes  !    tasks:          -­‐  apt:  update_cache=yes  !        -­‐  include:  web.yml

(save as playbook.yml)

Playbook

-­‐-­‐-­‐  -­‐  hosts:  lamp      sudo:  yes  !    tasks:          -­‐  apt:  update_cache=yes  !        -­‐  include:  web.yml

(save as playbook.yml)

Name of group/host defined in inventory

Playbook

-­‐-­‐-­‐  -­‐  hosts:  lamp      sudo:  yes  !    tasks:          -­‐  apt:  update_cache=yes  !        -­‐  include:  web.yml

(save as playbook.yml)

Name of group/host defined in inventory

Include the playbook we created earlier

ansible-­‐playbook run

ansible-­‐playbook run

Ansible ♥ Vagrant

Ansible ♥ Vagrant

• First-class provisioner

• Inside Vagrantfile:

       config.vm.provision  "ansible"  do  |ansible|              ansible.playbook  =  "playbook.yml"              ansible.inventory_path  =  "inventory-­‐vagrant"        end

Deploy Drupal 8 with

-­‐-­‐-­‐  -­‐  hosts:  d8      sudo:  yes  !    pre_tasks:          -­‐  apt:  update_cache=yes          -­‐  apt_repository:  >                  repo='ppa:ondrej/php5-­‐oldstable'  !    roles:          -­‐  geerlingguy.apache          -­‐  geerlingguy.mysql          -­‐  geerlingguy.php          -­‐  geerlingguy.php-­‐mysql          -­‐  geerlingguy.postfix          -­‐  geerlingguy.drupal

-­‐-­‐-­‐  -­‐      !            -­‐          -­‐                  repo='ppa:ondrej/php5-­‐oldstable'!            -­‐          -­‐          -­‐          -­‐          -­‐          -­‐  

(this actually works)

00:03:14 later…

Demo

Ansible Roles• Encapsulation for configuration/tasks

Ansible Roles• Encapsulation for configuration/tasks

Ansible Role

files/

tasks/

handlers/

vars/ meta/

templates/

Drupal Deployment Role

deploy/ roles/ site-deploy/ playbook.yml

Drupal Deployment Role

deploy/ roles/ site-deploy/ playbook.yml

Custom role!'site-deploy'

tasks

-­‐-­‐-­‐  -­‐  name:  Run  drush  commands  to  update  site.      command:  >          drush  -­‐y  {{  item  }}          chdir={{  drupal_core_path  }}      with_items:            -­‐  "cset  system.site  name  '{{  site_name  }}'"          -­‐  "rap  'anonymous'  'search  content'"      notify:  restart  webserver

site-deploy/tasks/main.yml

vars

-­‐-­‐-­‐  site_name:  "Ansible  Deployment"  drupal_core_path:  /var/www/drupal-­‐8.x-­‐dev

site-deploy/vars/main.yml

handlers

-­‐-­‐-­‐  -­‐  name:  restart  webserver      service:  >          name=apache2          state=restarted      sudo:  yes

site-deploy/handlers/main.yml

deploy/ roles/ site-deploy/ playbook.yml

tasks/main.yml vars/main.yml handlers/main.yml

Drupal Deployment Role

deploy/ roles/ site-deploy/ playbook.yml

Drupal Deployment Role

playbook

-­‐-­‐-­‐  -­‐  hosts:  d8      roles:          -­‐  site-­‐deploy

playbook.yml

Demo

Notifications

-­‐  name:  Send  IRC  message.      irc:  >          channel='#drupalcon'          server='chat.freenode.net'          nick='ansible-­‐ninja'          msg={{  irc_message  }}      delegate_to:  127.0.0.1

(also inside playbook.yml)

-­‐-­‐-­‐  -­‐  hosts:  d8      sudo:  yes  !    pre_tasks:          -­‐  apt:  update_cache=yes          -­‐  apt_repository:  >                  repo='ppa:ondrej/php5-­‐oldstable'  !    roles:          -­‐  geerlingguy.apache          -­‐  geerlingguy.mysql          -­‐  geerlingguy.php          -­‐  geerlingguy.php-­‐mysql          -­‐  geerlingguy.postfix          -­‐  geerlingguy.drupal          -­‐  site-­‐deploy

-­‐-­‐-­‐  -­‐  hosts:  d8      sudo:  yes  !    pre_tasks:          -­‐  apt:  update_cache=yes          -­‐  apt_repository:  >                  repo='ppa:ondrej/php5-­‐oldstable'  !    roles:          -­‐  geerlingguy.apache          -­‐  geerlingguy.mysql          -­‐  geerlingguy.php          -­‐  geerlingguy.php-­‐mysql          -­‐  geerlingguy.postfix          -­‐  geerlingguy.drupal          -­‐  site-­‐deploy

Add to provisioningplaybook.yml

reverse-proxy.yml

webserver.yml

database.yml

search.yml

cache.yml

reverse-proxy.yml

webserver.yml

database.yml

search.yml

cache.yml

infrastructure-playbook.yml

-­‐-­‐-­‐  -­‐  hosts:  all      roles:          -­‐  security          -­‐  monitoring          -­‐  fileshare  !-­‐  hosts:  webservers      roles:          -­‐  nginx          -­‐  php          -­‐  drupal  !-­‐  hosts:  database      roles:          -­‐  postgres

for Drupal Deployment Victory!

for Drupal Deployment Victory!

• Easy to get started

for Drupal Deployment Victory!

• Easy to get started

• OH: “it works on my machine”

• sysadmin burnout

for Drupal Deployment Victory!

• Easy to get started

• OH: “it works on my machine”

• sysadmin burnout

• You’ll actually enjoy it!

for Drupal Deployment Victory!

• Easy to get started

• OH: “it works on my machine”

• sysadmin burnout

• You’ll actually enjoy it!

• …but BEWARE THE GOLDEN HAMMER!

Things I wanted to cover, but didn’t have time

• Ansible ♥’s:

• Packer

• Docker

• [AWS|DO|Linode|Rackspace|etc.]

Things I wanted to cover, but didn’t have time

• Ansible ♥’s:

• Packer

• Docker

• [AWS|DO|Linode|Rackspace|etc.]

• Delegation, notifications, ad-hoc commands, async commands, rolling updates, prompts, Ansible Vault, wait_for, forks, dynamic inventory, and oh-so-much-more…

Things I wanted to cover, but didn’t have time

• Download Ansible

• Automate!

• Buy my book :)

Things you will do now:

WHAT DID YOU THINK?E VA LUAT E T H I S S E S S I O N :

A U S T I N 2 0 1 4 . D R U PA L . O R G / S C H E D U L E

Thank you!

2014