Vagrant & ansible

Vagrant låter dig enkelt köra virtuella maskiner på din dator.

1. Installera Virtual Box

Ladda ner och installera virtual box

2. Installera vagrant

osx:
Ladda ner och kör installationsfilen

Windows:
choco install -y vagrant (med Chocolatey)

Officiella instruktioner för att installera vagrant

3. Flytta ditt projekt till en “source” mapp

Skapa en mapp i projektmappen som du förslagsvis kallar för “source” eller “code” och flytta sedan in alla dina kodfiler dit. Då blir det lätt för dig att skilja på filer som används för att få igång miljö..

4. Initiera vagrant i ditt projekt

Kör vagrant init

När den är klar kommer du ha en fil som heter Vagrantfile

efter-vagrant-init

Där finns många exempel på vanliga inställningar du kanske vill göra, och den ser förmodligen ut ungefär såhär:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
  config.vm.box = "base"

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # NOTE: This will enable public access to the opened port
  # config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine and only allow access
  # via 127.0.0.1 to disable public access
  # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # config.vm.network "private_network", ip: "192.168.33.10"

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # config.vm.network "public_network"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  # config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  #
  # View the documentation for the provider you are using for more
  # information on available options.

  # Enable provisioning with a shell script. Additional provisioners such as
  # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   apt-get update
  #   apt-get install -y apache2
  # SHELL
end

Vad är det vi faktiskt behöver? Det beror på vad du har för projekt. Vi börjar med att få upp vad som behövs för att kunna köra elixirprojekt.

Börja med att ta bort det mesta så att du bara har detta kvar:

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
# Documentation: https://docs.vagrantup.com

Vagrant.configure("2") do |config|
  config.vm.box = "debian/jessie64"
end

Om du är nyfiken och vill känna på linuxburken redan nu kan du fortsätta med resterande steg i denna del, annars kan du gå vidare till nästa punkt!

Nu kan du köra $ vagrant up i terminalen, och vänta en stund.

Du har nu en virtuell linuxburk på din dator, med linux versionen (distributionen) debian - version 8 (som kallas för jessie) Det är denna inställning som du kan ändra om du t.ex. hellre vill köra ubuntu:

config.vm.box = "debian/jessie64"

Det finns många alternativ, och de kallas för “boxes”

När “vagrant up” är klar kan du skriva $ vagrant ssh för att ssh:a in till maskinen. Om du sedan skriver $cd .. och trycker enter, två gånger, och sedan ls så ser du att du har en komplett debian maskin framför dig.

5. Konfigurera mera!

Du kan följa alla följande steg, eller välja ut de som känns relevanta för just ditt projekt. När du känner dig redo kör du “vagrant up” för att få igång maskinen, och om du vill börja om kan du köra vagrant destroy och sedan köra vagrant up igen.

Välja IP

Precis som vi surfar in på en vanlig hemsida ute på internet, så vill vi kunna surfa in på webbprojekt inne i virtuella maskinen ifrån vanlig webbläsare också. Välj IP, vi tar 192.168.60.84 It’s probably best to use a reserved private subnet like 192.168.0.0/16 or 10.0.0.0/8

config.vm.network "private_network", ip: "192.168.60.84"

Delade mappar

T.ex. config.vm.synced_folder “../source”, “/var/www/amazingproject”, owner: “deployer”, group: “deployer”

Domännamn

config.vm.hostname = “amazingproject.local

Då måste du också peka amazingproject.local i /etc/hosts till ip-numret vi har satt.

vagrant plugin install vagrant-hostsupdater

så läggs en rad till i etc/hosts, efter att du angivit ditt administratörslösenord.

Having to supply a password so the hosts file can be updated gets annoying very quicky so you can give Vagrant sudo rights: $ sudo visudo

Add these lines to the bottom (Keys: Shift+G, i, Ctrl+V, Esc, :wq)

Cmnd_Alias VAGRANT_HOSTS_ADD = /bin/sh -c echo "*" >> /etc/hosts
Cmnd_Alias VAGRANT_HOSTS_REMOVE = /usr/bin/sed -i -e /*/ d /etc/hosts
%staff ALL=(root) NOPASSWD: VAGRANT_HOSTS_ADD, VAGRANT_HOSTS_REMOVE

Om du får fel som detta: There was an error when attempting to rsync a synced folder. Please inspect the error message below for more info.

Host path: /Users/v/Dropbox/code/kottegott/ Guest path: /vagrant Command: “rsync” “–verbose” “–archive” “–delete” “-z” “–copy-links” “–no-owner” “–no-group” “–rsync-path” “sudo rsync” “-e” “ssh -p 2222 -o LogLevel=FATAL -o ControlMaster=auto -o ControlPath=/var/folders/86/ymjxvwl515s3vld0b4dy70tr0000gn/T/ssh.710 -o ControlPersist=10m -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ‘/Users/v/Dropbox/code/kottegott/.vagrant/machines/default/virtualbox/private_key’” “–exclude” “.vagrant/” “/Users/v/Dropbox/code/kottegott/” “vagrant@127.0.0.1:/vagrant” Error: symlink has no referent: “/Users/v/Dropbox/code/kottegott/source/assets/node_modules/phoenix” symlink has no referent: “/Users/tinky/code/project/source/assets/node_modules/phoenix_html” symlink has no referent: “/Users/tinky/code/project/assets/node_modules/phoenix” symlink has no referent: “/Users/tinky/code/project/assets/node_modules/phoenix_html” rsync error: some files could not be transferred (code 23) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-52/rsync/main.c(996) [sender=2.6.9]

Då kan det vara en förvald inställning som spökar: https://stackoverflow.com/questions/48086373/vagrant-error-symlink-has-no-referent

Då kan alltså detta rädda dig: config.vm.synced_folder “.”, “/vagrant”, disabled: true

Annat felmeddelande:

Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

id -u deployer

The error output from the command was:

id: deployer: no such user

aha! Användaren deployer finns ju inte!

Provisionera ( installera mjukvara m.m. )

provisionera burken med shell till en början om du vill göra det enkelt för dig att komma igång: www.vm.provision :shell, :path => “provision.sh”

provision.sh kan t.ex. se ut såhär: …

.. när du känner dig redo så går vi vidare till att provisionera(är detta svenska idag?) med ansible.

Shell

Basic usage När körs provision? Naming provisionersx

Lägg till användare deployer via shell:
$script = <<-SCRIPT
echo "Adding a new user: deployer"
/usr/sbin/useradd -m -s /bin/bash deployer

echo #Adding .ssh folder as deployer"
su -c "mkdir /home/deployer/.ssh" deployer

echo "Initiate empty authorized_keys as deployer"
su -c "touch /home/deployer/.ssh/authorized_keys" deployer

echo '#{public_key}' >> /home/deployer/.ssh/authorized_keys
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: $script
end

Ansible

Installera ansible Du kan köra brew install ansible på osx (står inte med på installationssidan, där rekommenderar de pip för osx) Ansbile - kom igång

Lägg till användare deployer med ansible

Ansible variables - someone wrote about this Ansible variables - docs

WIP

Övrigt

Detta rekommenderas också att du lägger till

config.vbguest.auto_update = true


Komplett konfiguration

De valen innebär att vi byter ut allting i “Vagrantfile” till detta innehåll

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.

Vagrant.configure("2") do |config|
  config.vm.box = "debian/jessie64"
  config.vm.network "private_network", ip: "192.168.60.84"
  config.vm.provision "shell", privileged: false, path: "provision.sh"
end









Om du vill veta mer om varför det här är relevant och intressant kan du läsa mer här

Sample Vagrantfile:

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

    
	## 'www' is an arbitrary identifier for this machine within this file.
	## This is useful when you want the same Vagrant file to control 
	## multiple machines, say when spinning up a cluster of servers.	
	config.vm.define "www" do |www|
		
		## Use Ubuntu 14.04 for the VM's OS. Vagrant will ony download this once. 
		## If anther project uses the same OS, Vagrant will use a cached version.	   
		www.vm.box = "ubuntu/trusty64"
		
		## If you're using the vagrant-hostsupdater plugin, this will also get added
		## to your hosts file
		www.vm.hostname = "bealers-24ways.dev"
        
		## Example of configuring the VM's 'hardware' on-the-fly.
		## Give the VM 2 virtual CPUs
    ## Note: this is specific for VirtualBox, but you could also hav a secion for WMWare
		www.vm.provider :virtualbox do |vb|
			vb.customize ["modifyvm", :id, "--cpus", "2" ]
		end

		## A private link between host & VM
		## Probably best to use a reserved address, 192.168.0.0/16 or 10.0.0.0/8 
    www.vm.network "private_network", ip: "192.168.13.37"
		
		## Map the local parent folder to /var/www/24ways on the VM
    www.vm.synced_folder "../", "/var/www/24ways",
        	owner: "www-data", group: "www-data"
			
		## This script will be executed on the VM, to install things like Apache & PHP
    www.vm.provision :shell, :path => "provision.sh"

    ## Our symlinked Apache VirtualHost doesn't exist when apache is installed
		## this ensures that the config file is picked up later
    www.vm.provision "shell", inline: "service apache2 restart", run: "always"
    
  end

end

Sample provision.sh file

#!/bin/sh

## This file gets executed the first time you do a `vagrant up`, if you want it to
## run again you'll need run `vagrant provision`

## Bash isn't ideal for provisioning but Ansible/Chef/Puppet 
## are not within the scope of this article

## Install all the things
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install --assume-yes php5 php5-mysql php5-cli php5-curl php-apc \
	apache2 libapache2-mod-php5 mysql-client mysql-server supervisor \
	vim ntp bzip2 php-pear

## make www-data use /bin/bash for shell
chsh -s /bin/bash www-data

## Create a directory structure
## (These would probably already exist within your project)
mkdir /var/www/24ways/etc
mkdir /var/www/24ways/code

## Create an Apache vhost
## (This would probably already exist within your project)
echo "<VirtualHost *:80>
ServerName bealers-24ways.dev
DocumentRoot /var/www/24ways/code
<Directory /var/www/24ways/code>
	AllowOverride All
    Allow from All
</Directory>  
</VirtualHost>" > /var/www/24ways/etc/bealers-24ways.dev.conf

## Tell Apache about our vhost
ln -s /var/www/24ways/etc/bealers-24ways.dev.conf /etc/apache2/sites-enabled/bealers-24ways.dev.conf

## Tweak permissions for www-data user
chgrp www-data /var/log/apache2
chmod g+w /var/log/apache2
chown www-data.www-data /var/www/24ways/etc
chown www-data.www-data /var/www/24ways/code

## Enable Apache's mod-rewrite, if it's not already
a2enmod rewrite

## Disable the default sites 
a2dissite 000-default

## Configure PHP for dev
echo "upload_max_filesize = 15M
log_errors = On
display_errors = On
display_startup_errors = On
error_log = /var/log/apache2/php.log
memory_limit = 1024M
date.timezone = Europe/London" > /etc/php5/mods-available/siftware.ini

php5enmod siftware

## Restart Apache
service apache2 reload

## Create a database and grant a user some permissions
echo "create database bealers_24ways;" | mysql -u root
echo "grant all on bealers_24ways.* to bealers_24ways@localhost identified by 'lamepassword';" | mysql -u root

## Install wp-cli
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

mv /home/vagrant/wp-cli.phar /var/www/24ways/wp-cli
chmod +x /var/www/24ways/wp-cli

## Install Wordpress core using wp-cli
/var/www/24ways/wp-cli core download \
	--path=/var/www/24ways/code \
	--force --allow-root
 
rm /var/www/24ways/code/wp-config-sample.php

## Very basic wp-config.php using our recently created MySQL credentials
## Could use wp-cli for this too, but this'll do
echo "<?php 
\$table_prefix = 'foo_';
define('DB_NAME',     'bealers_24ways');
define('DB_USER',     'bealers_24ways');
define('DB_PASSWORD', 'lamepassword');
define('DB_HOST',     'localhost');
define('DB_CHARSET',  'utf8');
define('WPLANG', '' );
if (!defined('ABSPATH')) 
	define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
?>" > /var/www/24ways/code/wp-config.php
  
## Provision Wordpress using wp-cli
/var/www/24ways/wp-cli core install \
	--url='http://bealers-24ways.dev' \
	--path=/var/www/24ways/code \
	--title='Vagrant FTW' \
	--admin_user=admin \
	--admin_password=24ways \
	--admin_email=bealers@example.org \
	--allow-root

## siteurl & home are getting /code appended in wp_options, no idea why
/var/www/24ways/wp-cli option update siteurl 'http://bealers-24ways.dev' \
	--path=/var/www/24ways/code \
	--allow-root

/var/www/24ways/wp-cli option update home 'http://bealers-24ways.dev' \
	--path=/var/www/24ways/code \
	--allow-root

/var/www/24ways/wp-cli option update blogdescription 'Brought to you by 24ways.org' \
	--path=/var/www/24ways/code \
	--allow-root

/var/www/24ways/wp-cli post create \
	--path=/var/www/24ways/code \
	--post_title='What is Vagrant and why should I care?' \
	--post_content='<p>OK, I totally get it now<p>' \
	--post_status=publish \
	--allow-root

Tips om locale (LC_ALL) strular https://www.vagrantup.com/docs/vagrantfile/tips.html#overwrite-host-locale-in-ssh-session

Längst upp i Vagrant-filen

ENV[“LC_ALL”] = “en_US.UTF-8”

Vem ligger bakom denna kurs?

Victoria Wagman som har arbetat som lärare i webbutveckling, och idag arbetar som programmerare hos 46elks.

Detta material byggs upp lite i taget.