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

Streamlined local development with Vagrant and Ansible - Drukwerkdeal

Streamlined local development with Vagrant and Ansible - Drukwerkdeal

Slides for my Vagrant & Ansible talk at Drukwerkdeal.

Thijs Feryn

May 29, 2015
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. •Environment per project •Dev ~= Test ~= Staging ~= Prod

    •Easy to define & transport •Easy to tear down •Provisionable: infrastructure as code •Versionable •Shared across the team
  2. •Select base box •Choose virtualization provider •Configure VM parameters •Configure

    networking •Tweak SSH settings •Mount local folders •Provision machine What does a Vagrantfile do?
  3. Vagrant.configure(2)  do  |config|            config.vm.box  =

     "ubuntu/trusty64"            config.vm.network  "forwarded_port",  guest:  80,  host:  8080      config.vm.network  "private_network",  ip:  "192.168.33.10"      config.vm.network  "public_network"      config.vm.synced_folder  "./www",  "/var/www"      config.vm.provider  "virtualbox"  do  |vb|          vb.memory  =  "1024"          vb.cpus  =  "4"        end      config.vm.provision  "ansible"  do  |ansible|                  ansible.playbook  =  "ansible/playbook.yml"      end   end
  4. Manage boxes $  vagrant  box  add  hashicorp/precise64   $  vagrant

     box  add  precise32  http:// files.vagrantup.com/precise32.box  -­‐-­‐provider   virtualbox   $  vagrant  box  list   $  vagrant  box  remove  hashicorp/precise64   $  vagrant  box  repackage  precise32  virtualbox  0   $  vagrant  box  outdated   $  vagrant  box  update   $  vagrant  package
  5. Vagrant.configure("2")  do  |config|      config.vm.box  =  "ubuntu/trusty64"   end

    Vagrantfile can do this too Vagrant.configure("2")  do  |config|      config.vm.box  =  "precise32"      config.vm.box_url  =  "http:// files.vagrantup.com/precise32.box"       end URL for self-hosted boxes
  6. •Passwordless login •SSH keys •Generated on vagrant up •Private key

    in .vagrant folder of your project •Public key in authorized_keys file for vagrant user
  7. vagrant ssh-config Host  default      HostName  127.0.0.1    

     User  vagrant      Port  2202      UserKnownHostsFile  /dev/null      StrictHostKeyChecking  no      PasswordAuthentication  no      IdentityFile  /Users/thijs/Sites/ vagrantup/.vagrant/machines/default/ virtualbox/private_key      IdentitiesOnly  yes      LogLevel  FATAL
  8. Vagrant.configure(2)  do  |config|            config.vm.box  =

     "ubuntu/trusty64"            config.vm.network  "forwarded_port",  guest:  80,  host:  8080      config.vm.network  "private_network",  ip:  "192.168.33.10"      config.vm.network  "public_network"   end Networking
  9. Vagrant.configure(2)  do  |config|            config.vm.box  =

     "ubuntu/trusty64"            config.vm.network  "forwarded_port",  guest:  80,  host:  8080      config.vm.network  "private_network",  ip:  "192.168.33.10"      config.vm.network  “public_network"      config.vm.synced_folder  "./www",  "/var/www"   end Synced folders
  10. Vagrant.configure(2)  do  |config|            config.vm.box  =

     "ubuntu/trusty64"            config.vm.network  "forwarded_port",  guest:  80,  host:  8080      config.vm.network  "private_network",  ip:  "192.168.33.10"      config.vm.network  "public_network"      config.vm.synced_folder  "./www",  "/var/www"      config.vm.provider  "virtualbox"  do  |vb|          vb.memory  =  "1024"          vb.cpus  =  "4"        end   end VM properties
  11. •File •Shell •Ansible •Cfengine •Chef Solo •Chef Zero •Chef Client

    •Chef Apply •Docker •Puppet Apply •Puppet Agent •Salt Provisioning
  12. •Configuration management •Simple/lightweight •Yaml •Config > code •Written in Python

    •Standalone/agentless •Pushes commands over SSH •Lots of modules •Lots of public “roles”
  13. Vagrant.configure(2)  do  |config|            config.vm.box  =

     "ubuntu/trusty64"            config.vm.network  "forwarded_port",  guest:  80,  host:  8080      config.vm.network  "private_network",  ip:  "192.168.33.10"      config.vm.network  "public_network"      config.vm.synced_folder  "./www",  "/var/www"      config.vm.provider  "virtualbox"  do  |vb|          vb.memory  =  "1024"          vb.cpus  =  "4"        end      config.vm.provision  "ansible"  do  |ansible|                  ansible.playbook  =  "ansible/playbook.yml"      end   end Ansible provisioning in Vagrant
  14. -­‐-­‐-­‐   -­‐  hosts:  all      vars:    

         docroot:  /vagrant/www          servername:  mysite.dev      sudo:  yes      tasks:      -­‐  name:  ensure  nginx  is  at  the  latest  version          apt:  pkg=nginx  state=latest      -­‐  name:  write  the  nginx  config  file          template:  src=mysite.conf.j2  dest=/etc/nginx/sites-­‐ enabled/mysite.conf          notify:          -­‐  restart  nginx      -­‐  name:  ensure  nginx  is  running  (and  enable  it  at  boot)          service:  name=nginx  state=started  enabled=yes      handlers:          -­‐  name:  restart  nginx              service:  name=nginx  state=restarted Simple playbook example
  15. -­‐-­‐-­‐   -­‐  hosts:  all      vars:    

         docroot:  /vagrant/www          servername:  mysite.dev      sudo:  yes      tasks:      -­‐  name:  ensure  nginx  is  at  the  latest  version          apt:  pkg=nginx  state=latest      -­‐  name:  write  the  nginx  config  file          template:  src=mysite.conf.j2  dest=/etc/nginx/sites-­‐ enabled/mysite.conf          notify:          -­‐  restart  nginx      -­‐  name:  ensure  nginx  is  running  (and  enable  it  at  boot)          service:  name=nginx  state=started  enabled=yes      handlers:          -­‐  name:  restart  nginx              service:  name=nginx  state=restarted
  16. -­‐group_vars      all.yml      webservers.yml      databases.yml

      -­‐host_vars      webserver001.yml      webserver002.yml      database001.yml      database002.yml   -­‐playbook.yml   -­‐common.yml   -­‐roles      nginx      mysql Directory layout Variables per group or for all groups Variables per host Main playbook Included playbook Modularized playbooks
  17. -­‐-­‐-­‐   -­‐  hosts:  webservers      pre_tasks:    

         -­‐  shell:  echo  'hello'      roles:          -­‐  nginx      tasks:          -­‐  shell:  echo  'still  busy'      post_tasks:          -­‐  shell:  echo  'goodbye' -­‐-­‐-­‐   -­‐  hosts:  databases      pre_tasks:          -­‐  shell:  echo  'hello'      roles:          -­‐  mysql      tasks:          -­‐  shell:  echo  'still  busy'      post_tasks:          -­‐  shell:  echo  'goodbye' -­‐-­‐-­‐   -­‐  hosts:  all      tasks:          -­‐  include:  common.yml          -­‐  shell:  echo  'still  busy'   -­‐-­‐-­‐   -­‐  hosts:  webserver001      tasks:          -­‐  shell:  echo  'very  busy'  
  18. Vagrant.configure(2)  do  |config|            config.vm.box  =

     "ubuntu/trusty64"            config.vm.define  "webserver001",  primary:true  do  |ws001|              ws001.vm.hostname  =  "webserver001"              ws001.vm.network  :private_network,  ip:  "192.168.33.10"              ws001.vm.synced_folder  "./www",  "/var/www"                  end            config.vm.define  "webserver002"  do  |ws002|              ws002.vm.hostname  =  "webserver002"              ws002.vm.network  :private_network,  ip:  "192.168.33.11"              ws002.vm.synced_folder  "./www",  "/var/www"                  end                config.vm.define  "database001"  do  |db001|              db001.vm.hostname  =  "database001"              db001.vm.network  :private_network,  ip:  "192.168.33.12"      end            config.vm.define  "database002"  do  |db002|              db002.vm.hostname  =  "database002"              db002.vm.network  :private_network,  ip:  "192.168.33.13"      end            config.vm.provider  "virtualbox"  do  |vb|          vb.memory  =  "512"          vb.cpus  =  "2"        end      config.vm.provision  "ansible"  do  |ansible|                  ansible.playbook  =  "ansible/playbook.yml"                  ansible.groups  =  {                          "webservers"    =>  ["webserver001",  "webserver002"],                          "databases"      =>  ["database001",  "database002"],                                                  "all_groups:children"  =>  ["webservers",  "databases"]                  }      end   end
  19. Inventory $  cat  .vagrant/provisioners/ansible/ inventory/vagrant_ansible_inventory #  Generated  by  Vagrant  

    database001  ansible_ssh_host=127.0.0.1  ansible_ssh_port=2204   database002  ansible_ssh_host=127.0.0.1  ansible_ssh_port=2205   webserver001  ansible_ssh_host=127.0.0.1  ansible_ssh_port=2202   webserver002  ansible_ssh_host=127.0.0.1  ansible_ssh_port=2203   [webservers]   webserver001   webserver002   [databases]   database001   database002   [all_groups:children]   webservers   databases
  20. -­‐-­‐-­‐   -­‐  hosts:  webservers      pre_tasks:    

         -­‐  shell:  echo  'hello'      roles:          -­‐  nginx      tasks:          -­‐  shell:  echo  'still  busy'      post_tasks:          -­‐  shell:  echo  'goodbye' -­‐-­‐-­‐   -­‐  hosts:  databases      pre_tasks:          -­‐  shell:  echo  'hello'      roles:          -­‐  mysql      tasks:          -­‐  shell:  echo  'still  busy'      post_tasks:          -­‐  shell:  echo  'goodbye' -­‐-­‐-­‐   -­‐  hosts:  all      tasks:          -­‐  include:  common.yml          -­‐  shell:  echo  'still  busy'   -­‐-­‐-­‐   -­‐  hosts:  webserver001      tasks:          -­‐  shell:  echo  'very  busy'  
  21. vagrant  up   vagrant  ssh   vagrant  destroy   vagrant

     up  webserver001   vagrant  ssh  webserver001   vagrant  destroy  webserver001   vagrant  up  database001   vagrant  ssh  database001   vagrant  destroy  database001 All VM’s Primary VM All VM’s