DevSecOps

20 out, 2015

Vagrant – as vantagens da virtualização em ambiente local

Publicidade

Olá, pessoal.

Quando conheci a ferramenta, achei realmente engraçado seu nome, uma ferramenta de Vagabundo. Seu nome vem da facilidade em que se cria ambientes diversos de forma rápida e prática.

Para facilitar, todos os exemplos foram colocados neste repositório, e cada branch representa seu tipo de provisionamento.

A proposta é poder criar e configurar ambientes de desenvolvimento leves, reprodutíveis e portáteis.

Mudando sua forma de trabalhar

O download do Vagrant pode ser feito em seu site, e ele possui versões para Mac, Windows e Linux. Afinal, não importa o seu sistema operacional, o que importa é que seu ambiente é o mais próximo possível do ambiente de produção/homologação.

Configurar

A configuração é a mais simples possível: com apenas um arquivo “Vagrantfile“, você descreve o tipo de máquina, a URL da imagem, os softwares que serão instalados em seu ambiente, e as maneiras como deseja ter acesso a essa máquina criando redes internas e externas, além das configurações de IP, hostname, e tudo que envolve um ambiente de aplicações web.

Ambientes iguais

Essa ferramenta acaba com as desculpas de “funciona na minha máquina”, pois o ambiente pode ser atualizado com frequência, e distribuído para toda a equipe.

Nosso primeiro ambiente com Puppet

Vamos iniciar a criação de ambientes, usando duas ferramentas: Puppet e Chef. Ambas oferecem receitas prontas de configurações iniciais para o start do seu projeto, e tanto o PuPHPet como o Chef possuem ótimas integrações com o Vagrant, fazendo com que todo o trabalho de escolher uma imagem, e configurar a partir dela, para depois distribuir, seja poupado.

Então em alguns minutos, eu prometo para você que teremos uma máquina virtual utilizando

  • CentOs
  • NGINX
  • PHP-FPM
  • MySQL
  • MongoDB
  • xDebug
  • MailCatcher

Faça o Download do PuPHPet já gerado por mim ou gere o seu no site PuPHPet.

Coloque na pasta do seu projeto, no meu caso “~/projects/app”, (altere dentro do seu Vagrantfile caso o caminho do seu projeto seja diferente) e execute no terminal:

vagrant up

 

Após isso, aguarde a primeira execução do seu vagrant, enquanto ele faz o download da imagem, configura pela primeira vez seu ambiente com as configurações especificadas no arquivo “puphpet/config.yaml”.

Alguns itens importantes do seu ambiente

Abrindo o arquivo “puphpet/config.yaml”, você irá encontrar algumas informações importantes sobre seu ambiente:

Memoria (1GB)

memory: '1024'

 

CPUs

cpus: '1'

 

Rede privada

private_network: 192.168.10.10

 

MySQL

mysql:
    install: '1'
    root_password: app_pwd
    adminer: '1'
    databases:
        ptUkwSJZgC0x:
            grant:
                - ALL
            name: app_dev
            host: localhost
            user: app_dev
            password: app_dev
            sql_file: ''

 

<strong>MongoDB</strong>
mongodb:
    install: '1'
    settings:
        auth: 1
        port: '27017'
    databases:
        iSWYd6Tv28w5:
            name: app_dev
            user: app_dev
            password: app_dev

 

Provisionamento Puppet

provision:
            puppet:
                manifests_path: puphpet/puppet
                manifest_file: site.pp
                module_path: puphpet/puppet/modules
                options:
                    - '--verbose'
                    - '--hiera_config /vagrant/puphpet/puppet/hiera.yaml'
                    - '--parser future'

 

Agora basta versionar a pasta puphpet e o arquivo VagrantFile e distribua junto ao projeto para todos. Os requisitos mínimos para a sua equipe iniciar serão VirtualBox e Vagrant instalados localmente (Mac, Windows ou Linux).

Observação

Eu prefiro a utilização do Chef, que, como veremos mais abaixo, é na minha opinião consideravelmente mais organizado e rápido, além de ter integrações maiores com ChefServer & AWS (OpsWorks).

Acessando o ambiente

Para acessar seu ambiente, execute:

vagrant up
vagrant ssh

 

Após a primeira inicialização, será automaticamente gerada uma chave privada no diretório puphpet/files/dot/ssh/id_rsa.key.

Essa chave é gerada após seu primeiro start do ambiente.

Custom files

O PuPHPet permite que você altere alguns arquivos do seu ambiente, e as variáveis do próprio sistema operacional, por parte dos Dotfiles.

Você pode colocar arquivos personalizados para seu ambiente, como .bash_aliases, .vimrc, .gitconfig etc., na pasta puphpet/files/dot/.

Durante o lançamento do ambiente vagrant up, ele será automaticamente copiado para o seu ambiente. Pode começar brincando com o .bash_aliases .

Eu sempre deixo alguns atalhos para facilitar o gerenciamento do ambiente:

#All Services
alias restart_all="sudo /etc/init.d/nginx restart & sudo /etc/init.d/php-fpm restart & sudo /etc/init.d/mysql restart & sudo /etc/init.d/mongo restart"

#Singles Services
alias nginx_restart="sudo /etc/init.d/nginx restart;"
alias php-fpm_restart="sudo /etc/init.d/php-fpm restart;"
alias mysql_restart="sudo /etc/init.d/mysql restart;"
alias mongo_restart="sudo /etc/init.d/mongo restart;"

#Logs
##APP
alias app_access_log="sudo tail -f /var/log/nginx/app.dev.access.log"
alias app_error_log="sudo tail -f /var/log/nginx/app.dev.error.log"

##PHP-FPM
alias php-fpm_error="sudo tail -f /var/log/php-fpm/error.log"


##NGINX
alias nginx_log="sudo tail -f /var/log/nginx/error.log"
alias nginx_access="sudo tail -f /var/log/nginx/access.log"

##MYSQL
alias mysql_log="sudo tail -f /var/log/mysql.log"

##MONGO
alias mongo_log="sudo tail -f /var/log/mongodb/mongod.log"

##CRONTAB LOG
alias crontab_log="sudo tail -f /var/log/cron"

 

Scripts personalizados

Você também pode executar o seu próprio código de personalização do ambiente, adicionando-o na pasta /puphpet/exec-always (executa toda vez), e /puphpet/exec-once (apenas uma vez, assim como as pastas de inicialização sempre e apenas uma vez).

Vale lembrar que os arquivos são executados em ordem alfabética, tome cuidado.

Após saber isso tudo, edite o arquivo de hosts do seu computador, e adicione:

192.168.10.10 app.dev

Após salvar, abra o endereço: http://app.dev e veja o seu ambiente prontinho.

Dica: Observe sempre se, ao subir o seu ambiente, todos os serviços estão rodando OK. Basta acessar sua máquina usando vagrant ssh, e depois: /etc/init.d/servico status e verificar se o serviço está rodando ou não.

Shell, o bom e velho

O Vagrant permite a execução do provisionamento por meio de shell script, o que é também bastante simples. Nesse modelo de configuração do Vagrant, iremos configurar uma imagem simples Ubuntu 12.04 LTS 32-bit.

Iniciando nosso ambiente

cd ~/projects/vagrant_shell/;

vagrant init hashicorp/precise32
vagrant up

 

Após essa execução, o vagrant irá fazer o download da imagem na url https://vagrantcloud.com/hashicorp/precise32/version/1/provider/virtualbox.box e importar para o seu VirtualBox.

Vagrantfile

Após isso, iremos editar o arquivo Vagrantfile e adicionar o nosso provisionamento via Shell. Acrescente este trecho após o |config|:

config.vm.provision "shell", path: "tools/provision.sh"

 

Se o seu caso for Windows, pode trocar o provision.sh por algum arquivo .bat ou .ps1. Se quiser manter esse provisionamento em algum servidor, e distribuir apenas a URL, basta trocar o caminho: “tools/provision.sh” pelo endereço do provisionamento “http://url.com.br/provision.sh”.

Agora, vamos criar o diretório tools e o arquivo provision.sh:

mkdir tools/
cd tools;
touch provision.sh

 

Para o provisionamento, vamos acrescentar o conteúdo do arquivo provision.sh:

#UPDATE UBUNTU
sudo apt-get update;
apt-get -f install

#Install Packages
##nginx
sudo apt-get install nginx --yes

##PHP5-FPM
sudo apt-get install php5-fpm php5-cli php5-common php5-curl php5-xdebug php5-gd php5-imagick php5-mcrypt --yes

##MySQL
echo "mysql-server-5.5 mysql-server/root_password password root" | debconf-set-selections
echo "mysql-server-5.5 mysql-server/root_password_again password root" | debconf-set-selections
sudo apt-get -y install mysql-server-5.5

#INSTALL MONGODB
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 --yes
touch /etc/apt/sources.list.d/mongodb.list
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list
sudo apt-get update --yes
sudo apt-get install mongodb-org --yes
sudo service mongod start

 

Para executar essa instalação padrão dos pacotes nginx, mysql-server, php5-fpm e mongodb execute no seu prompt:

vagrant provision

 

Após a execução do provisionamento, entre no seu ambiente e verifique se os serviços já estão todos rodando.

Agora abra o arquivo <strong>Vagrantfile</strong> novamente, e vamos acrescentar as portas necessárias para comunicação dos serviços instalados.
  #NGINX
  config.vm.network "forwarded_port", guest: 80, host: 80

  #MYSQL
  config.vm.network "forwarded_port", guest: 3306, host: 3306

  #MONGODB
  config.vm.network "forwarded_port", guest: 27017, host: 27017

  #PRIVATE NETWORK
  config.vm.network "private_network", ip: "192.168.33.100"

  #SHAREFOLDER DEFAULT NGINX VHOST
  config.vm.synced_folder "./", "/var/www/"

 

Agora, basta solicitar ao vagrant para reiniciar o seu ambiente:

vagrant reload

 

Agora se tudo deu certo, acesse no seu browser: http://192.168.33.100 e pronto, veja seu ambiente nginx pronto para receber sua aplicação web. Veja só:

vagrant-1

Chef

O Vagrant possui integrações com o Vagrant Chef Solo e Chef Client, mas, nesse exemplo, um dica é gerar um arquivo inicial pelo http://rove.io que é um projeto que gera o start inicial baseado nas suas escolhas, bem prático.

Gere o seu pack inicial, e vamos à configuração rápida do arquivo Cheffile.

Cheffile
# encoding: utf-8

site 'http://community.opscode.com/api/v1'

cookbook "apt"
cookbook "php", {}
cookbook "mysql", {}
cookbook "nginx", {}
cookbook "mongodb", {}
cookbook "git", {}

 

A entrada site ‘http://community.opscode.com/api/v1’ define que usaremos as receitas fornecidas pela API do http://www.getchef.com/ e, logo depois, nossos livrinhos de receitas que usaremos, que são o apt, o php, o mysql, nginx mongodb e git.

Vagrantfile

Agora vamos configurar o nosso Vagrantfile:

# encoding: utf-8
# This file originally created at http://rove.io/06d3af5cb4c2ff1ad165f7efa50f20df
# ALTERADO POR JO O VAGNER
# Permalink: http://blog.rivendel.com.br/2014/08/20/vagrant-as-vantagens-da-virtualizacao-em-ambiente-local
# -*- mode: ruby -*-
# vi: set ft=ruby :

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

  config.vm.box = "opscode-ubuntu-12.04_chef-11.4.0"
  config.vm.box_url = "https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_chef-11.4.0.box"
  config.ssh.forward_agent = true

  #NGINX
  config.vm.network "forwarded_port", guest: 80, host: 8080

  #MYSQL
  config.vm.network "forwarded_port", guest: 3306, host: 3308

  #MONGODB
  config.vm.network "forwarded_port", guest: 27017, host: 27017

  #PRIVATE NETWORK
  config.vm.network "private_network", ip: "192.168.33.101"

  #SHAREFOLDER DEFAULT NGINX VHOST
  config.vm.synced_folder "./", "/var/www/"

  config.vm.provision :chef_solo do |chef|
    chef.cookbooks_path = ["cookbooks"]
    chef.add_recipe :apt
    chef.add_recipe 'php'
    chef.add_recipe 'mysql::server'
    chef.add_recipe 'nginx'
    chef.add_recipe 'mongodb::default'
    chef.add_recipe 'git'
    chef.json = {
      :mysql   => {
        :server_root_password   => "app_cheff",
        :server_repl_password   => "app_cheff",
        :server_debian_password => "",
        :service_name           => "mysql",
        :basedir                => "/usr",
        :data_dir               => "/var/lib/mysql",
        :root_group             => "root",
        :mysqladmin_bin         => "/usr/bin/mysqladmin",
        :mysql_bin              => "/usr/bin/mysql",
        :conf_dir               => "/etc/mysql",
        :confd_dir              => "/etc/mysql/conf.d",
        :socket                 => "/var/run/mysqld/mysqld.sock",
        :pid_file               => "/var/run/mysqld/mysqld.pid",
        :grants_path            => "/etc/mysql/grants.sql"
      },
      :nginx   => {
        :dir                => "/etc/nginx",
        :log_dir            => "/var/log/nginx",
        :binary             => "/usr/sbin/nginx",
        :user               => "www-data",
        :init_style         => "runit",
        :pid                => "/var/run/nginx.pid",
        :worker_connections => "1024"
      },
      :mongodb => {
        :dbpath  => "/var/lib/mongodb",
        :logpath => "/var/log/mongodb",
        :port    => "27017"
      },
      :git     => {
        :prefix => "/usr/local"
      }
    }
  end
end

 

É necessário instalar librarian-chef (Ruby), instalado.

sudo apt-get install ruby
sudo apt-get install ruby-dev
sudo apt-get install rubygems
sudo gem install librarian-chef

 

Depois execute a instalação dos cookbooks e inicie seu ambiente

librarian-chef install

 

Após a conclusão do librarian-chef , basta iniciar o seu vagrant pela primeira vez, e aguardar o download da imagem do Ubuntu 12-04 fornecido no Vagrantfile:

vagrant up

 

Após isso, basta acessar seu ambiente no browser http://192.168.33.101.