VAGRANT+ANSIBLE

= TRUE


Who, Me?

Mikke Schirén
Developer at Wunderkraut Sweden
(former actor, journalist, whatever)

Worked with Drupal since 4.7

d.o: MiSc , Twitter: mikkdroid

(certified Drupal developer and loves bande dessinée (comics))

advanced

because

it's simple

WE NEED A

CONTROLLED

DEVELOPMENT

ENVIRONMENT


So WHY THE

NEED FOR VAGRANT

AND PUPPET?

MOST COMMON DRUPAL

DEVELOPMENT ENVIRONMENT

(I'm guessing here...)

MOST COMMON DRUPAL

PRODUCTION
ENVIRONMENT

(That we know for a fact)


AND THAT'S NO PROBLEM,

OR?

DEVELOPMENT ENVIRONMENT SHOULD BE LIKE PRODUCTION

AND IT SHOULD

BE EASY TO SETUP


 What we had before 

One Virtual machine that should fit all projects and developers


 Problem

Developers fixing their VMs so it fitted them, or

Developers developed locally  because it was to much work to get the VM to work.

SOLUTION


Easy to setup local enviroment =

  • Vagrant (controlled Virtualbox)
  • And a provisioner

Puppet, CHEF, ANSIBLE, DOCKER?

DOCKER: THE WET DREAM



BUT
most of our developers use...


ANSIBLE

  • Works with our way of working
  • Easier to work with than Puppet (that we used before)
  • Using YML, like D8.
  • Works with Linux and Mac OsX (supposed to work on windows now, but nobody at WK Sweden uses Windows).
  • Ansible manages machines over SSH protocol, no installs needed for ansible on a virtual machine
  • Supports Jinja2 templates.


EXAMPLE


Vagrant + Ansible for Ubuntu and CentOs
using variables

VAGRANTFILE

# Set box_type to "Ubuntu" or "CentOS"
box_type = "Ubuntu"
# box_type = "CentOS"
box_name = "Cache"
box_host = "cache.dev"
box_mem = 3096
box_ip =  "192.168.50.98"


VAGRANTFILE

Vagrant.configure("2")  do |config|
    config.vm.box = box_type == "Ubuntu" ? "ubuntu/trusty64" : "chef/centos-6.5"
    # Disable totally unnecessary default shared folder
    config.vm.synced_folder '.', '/vagrant', :id => 'vagrant-root', :disabled => true
    # Assign this VM to a host only network IP, allowing you to access it
    # via the IP.
    config.vm.network :private_network, ip: box_ip
    config.vm.hostname = box_host
    config.vm.provider "virtualbox" do |v|
        v.name = box_name
        v.customize ["modifyvm", :id, "--memory", box_mem]
        v.customize ["modifyvm", :id, "--cpus", "1"]
    end

    


VAGRANTFILE

    # Provisioning settings.
    config.vm.provision "ansible" do |ansible|
        ansible_distribution = box_type
        ansible.playbook = "provision/site.yml"
        ansible.sudo = true
        ansible.extra_vars = {
          apache_service_http_port: 8081,
          server_hostname: config.vm.hostname,
          drupal_root: share_root + "/web",
          mysql_root_password: "password",
          php_memory_limit: "2048M",
          composer_user: "vagrant",
          composer_user_home: "/home/vagrant",
          box_mem: box_mem,
        }
    end

AND FINAL STUFF

    # The path to the platform
    config.vm.synced_folder vagrant_root, share_root, :nfs => true, :nfs_udp => true

end

ADD SOME MORE EXTRA IF NEEDED

config.vm.provision :shell do |shell|
shell.path = "script.sh"
end

And whatever you could do in the shellscript, like:

  • Create database
  • Add ssh-key
  • Download databasedump


But better to use....



ANSIBLE PLAYBOOK

site.yml
## YAML Template.
---
- hosts: all
  pre_tasks:
    - include: tasks/pre_tasks.yml
  roles:
    - varnish
    - devbox
    - selenium
    - redis
  vars_files:
    - vars/os.yml
  post_tasks:
    - include: tasks/post_tasks.yml


PRETASKS

Example 1

- name: Ensure Python SELinux bindings installed
  yum: name=libselinux-python state=latest update_cache=yes
  when: is_centos

- name: Disable selinux
  selinux: state=disabled
  when: is_centos

Example 2

- name: Update repos
  shell: apt-get update
  when: is_ubuntu

EXAMPLE: APACHE

Example structure

EXAMPLE: APACHE

# tasks file for apache2
- include_vars: "{{ ansible_distribution }}.yml"
- name: Install Apache2
  action: "{{ ansible_pkg_mgr }} name={{ apache_service_name }} state=installed"
- shell: a2enmod rewrite
  notify: restart apache2
  when: is_ubuntu
- file: path=/etc/apache2/sites-enabled/000-default.conf state=absent
  when: is_ubuntu
- template:
    src=vhost.j2
    dest={{ apache_service_conf_dir }}/drupal.conf
    owner=root group=root mode=0644
  notify: restart apache2
  when: apache_service_http
- template:
    src=ports.conf
    dest={{ apache_service_dir }}/ports.conf
    owner=root group=root mode=0644
  notify: restart apache2
  when: apache_service_http

AND MORE

  • Everything in repo
  • Everything version controlled
  • No more local development
  • No more Homebrew, XAMP, WAMP. etc.

NO MORE

"It worked in my enviroment!"


(Or not so much of it)

Tools and links

Whatever fileeditor to edit files

http://docs.vagrantup.com/v2/

http://www.vagrantbox.es/


Example box: 

http://bit.ly/1EQXou6

(https://github.com/nodeone/wkse-vagrantbox)

Made with Slides.com