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

Vagrant and Ansible: A love story

Sebastian
February 05, 2015

Vagrant and Ansible: A love story

My talk "vagrant + ansible: A love story" will introduce the audience not yet familiar with vagrant to this wonderfull tool which aims at "Create[ing] and configur[ing] lightweight, reproducible, and portable development environments". This will include a short overview over the architecture of vagrant and the different use cases. Two different ways of using ansible with vagrant will be discussed together with pro's and con's of both. Best practices of working withvagrant and ansible will be described.

Sebastian

February 05, 2015
Tweet

More Decks by Sebastian

Other Decks in Technology

Transcript

  1. Ansible and Vagrant
    A love story
    AnsibleFest London, 2015
    http://pixabay.com/get/f72f42c0c92d9ee12bc3/1422473642/cloud-600224_1920.jpg
    @Sgoettschkes

    View full-size slide

  2. http://pixabay.com/get/5c603ff58720250803c9/1422648022/forest-438432_1280.jpg

    View full-size slide

  3. http://pixabay.com/get/3489448873097c5aa562/1422648090/apple-195628_1280.jpg

    View full-size slide

  4. “It works on my machine”

    View full-size slide

  5. “It’s all in SETUP.md”

    View full-size slide

  6. Enter vagrant

    View full-size slide

  7. Building blocks
    Configuration
    + Provider
    + Base Boxes
    + Provisioner
    + Plugins
    = Vagrant
    http://pixabay.com/static/uploads/photo/2010/12/10/08/salad-1105_640.jpg

    View full-size slide

  8. Configuration
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7-ansible"
    config.vm.network "private_network", ip: "127.0.0.101"
    config.vm.synced_folder "../", "/srv/workspace"
    config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
    end
    end

    View full-size slide

  9. Base Boxes
    Base Boxes
    ● Image from VM
    ● Provider-specific
    ● Distribution through
    ○ HTTP
    ○ “Atlas”
    http://upload.wikimedia.org/wikipedia/commons/9/91/Shipping_containers_at_Clyde.jpg

    View full-size slide

  10. Provisioners

    View full-size slide

  11. Provisioners

    View full-size slide

  12. Plugins
    # AWS provider
    $ vagrant plugin install vagrant-aws
    # Boxen provisioner
    $ vagrant plugin install ventriloquist
    # Executing on the host
    $ vagrant plugin install vagrant-hostmanager
    # Executing on the guest
    $ vagrant plugin install vagrant-camera

    View full-size slide

  13. Synced folders
    http://upload.wikimedia.org/wikipedia/commons/5/5d/BalticServers_data_center.jpg
    # Vagrantfile
    config.vm.synced_folder
    "~/local/path/to/project", # on host
    "/opt/project" # on guest

    View full-size slide

  14. SSH
    http://pixabay.com/static/uploads/photo/2013/04/08/22/48/tunnel-101976_640.jpg
    $ vagrant ssh
    # or
    $ ssh -p 2222 vagrant@localhost
    # with password “vagrant”

    View full-size slide

  15. Example
    $ tree
    .
    |-- .git
    |-- .vagrant
    |-- playbook.yml
    |-- Vagrantfile

    View full-size slide

  16. Example
    $ cat Vagrantfile
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7-ansible"
    config.vm.network "private_network", ip: "127.0.0.101"
    config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
    end
    end

    View full-size slide

  17. Example
    $ cat Vagrantfile
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7-ansible"
    config.vm.network "private_network", ip: "127.0.0.101"
    config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
    end
    end

    View full-size slide

  18. Example
    $ cat Vagrantfile
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7-ansible"
    config.vm.network "private_network", ip: "127.0.0.101"
    config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
    end
    end

    View full-size slide

  19. Example
    $ cat Vagrantfile
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7-ansible"
    config.vm.network "private_network", ip: "127.0.0.101"
    config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
    end
    end

    View full-size slide

  20. Example
    $ cat playbook.yml
    ---
    hosts: all
    tasks:
    - name: update apt
    apt: update_cache=yes
    - name: install git
    apt: pkg=git state=latest

    View full-size slide

  21. More
    dependencies,
    anyone?
    https://www.dropbox.com/s/xdeyi95buvofdxy/169H.jpg

    View full-size slide

  22. Better example
    $ tree
    .
    |-- .git
    |-- .vagrant
    |-- hosts
    |-- playbook.yml
    |-- Vagrantfile

    View full-size slide

  23. Better example
    $ tree
    .
    |-- .git
    |-- .vagrant
    |-- hosts
    |-- playbook.yml
    |-- Vagrantfile

    View full-size slide

  24. Better example
    $ cat hosts
    localhost ansible_connection=local

    View full-size slide

  25. Better example
    Vagrant.configure(2) do |config|
    # ...
    config.vm.provision "shell",
    inline: "cp /vagrant/hosts /etc/ansible/hosts"
    if Vagrant.has_plugin?("vagrant-ansible-local”)
    config.vm.provision "ansibleLocal", playbook: "playbook.yml"
    else
    config.vm.provision "shell",
    inline: "ansible-playbook /vagrant/playbook.yml"
    end

    View full-size slide

  26. Better example
    Vagrant.configure(2) do |config|
    # ...
    config.vm.provision "shell",
    inline: "cp /vagrant/hosts /etc/ansible/hosts"
    if Vagrant.has_plugin?("vagrant-ansible-local”)
    config.vm.provision "ansibleLocal", playbook: "playbook.yml"
    else
    config.vm.provision "shell",
    inline: "ansible-playbook /vagrant/playbook.yml"
    end

    View full-size slide

  27. Better example
    Vagrant.configure(2) do |config|
    # ...
    config.vm.provision "shell",
    inline: "cp /vagrant/hosts /etc/ansible/hosts"
    if Vagrant.has_plugin?("vagrant-ansible-local”)
    config.vm.provision "ansibleLocal", playbook: "playbook.yml"
    else
    config.vm.provision "shell",
    inline: "ansible-playbook /vagrant/playbook.yml"
    end

    View full-size slide

  28. Better example
    Vagrant.configure(2) do |config|
    # ...
    config.vm.provision "shell",
    inline: "cp /vagrant/hosts /etc/ansible/hosts"
    if Vagrant.has_plugin?("vagrant-ansible-local”)
    config.vm.provision "ansibleLocal", playbook: "playbook.yml"
    else
    config.vm.provision "shell",
    inline: "ansible-playbook /vagrant/playbook.yml"
    end

    View full-size slide

  29. http://freehddesktopwallpaper.info/wp-content/uploads/2013/06/Blue-Flowers-hd-Wallpapers.jpg
    Basic workflow

    View full-size slide

  30. Basic workflow
    $ vagrant init Sgoettschkes/debian7-ansible
    $ vagrant up
    # box is booting
    $ vagrant ssh
    # It’s actually a normal, headless VM!
    $ exit

    View full-size slide

  31. Basic workflow
    $ vim Vagrantfile
    # change config
    # add provisioners and so on
    $ git init
    $ git commit -Am ‘I am using Vagrant now!’
    # Keep the Vagrantfile and files needed for provisioning
    # in git (or any other scm) to share with others

    View full-size slide

  32. Basic workflow
    $ git clone [email protected]:awesomecompany/awesomeVm.git
    $ cd awesomeVm && vagrant up
    # VM is setup the same as on your co-workers machine
    # You can now work on your project

    View full-size slide

  33. Basic workflow
    # Co-worker updated Vagrantfile/provisioning files
    $ git pull --rebase
    $ vagrant provision
    # VM is up to date again

    View full-size slide

  34. Basic workflow
    # You wanna change some Vagrant related stuff
    $ vim Vagrantfile
    # Change it!
    $ vim playbook.yml
    # Change something here as well, maybe?
    $ vagrant provision
    # Your box is up to date again
    $ git commit -am ‘Incredible changes’ && git push

    View full-size slide

  35. http://www.gratisography.com/pictures/114_1.jpg
    Playbook
    testing?

    View full-size slide

  36. Testing playbooks
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7"
    config.vm.define "web1" do |web1|
    web1.vm.network "private_network", ip: "192.168.1.150"
    end
    config.vm.define "db1" do |db1|
    db.vm.network "private_network", ip: "192.168.1.151"
    end
    end

    View full-size slide

  37. Testing playbooks
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7"
    config.vm.define "web1" do |web1|
    web1.vm.network "private_network", ip: "192.168.1.150"
    end
    config.vm.define "db1" do |db1|
    db.vm.network "private_network", ip: "192.168.1.151"
    end
    end

    View full-size slide

  38. Testing playbooks
    Vagrant.configure(2) do |config|
    config.vm.box = "Sgoettschkes/debian7"
    config.vm.define "web1" do |web1|
    web1.vm.network "private_network", ip: "192.168.1.150"
    end
    config.vm.define "db1" do |db1|
    db.vm.network "private_network", ip: "192.168.1.151"
    end
    end

    View full-size slide

  39. Testing playbooks
    $ cat testing
    [webservers]
    192.168.1.150 ansible_ssh_user=vagrant ansible_ssh_private_key=path/to/key
    [dbservers]
    192.168.1.151 ansible_ssh_user=vagrant ansible_ssh_private_key=path/to/key

    View full-size slide

  40. Testing playbooks
    $ cat testing
    [webservers]
    192.168.1.150 ansible_ssh_user=vagrant ansible_ssh_private_key=path/to/key
    [dbservers]
    192.168.1.151 ansible_ssh_user=vagrant ansible_ssh_private_key=path/to/key

    View full-size slide

  41. Testing playbooks
    $ cat testing
    [webservers]
    192.168.1.150 ansible_ssh_user=vagrant ansible_ssh_private_key=path/to/key
    [dbservers]
    192.168.1.151 ansible_ssh_user=vagrant ansible_ssh_private_key=path/to/key

    View full-size slide

  42. Testing playbooks
    $ vagrant destroy --force && vagrant up
    # Now you have freshly setup machines
    # Run your playbooks like you would for staging/production
    $ ansible-playbook -i testing site.yml
    # Maybe run a testscript
    $ ./test_setup.sh

    View full-size slide

  43. https://www.dropbox.com/s/mfmusz1qjotilbs/2H.jpg
    Best practices

    View full-size slide

  44. Base Boxes
    The fewer, the better

    View full-size slide

  45. Provisioning
    Idempotent

    View full-size slide

  46. Provisioning
    One step

    View full-size slide

  47. Provisioning
    # Bad:
    $ vagrant up
    $ install software x
    $ run script y
    $ create z

    View full-size slide

  48. Provisioning
    # Good:
    $ vagrant up

    View full-size slide

  49. Vms per Developer
    The fewer, the better
    (again)

    View full-size slide

  50. http://nos.twnsnd.co/image/108652898544
    What else is
    there?

    View full-size slide

  51. Vagrant share
    $ vagrant share
    # Your VM is now accessible through a public url
    # You can go back doing awesome work!

    View full-size slide

  52. Vagrant push
    config.push.define "ftp" do |push|
    push.dir = "/srv/workspace"
    push.host = "ftp.awesomeCompany.com"
    end

    View full-size slide

  53. Vagrant push
    config.push.define "local-exec" do |push|
    push.script = "deploy.sh"
    end

    View full-size slide

  54. Vagrant
    “Development environments
    made easy”
    http://fc02.deviantart.net/fs50/i/2009/315/4/c/Tweaked_toy_airplane_by_afd.jpg

    View full-size slide

  55. https://www.dropbox.com/s/6z5aiwa8l09g2pa/86H.jpg

    View full-size slide