[DevOps] – How to use Vagrant to automate environments ?

Vagrant

https://www.vagrantup.com/

Create and configure lightweight, reproducible, and portable development environments.

 

UP AND RUNNING

$ vagrant init hashicorp/precise64
$ vagrant up

PROJECT SETUP

$ mkdir vagrant_getting_started
$ cd vagrant_getting_started
$ vagrant init 

INSTALLING A BOX

$ vagrant box add hashicorp/precise64

Where hashicordp/precise64 is a image with Ubuntu

Images Catalog : https://atlas.hashicorp.com/boxes/search

USING A BOX

Vagrantfile -> In this file is the place where we make all vagrant configurations. Here we will define all actions, packages, tools, etc …

Obs.: This file is generated automatically by vagrant init command

Vagrant.configure("2") do |config|
    config.vm.box = "hashicorp/precise32"
    config.vm.define :web do |web_config|
        web_config.vm.network "private_network", ip: "192.168.50.10"
    end
end

+ More Options :

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.box_version = "1.1.0" // Version
end
Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.box_url = "http://files.vagrantup.com/precise64.box" // URL
end

UP AND SSH

  • UP:
$ vagrant up
  • SSH:
$ vagrant ssh

Up the image and go inside .

  • EXIT – LOGOUT
vagrant@precise64:~$ logout
Connection to 127.0.0.1 closed.

IMPORTANT : Vagrantfile you see inside the virtual machine is actually the same Vagrantfile that is on your actual host machine. ( vagrant@precise64:~$ ls /vagrant )

COMMANDS

# vagrant reload -> Reload Machine

# vagrant destroy -> Destroy Machine

PROVISIONING

In the part of software provisioning , plus the Puppet , Chef and Salt are popular alternatives. For those who try the most minimalist way , sometimes the configuration of the machines with the shell itself may be sufficient.

Example of a simple configuration using the Vagrantfile :

bootstrap.sh in the same directory as your Vagrantfile:

#!/usr/bin/env bash

apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant /var/www
fi

Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.provision :shell, path: "bootstrap.sh"
end

Also, you can check things before or after and others configurations or steps.

Examples and Options : https://www.vagrantup.com/docs/provisioning/

 PROVISIONING WITH PUPPET

WebSite : https://puppet.com/

Also, you can make the provisioning using puppet. You need create a puppet file, with all data, in the same directory and execute the command inside the vagrant machine:

$ puppet apply /home/vagrant/ myfile.pp

Observations: pp is the extension for puppet files

Important : All files that you will need to use you should put in this directory.

 

Examples of Configuration :

# Command Execution: 

exec { "name":
    command => "command"
}
Example:
exec { "apt-update":
    command => "/usr/bin/apt-get update"
}

# Install package :

package { ["openjdk-7-jre", "tomcat7"]:
    ensure => installed, // To have sure it was installed
    require => Exec["apt-update"] // Before install run 
}
package { 'unzip':
  ensure => installed,
  require => Exec["apt-update"]
}
#ensure : It will validate if the package was really installed
#require : It will execute the command before the installation

# To running services and restarts :

service { "tomcat7":
    ensure => running,
    enable => true,
    hasstatus => true,
    hasrestart => true, 
    require => Package["tomcat7"]
}

# To deploy in Tomcat server :

You file will be example : /vagrant/myapp.war

file { "/var/lib/tomcat7/webapps/myapp.war":
    source => "/vagrant/myapp.war",
    owner => tomcat7,
    group => tomcat7,
    mode => 0644,
    require => Package["tomcat7"],
    notify => Service["tomcat7"]
}

When we run the apply we are using the sudo user. In this situation we want do the deploy with tomcat7 user and group , because this we have :

 owner => tomcat7,
 group => tomcat7,

The to this file access mode is ‘ 0644 ‘ , writing and reading, and execution etc.

notify => Service["tomcat7"] # It will restart the service in the end. 

# Mysql

package { ["openjdk-7-jre", "tomcat7", "mysql-server"]:
    ensure => installed,
    require => Exec["apt-update"]
}

service { "mysql":
    ensure => running,
    enable => true,
    hasstatus => true,
    hasrestart => true,
    require => Package["mysql-server"]
}

# To create the database:

exec { "createdb":
    command => "mysqladmin -uroot create mynamedb",
    unless => "mysql -u root mynamebd",
    path => "/usr/bin",
    require => Service["mysql"]
}

Obs.: If don’t have this database created before, only.

#Run database script after creation.

exec { "mysql-script" :
    command => "Script",
    unless  => "Script for conditional",
    path => "/usr/bin",
    require => Exec["createdb"]
}

# Configuration by environment

file_line { "production":
    file => "/etc/default/tomcat7",
    line => "JAVA_OPTS=\"\$JAVA_OPTS -Dbr.com.myproject.bundle.environment=production\"",
    require => Package["tomcat7"],
    notify => Service["tomcat7"]
}

# Write in the file unless it was wrote before

define file_line($file, $line) {
    exec { "/bin/echo '${line}' >> '${file}'":
        unless => "/bin/grep -qFx '${line}' '${file}'"
    }
}

When finish all configurations. How to apply configurations ?

$ vagrant reload 

$ vagrant ssh 

$ puppet apply /home/vagrant/ myfile.pp

How to run Puppet automatically ?

Vagrant.configure("2") do |config|

    config.vm.box = "hashicorp/precise32"

    config.vm.define :web do |web_config|
        web_config.vm.network "private_network", ip: "192.168.50.10"
        web_config.vm.provision "puppet" do |puppet|
            puppet.manifest_file = "myapp.pp"
        end
    end

end

Now if you execute the command “vagrant up” all provisions will be executed by the puppet.

How to run it in the cloud ? ( AWS for example )

# Install plugin vagrant to connect in the aws : 

vagrant plugin install vagrant-aws

# Do the configurations :

config.vm.provider :aws do |aws, override|
    aws.keypair_name = "mysystem-devops"
    aws.ami = "ami-358c955c"
    aws.security_groups = ['devops-vagrant']

    override.ssh.username = "ubuntu"
    override.ssh.private_key_path = "mysystem-devops.pem"
end

# Install the puppet

# Script to install the puppet – You need create the shell script “installPuppet.sh”

#!/bin/sh
set -e -x

if which puppet > /dev/null ; then
    echo "Puppet is already installed"
    exit 0
fi

export DEBIAN_FRONTEND=noninteractive
wget -qO /tmp/puppetlabs-release-precise.deb https://apt.puppetlabs.com/puppetlabs-release-precise.deb

dpkg -i /tmp/puppetlabs-release-precise.deb
rm /tmp/puppetlabs-release-precise.deb
aptitude update
echo Installing puppet
aptitude install -y puppet
echo "Puppet installed!"

## Puppet in the configuration file.
config.vm.define :web do |web_config|
        web_config.vm.network "private_network", ip: "192.168.50.10"
        web_config.vm.provision "shell", path: "manifests/installPuppet.sh"
        web_config.vm.provision "puppet" do |puppet|
            puppet.manifest_file = "myapp.pp"
        end
        web_config.vm.provider :aws do |aws|
            aws.tags = { 'Name' => 'MySystem (vagrant)'}
        end
    end

# To startup using the plugin :

vagrant up --provider=aws

# All plugins : https://www.vagrantup.com/docs/plugins/

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s