Share
Embed
Streamlined local development with Vagrant & Ansible - Devtalks 2015
Slides for my Vagrant & Ansible talk at Devtalks 2015 in Cluj Romania
Thijs Feryn PRO
May 13, 2015
Transcript
63 slides
-
•Environment per project •Dev ~= Test ~= Staging ~= Prod
•Easy to define & transport •Easy to tear down •Provisionable: infrastructure as code •Versionable •Shared across the team -
Vagrantfile Vagrant box vagrant up How Vagrant works Provisioning scripts
VM’s on your computer -
•Select base box •Choose virtualization provider •Configure VM parameters •Configure
networking •Tweak SSH settings •Mount local folders •Provision machine What does a Vagrantfile do? -
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 -
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 -
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 -
•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 -
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 -
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 -
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 -
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 -
•File •Shell •Ansible •Cfengine •Chef Solo •Chef Zero •Chef Client
•Chef Apply •Docker •Puppet Apply •Puppet Agent •Salt Provisioning -
•Configuration management •Simple/lightweight •Yaml •Config > code •Written in Python
•Standalone/agentless •Pushes commands over SSH •Lots of modules •Lots of public “roles” -
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 -
-‐-‐-‐ -‐ 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 -
-‐-‐-‐ -‐ 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 -
-‐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 -
-‐-‐-‐ -‐ 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' -
Inventory $ cat .vagrant/provisioners/ansible/ inventory/vagrant_ansible_inventory # Generated by Vagrant
default ansible_ssh_host=127.0.0.1 ansible_ssh_port=2202 -
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 -
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 -
-‐-‐-‐ -‐ 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' -
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