English
Vagrantfiles eficientes - Parte 1 - Mínimo
Emerson Prado - 17/05/2019
- TL;DR
- Pré requisitos
- Muito prazer, Vagrant
- Mínimo necessário para o Vagrant funcionar
- Só isso já funciona?
- E depois?
TL;DR
Se você já sabe usar o Vagrant e sabe o que é um Vagrantfile, talvez você possa pular esta parte dos artigos, e fazer tudo funcionar com o resumo abaixo.
Comece criando um diretório base e um arquivo chamado "Vagrantfile" (com esta grafia exata, inicial maiúscula e sem extensão) neste diretório. Então, inclua as configurações das MVs no Vagrantfile, como no exemplo comentado abaixo:
# Passe um bloco de código para o método Vagrant.configure # Dê um nome ao objeto retornado - Aqui, chamaremos de "config" Vagrant.configure("2") do |config| # Opcionalmente, inclua configurações dentro do bloco global # Serão aplicadas em todas as MVs config.vm.provision "shell" do |shell| shell.inline = 'echo "Provisionando em `date`"' end # Inclua as definições de máquinas virtuais criando um bloco pra cada uma # Informe nomes das MVs como atributo - Os comandos do shell usarão estes # Dê um nome ao objeto retornado - Aqui, chamaremos de "vm" config.vm.define 'vm_1' do |vm| # Dentro de cada bloco, passe as configurações específicas da MV vm.vm.box = "ARTACK/debian-jessie" vm.vm.network "private_network", ip: "192.168.1.2" end # Repita para outras MVs config.vm.define 'vm_2' do |vm| vm.vm.box = "ARTACK/debian-jessie" vm.vm.network "private_network", ip: "192.168.1.3" end config.vm.define 'vm_3' do |vm| vm.vm.box = "centos/7" vm.vm.network "private_network", ip: "192.168.1.4" end end
Então, brinque à vontade, e continue na parte 2.
Pré requisitos
Veja abaixo os conhecimentos necessários para entender esta série de artigos. Na verdade, você só precisa de noções de:
- Virtualização - O que é uma máquina virtual e o que significa alocar recursos de hardware e rede
- Programação
- Conceitos de programação orientada a objeto
Muito prazer, Vagrant
O Vagrant é uma ferramenta poderosíssima que, atuando com um virtualizador como o VirtualBox, permite criar, configurar, iniciar, desligar e apagar várias máquinas virtuais com comandos simples, a partir de um arquivo de configuração (Vagrantfile
). Isso facilita enormemente testes de configurações e softwares.
Se ainda não o conhece, recomendo esta apresentação da documentação oficial.
Esta série de 4 artigos mostra como tornar mais simples e eficiente o trabalho do Vagrant com várias MVs, com variedades de hardware, SO e configurações, sem ter que repetir e/ou alterar trechos do Vagrantfile
o tempo todo.
Mínimo necessário para o Vagrant funcionar
Além de instalar o software necessário - um virtualizador como o VirtualBox, o Ruby, e o próprio Vagrant - você deve criar um diretório para o seu projeto, e desenvolver um Vagrantfile, que é o arquivo de configuração geral do ambiente virtual a ser gerenciado. Também recomendo, muito, o uso de alguma ferramenta de versionamento como o Git.
O Vagrantfile
é o principal componente de um ambiente Vagrant. É ele que informa o Vagrant como as máquinas virtuais devem ser criadas e configuradas.
Uma ótima forma de começar é executar vagrant init
dentro do diretório do projeto. Este comando cria um Vagrantfile
mínimo, com muitos comentários ensinando como escrever as configurações básicas. Recomendo ler o arquivo gerado para ter uma ótima noção. Também recomendo ver a ajuda do comando com vagrant init -h
.
Mas, para realmente dominar a técnica, é interessante criar um Vagrantfile
do zero. O mínimo que o arquivo deve conter é:
- Um bloco contendo
Vagrant.configure("2") do |config|
, ondeconfig
é o objeto de configurações. O Vagrant é um módulo Ruby, eVagrant.configure
é um método que processa as configurações dentro do bloco. - Dentro do bloco
Vagrant.configure
, blocosconfig.vm.define 'nome' do |mv|
, ondemv
é o objeto de máquina virtual, com as configurações de cada máquina virtual.nome
é o que será usado nos comandos do Vagrant no seu shell. - Dentro de cada bloco
vm.define
, as configurações da máquina virtual. O mínimo possível é o nome do box, para o Vagrant baixar e "espelhar" pra criar a máquina virtual. - Opcionalmente, configurações globais, dentro do bloco
Vagrant.configure
e fora dos blocosvm.define
, que valerão para todas as MVs.
Aqui vai um exemplo de Vagrantfile extremamente minimalista, mas já funcional:
Abra seu editor preferido e crie um arquivo chamado Vagrantfile
, com o conteúdo abaixo, no diretório base do seu projeto
Importante: "Vagrantfile" se escreve exatamente assim, com a inicial maiúscula e sem extensão. Caso contrário, o Vagrant simplesmente não encontra o arquivo, e seu ambiente não funcionará.
Vagrant.configure("2") do |config| config.vm.define 'vm_1' do |vm| vm.vm.box = "ARTACK/debian-jessie" end end
Lembrando que Vagrant é um módulo Ruby (guarde bem esta frase), vamos pensar em Ruby: ao passar um bloco ao método Vagrant.configure
, ele devolve um objeto que chamamos de config
. Este objeto agrupa todas as configurações do projeto corrente do Vagrant. Deste objeto, chamamos o método vm.define
, que cria outro objeto, chamado vm
, que conterá as configurações da máquina virtual específica.
Note o nome vm_1
, na criação do objeto da MV. Este nome será o usado nos comandos do Vagrant.
Note também o nome do box: ARTACK/debian-jessie
. É um dos incontáveis disponíveis no repositório do Vagrant. Você pode procurar boxes que te atendam neste repositório - ver SO, configurações de hardware, software pré-instalado, etc. - e simplesmente colocar o nome no atributo vm.box
de uma ou mais máquinas virtuais. O Vagrant cuida do download pra você. Você também pode criar boxes e referenciar os arquivos nesta configuração, mas isto já é outro papo.
Só isso já funciona?
Duvida? Execute vagrant up
no diretório criado e acompanhe as mensagens, que devem se parecer com isso:
$ vagrant up Bringing machine 'vm_1' up with 'virtualbox' provider... ==> vm_1: Importing base box 'ARTACK/debian-jessie'... ... ==> vm_1: Booting VM... ... ==> vm_1: Machine booted and ready! ==> vm_1: Checking for guest additions in VM... ==> vm_1: Mounting shared folders... vm_1: /vagrant =>
Depois, execute vagrant ssh vm_1
. Pronto - você está na máquina virtual criada:
$ vagrant ssh vm_1 ... vagrant@debian:~$
Brinque à vontade. Depois saia com exit
. Se quiser desligar, ativar novamente ou reiniciar a máquina, basta usar vagrant halt vm_1
, vagrant up vm_1
ou vagrant reload vm_1
, respectivamente.
Se, nos seus testes, você arrebentou a máquina, ou se quiser começar de novo, sem problemas. Saia dela normalmente, apague a máquina com vagrant destroy vm_1
e crie novamente com vagrant up vm_1
. Pronto. Máquina virtual novinha em folha, como se nada tivesse acontecido. Quantas vezes quiser.
E depois?
Agora você pode incluir várias outras máquinas virtuais, usando o mesmo box ou boxes diferentes - só especifique o box usado por cada máquina virtual, e o Vagrant cuida do resto - e incluir configurações para cada máquina, e também configurações globais. Exemplo:
Lembre-se: este código com as configurações das MVs vai no seu Vagrantfile
Vagrant.configure("2") do |config| config.vm.provision "shell" do |shell| shell.inline = 'echo "Provisionando em `date`"' end config.vm.define 'vm_1' do |vm| vm.vm.box = "ARTACK/debian-jessie" vm.vm.network "private_network", ip: "192.168.1.2" end config.vm.define 'vm_2' do |vm| vm.vm.box = "ARTACK/debian-jessie" vm.vm.network "private_network", ip: "192.168.1.3" end config.vm.define 'vm_3' do |vm| vm.vm.box = "centos/7" vm.vm.network "private_network", ip: "192.168.1.4" end end
Aqui, as 3 chamadas a vm.define
criam 3 máquinas virtuais, duas com o box já baixado - o Vagrant armazena em disco - e uma com outro box, também do repositório. Dentro de cada definição de MV, uma configuração de IP para uma rede interna (acessível apenas do hospedeiro e das outras MVs do projeto), e uma configuração global para execução de um comando de shell - que só serve para demonstração mesmo.
Você pode incluir várias configurações dentro de cada objeto MV, e elas valerão pra MV específica, ou configurações globais, fora dos blocos vm.define
, que valem para todas as MVs.
Ao subir as máquinas com vagrant up
, você vai ver as mensagens criadas pelo comando shell:
==> vm_X: Importing base box '...'... ... ==> vm_X: Provisionando em <Data/hora>
E, ao final, você pode confirmar os IPs atribuídos "pingando" as máquinas:
$ for IP in 192.168.1.{2..4} ; do ping -c 1 $IP ; done ... --- 192.168.1.2 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms ... --- 192.168.1.3 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms ... --- 192.168.1.4 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms ...
E assim por diante. Leia a documentação e deixe a imaginação voar.
O código já começou a ficar repetitivo. Agora vamos pro artigo 2!