Skip to content

Vagrant

wizardjedi edited this page Nov 23, 2014 · 5 revisions

http://hsto.org/storage/4da9574a/9546e72a/3e2ee71b/af55a6eb.png

Тёплый ламповый логотип vagrant'а.

Vagrant — это кросс-платформенное средство для развёртывания повторяемых и предсказуемых окружений для разработчиков, QA и админов.

Vagrant фактически является удобным менеджером для запуска виртуальных машин и управления ими. А ещё есть vagrant cloud и vagrant boxes ( https://vagrantcloud.com/ http://www.vagrantbox.es/ ) — это сервис, который хранит образы операционных систем (они называются box'ами) и шаблонов (кстати, можно делать свои и расшаривать их), что позволяет вообще не заморачиваться относительно установки ОС и т.д. в окружении.

В качестве виртуальных машин могут быть:

  • VirtualBox
  • VMWare
  • Docker
  • Hyper-V

А вот в качестве систем развёртывания:

  • Puppet
  • Chef
  • CFEngine
  • Shell
  • Файлы

Единственное, что вам нужно при работе с Vagrant — это указать образ операционной системы, настройки виртуалки (если нужно) и параметры развёртывания (опять же если нужно).

Всё остальное Vagrant сделает за вас. Больше не нужно запускать виртуальную машину, устанавливать и настраивать ОС, ставить SSH, настраивать расшаренные каталоги и форвардинг портов и т.д. Для всего этого уже есть шаблоны.

Для начала Vagrant надо поставить:

$ sudo apt-get update
$ sudo apt-get install vagrant
$ vagrant -v
Vagrant 1.4.3

Vagrant установлен.

Теперь создадим директорию для тестов и развернём первую машину.

$ mkdir vagranttest && cd vagranttest
$ vagrant init

После выполнения vagrant init в директории появляется файл Vagrantfile, который отвечает за развёртывание виртуальной машины. Если откроем его в редакторе, то увидим там много комментариев и параметров. Пока это всё не нужно заменим содержимое Vagrantfile на:

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
     config.vm.box = "debian77"
     config.vm.box_url = "https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box"
end

Пара комментариев и пойдём дальше:

  • config.vm.box = "debian77" - задаёт название для box'а
  • config.vm.box_url = "https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box" — задаёт URL, с которого будет скачан образ для Virtualbox

Теперь просто выполняем команду:

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Box 'debian77' was not found. Fetching box from specified URL for
the provider 'virtualbox'. Note that if the URL does not have
a box for this provider, you should interrupt Vagrant now and add
the box yourself. Otherwise Vagrant will attempt to download the
full box prior to discovering this error.
Downloading box from URL: https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box

Начинается загрузка и разворачивание образа. После загрузки видим следующее:

Extracting box...te: 2401k/s, Estimated time remaining: --:--:--)
Successfully added box 'debian77' with provider 'virtualbox'!
[default] Importing base box 'debian77'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Mounting shared folders...
[default] -- /vagrant

Вот собственно и всё. Образ скачан и развёрнут в Virtualbox.

Чтобы попасть в виртуалку достаточно выполнить комнаду:

$ vagrant ssh
Linux debian-7 3.2.0-4-amd64 #1 SMP Debian 3.2.63-2+deb7u1 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Nov 3 20:34:38 2014 from 10.0.2.2

vagrant@debian-7:~$ uname -a
Linux debian-7 3.2.0-4-amd64 #1 SMP Debian 3.2.63-2+deb7u1 x86_64 GNU/Linux

ну или можно сделать так:

$ vagrant ssh -c 'uname -a'
Linux debian-7 3.2.0-4-amd64 #1 SMP Debian 3.2.63-2+deb7u1 x86_64 GNU/Linux
Connection to 127.0.0.1 closed.

Для того, чтобы выключить машину достаточно выполнить:

$ vagrant halt
[default] Attempting graceful shutdown of VM...

Забегая вперёд скажу, что таким образом Vagrant может запускать не одну машину, а сразу несколько машин. Одну, две, 10, 15 ( https://docs.vagrantup.com/v2/multi-machine/index.html ). Всё это описывается в Vagrantfile, который можно положить в Git-репозиторий проекта и у всех заинтересованных лиц (разрабы, QA, админы) будет возможность быстро развернуть виртуалку или набор виртуалок.

Идём дальше.

У нас есть виртуалка, можно делать разные настройки, быстрый и удобный способ задания образов ОС и т. д. Но это ещё не окружение. Для того, чтобы превратить это в окружение нам необходимо установить некоторый софт. Данный процесс называется provisioning.

Для начала попробуем сделать что-то очень простое, например, установить пакет puppet в виртуальную машину.

Открываем Vagrantfile и добавляем следующие строки (выделено жирным):

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

    config.vm.box = "debian77"
    config.vm.box_url = "https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box"

    config.vm.provision "shell", :inline => <<-SHELL
        apt-get update
        apt-get install -y puppet
    SHELL
end

Пробуем запустить машину. Скачивания образа уже не происходит, а машина просто запускается.

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Clearing any previously set forwarded ports...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Mounting shared folders...
[default] -- /vagrant
[default] VM already provisioned. Run `vagrant provision` or use `--provision` to force it
$ vagrant ssh -c 'puppet -v'
bash: puppet: command not found
Connection to 127.0.0.1 closed.

Команда puppet не установлена, хотя об этом Vagrant нас и предупреждал.

Для того, чтобы запустить provisioning необходимо запускать машину как vagrant up --provision или выполнить vagrant provision.

Попробуем:

$ vagrant provision
[default] Running provisioner: shell...
[default] Running: inline script
stdin: is not a tty
Get:1 http://security.debian.org wheezy/updates Release.gpg [836 B]
Get:2 http://security.debian.org wheezy/updates Release [102 kB]
Hit http://mirrors.kernel.org wheezy Release.gpg
Get:3 http://security.debian.org wheezy/updates/main Sources [139 kB]
Get:4 http://mirrors.kernel.org wheezy-updates Release.gpg [836 B]
Get:5 http://security.debian.org wheezy/updates/main amd64 Packages [222 kB]
Hit http://mirrors.kernel.org wheezy Release
Get:6 http://security.debian.org wheezy/updates/main Translation-en [125 kB]
Get:7 http://mirrors.kernel.org wheezy-updates Release [124 kB]
Hit http://mirrors.kernel.org wheezy/main Sources
Hit http://mirrors.kernel.org wheezy/main amd64 Packages
Hit http://mirrors.kernel.org wheezy/main Translation-en
Get:8 http://mirrors.kernel.org wheezy-updates/main Sources [14 B]
Hit http://mirrors.kernel.org wheezy-updates/main amd64 Packages/DiffIndex
Hit http://mirrors.kernel.org wheezy-updates/main Translation-en/DiffIndex
Fetched 713 kB in 7s (89.3 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
The following packages were automatically installed and are no longer required:
fakeroot libxau6 libxdmcp6
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
augeas-lenses debconf-utils facter libaugeas-ruby1.8 libaugeas0 libruby1.8
puppet-common ruby ruby-json ruby-shadow ruby1.8
Suggested packages:
augeas-doc augeas-tools puppet-el vim-puppet etckeeper ruby-selinux
librrd-ruby1.8 ri ruby-dev ruby1.8-examples ri1.8 ruby-switch
Recommended packages:
rdoc
The following NEW packages will be installed:
augeas-lenses debconf-utils facter libaugeas-ruby1.8 libaugeas0 libruby1.8
puppet puppet-common ruby ruby-json ruby-shadow ruby1.8
0 upgraded, 12 newly installed, 0 to remove and 4 not upgraded.
Need to get 4,371 kB of archives.
After this operation, 12.9 MB of additional disk space will be used.
Get:1 http://mirrors.kernel.org/debian/ wheezy/main ruby all 1:1.9.3 [6,484 B]
Get:2 http://mirrors.kernel.org/debian/ wheezy/main libruby1.8 amd64 1.8.7.358-7.1+deb7u1 [2,091 kB]
Get:3 http://mirrors.kernel.org/debian/ wheezy/main ruby1.8 amd64 1.8.7.358-7.1+deb7u1 [320 kB]
Get:4 http://mirrors.kernel.org/debian/ wheezy/main ruby-json amd64 1.7.3-3 [78.5 kB]
Get:5 http://mirrors.kernel.org/debian/ wheezy/main facter all 1.6.10-1 [68.4 kB]
Get:6 http://mirrors.kernel.org/debian/ wheezy/main augeas-lenses all 0.10.0-1 [195 kB]
Get:7 http://mirrors.kernel.org/debian/ wheezy/main libaugeas0 amd64 0.10.0-1 [190 kB]
Get:8 http://mirrors.kernel.org/debian/ wheezy/main libaugeas-ruby1.8 amd64 0.4.1-1.1 [10.6 kB]
Get:9 http://mirrors.kernel.org/debian/ wheezy/main ruby-shadow amd64 2.1.4-2 [13.3 kB]
Get:10 http://mirrors.kernel.org/debian/ wheezy/main puppet-common all 2.7.23-1~deb7u3 [1,065 kB]
Get:11 http://mirrors.kernel.org/debian/ wheezy/main puppet all 2.7.23-1~deb7u3 [278 kB]
Get:12 http://mirrors.kernel.org/debian/ wheezy/main debconf-utils all 1.5.49 [55.8 kB]
dpkg-preconfigure: unable to re-open stdin: No such file or directory
Fetched 4,371 kB in 16s (261 kB/s)
Selecting previously unselected package ruby.
(Reading database ... 39358 files and directories currently installed.)
Unpacking ruby (from .../ruby_1%3a1.9.3_all.deb) ...
Selecting previously unselected package libruby1.8.
Unpacking libruby1.8 (from .../libruby1.8_1.8.7.358-7.1+deb7u1_amd64.deb) ...
Selecting previously unselected package ruby1.8.
Unpacking ruby1.8 (from .../ruby1.8_1.8.7.358-7.1+deb7u1_amd64.deb) ...
Selecting previously unselected package ruby-json.
Unpacking ruby-json (from .../ruby-json_1.7.3-3_amd64.deb) ...
Selecting previously unselected package facter.
Unpacking facter (from .../facter_1.6.10-1_all.deb) ...
Selecting previously unselected package augeas-lenses.
Unpacking augeas-lenses (from .../augeas-lenses_0.10.0-1_all.deb) ...
Selecting previously unselected package libaugeas0.
Unpacking libaugeas0 (from .../libaugeas0_0.10.0-1_amd64.deb) ...
Selecting previously unselected package libaugeas-ruby1.8.
Unpacking libaugeas-ruby1.8 (from .../libaugeas-ruby1.8_0.4.1-1.1_amd64.deb) ...
Selecting previously unselected package ruby-shadow.
Unpacking ruby-shadow (from .../ruby-shadow_2.1.4-2_amd64.deb) ...
Selecting previously unselected package puppet-common.
Unpacking puppet-common (from .../puppet-common_2.7.23-1~deb7u3_all.deb) ...
Selecting previously unselected package puppet.
Unpacking puppet (from .../puppet_2.7.23-1~deb7u3_all.deb) ...
Selecting previously unselected package debconf-utils.
Unpacking debconf-utils (from .../debconf-utils_1.5.49_all.deb) ...
Processing triggers for man-db ...
Setting up ruby (1:1.9.3) ...
Setting up libruby1.8 (1.8.7.358-7.1+deb7u1) ...
Setting up ruby1.8 (1.8.7.358-7.1+deb7u1) ...
Setting up ruby-json (1.7.3-3) ...
Setting up facter (1.6.10-1) ...
Setting up augeas-lenses (0.10.0-1) ...
Setting up libaugeas0 (0.10.0-1) ...
Setting up libaugeas-ruby1.8 (0.4.1-1.1) ...
Setting up ruby-shadow (2.1.4-2) ...
Setting up puppet-common (2.7.23-1~deb7u3) ...
Setting up puppet (2.7.23-1~deb7u3) ...
Starting puppet agent
puppet not configured to start, please edit /etc/default/puppet to enable
.
Setting up debconf-utils (1.5.49) ...
$ vagrant ssh -c 'puppet -V'
2.7.23
Connection to 127.0.0.1 closed.

Как видим на этот раз puppet был установлен.

Вообще, таким же образом можно задавать любые собственные скрипты для развёртывания окружения, но более правильным и простым является использование puppet'а для развёртывания окружения.

Воспользуемся этим инструментом и установим какие-нибудь пакеты.

Создаём директорию для манифеста puppet'а.

$ mkdir manifests
$ touch manifests/default.pp

В manifests/default.pp добавим следующий текст. Это стандартный puppet'овский манифест для установки пакетов: git, htop, curl, mc, vim.

package { ["git","htop","curl","mc","vim"]:
    ensure => "installed"
}

После этого добавим раздел puppet для provisioning'а в Vagrantfile.

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.box = "debian77"
    config.vm.box_url = "https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box"

    config.vm.provision "shell", :inline => <<-SHELL
        apt-get update
        apt-get install -y puppet
    SHELL

    config.vm.provision "puppet" do |puppet|
        puppet.manifests_path = "manifests"
        puppet.manifest_file = "default.pp"
    end
end

Мы поменяли способ provisioning'а, соответственно виртуалку надо перезапустить.

$ vagrant reload

И выполним команду.

$ vagrant provision
[default] Running provisioner: shell...
[default] Running: inline script
stdin: is not a tty
Hit http://security.debian.org wheezy/updates Release.gpg
Hit http://security.debian.org wheezy/updates Release
Hit http://mirrors.kernel.org wheezy Release.gpg
Hit http://security.debian.org wheezy/updates/main Sources
Hit http://security.debian.org wheezy/updates/main amd64 Packages
Hit http://mirrors.kernel.org wheezy-updates Release.gpg
Hit http://security.debian.org wheezy/updates/main Translation-en
Hit http://mirrors.kernel.org wheezy Release
Hit http://mirrors.kernel.org wheezy-updates Release
Hit http://mirrors.kernel.org wheezy/main Sources
Hit http://mirrors.kernel.org wheezy/main amd64 Packages
Hit http://mirrors.kernel.org wheezy/main Translation-en
Hit http://mirrors.kernel.org wheezy-updates/main Sources
Hit http://mirrors.kernel.org wheezy-updates/main amd64 Packages/DiffIndex
Hit http://mirrors.kernel.org wheezy-updates/main Translation-en/DiffIndex
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
puppet is already the newest version.
The following packages were automatically installed and are no longer required:
fakeroot libxau6 libxdmcp6
Use 'apt-get autoremove' to remove them.
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.
[default] Running provisioner: puppet...
Running Puppet with default.pp...
stdin: is not a tty
notice: /Stage[main]//Package[git]/ensure: ensure changed 'purged' to 'present'
notice: /Stage[main]//Package[htop]/ensure: ensure changed 'purged' to 'present'
notice: /Stage[main]//Package[mc]/ensure: ensure changed 'purged' to 'present'
notice: /Stage[main]//Package[vim]/ensure: ensure changed 'purged' to 'present'
notice: Finished catalog run in 59.75 seconds

А теперь попробуем обратиться к Git'у.

$ vagrant ssh -c 'git version'
git version 1.7.10.4
Connection to 127.0.0.1 closed.

Всё установлено и на это мы потратили 2-3 минуты, но теперь вы не забудете какие пакеты ставили в системе.

Давайте сделаем что-нибудь посложнее. Например, изменим timezone, а то сейчас время не совсем правильное.

$ date && vagrant ssh -c 'date'
Сб. нояб. 15 20:05:21 MSK 2014
Sat Nov 15 17:05:21 UTC 2014
Connection to 127.0.0.1 closed.

Для этого добавим в default.pp следующий код.

package { 'tzdata':
    ensure => "installed"
}

file { '/etc/timezone':
    ensure => present,
    content => "Europe/Moscow\n",
}

exec { 'reconfigure-tzdata':
    user => root,
    group => root,
    command => '/usr/sbin/dpkg-reconfigure --frontend noninteractive tzdata',
}

File['/etc/timezone'] -> Exec['reconfigure-tzdata']

И развернём по новой.

$ vagrant provision
[default] Running provisioner: shell...
[default] Running: inline script
stdin: is not a tty
...
[default] Running provisioner: puppet...
Running Puppet with default.pp...
stdin: is not a tty
notice: /Stage[main]//File[/etc/timezone]/content: content changed '{md5}ae1d80ba85332ae2d9fbbd491b17c043' to '{md5}fa68dd8e32fd0b0c7e6e776736260abd'
notice: /Stage[main]//Exec[reconfigure-tzdata]/returns: executed successfully
notice: Finished catalog run in 0.33 seconds
$ date && vagrant ssh -c 'date'
Сб. нояб. 15 20:07:34 MSK 2014
Sat Nov 15 20:07:34 MSK 2014
Connection to 127.0.0.1 closed.

Стало намного лучше.

Но что если нам необходимо поставить софт, которого нет в репозиториях операционной системы. Например, Oracle Java 8 из webupd8.

Создадим файл install_java.sh в директории с Vagrantfile. Vagrant по умолчанию добавляет эту директорию (как synced shared folder) в виртуалку по адресу /vagrant, то есть вы всегда можете достучаться до файлов на хост машине из виртуалки.

Содержимое install_java.sh

#!/bin/bash

if [ ! -f /etc/apt/sources.list.d/webupd8team-java.list ]; then
    echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list
    echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list
    apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886
    apt-get update
    echo debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections
    echo debconf shared/accepted-oracle-license-v1-1 seen true | sudo debconf-set-selections
    apt-get install -q -y oracle-java8-installer
fi

Этот скрипт добавляет нужные ключи, ссылки на репозитории и устанаваливает JDK8, соглашаясь с лицензиями (строчки с debconf shared/accepted-oracle-license-v1-1 seen true).

Теперь добавим вызов этого скрипта. Сразу предупрежу, что это не самый лучший способ и лучше делать это через puppet, но для иллюстрации сойдёт.

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.box = "debian77"
    config.vm.box_url = "https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box"

    config.vm.provision "shell", :inline => <<-SHELL
        apt-get update
        apt-get install -y puppet
    SHELL

    config.vm.provision "shell", path: "install_java.sh"
    
    config.vm.provision "puppet" do |puppet|
        puppet.manifests_path = "manifests"
        puppet.manifest_file = "default.pp"
    end
end

Пробуем.

$ vagrant provision
[default] Running provisioner: shell...
...
gpg: requesting key EEA14886 from hkp server keyserver.ubuntu.com
gpg: key EEA14886: public key "Launchpad VLC" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
...
Connecting to download.oracle.com (download.oracle.com)|88.221.133.31|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 160872482 (153M) [application/x-gzip]
Saving to: `jdk-8u25-linux-x64.tar.gz'
0K ........ ........ ........ ........ ........ ........ 1% 3.94M 38s
...
156672K ...... 100% 5.83M=38s
2014-11-15 20:16:32 (4.02 MB/s) - `jdk-8u25-linux-x64.tar.gz' saved [160872482/160872482]
Download done.
Removing outdated cached downloads...
update-alternatives: error: no alternatives for java
...
Oracle JDK 8 installed
update-alternatives: using /usr/lib/jvm/java-8-oracle/jre/lib/amd64/libnpjp2.so to provide /usr/lib/mozilla/plugins/libjavaplugin.so (mozilla-javaplugin.so) in auto mode
...
$ vagrant ssh -c 'java -version'
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
Connection to 127.0.0.1 closed.

Java установлена.

Давайте установим Cassandra'у.

Создаём скрипт install_cassandra.sh

#!/bin/bash

if [ ! -f /etc/apt/sources.list.d/cassandra.sources.list ]; then
    echo "deb http://debian.datastax.com/community stable main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list
    curl -L http://debian.datastax.com/debian/repo_key | sudo apt-key add -
    sudo apt-get update
    sudo apt-get install -q -y dsc21
    sudo apt-get install -q -y cassandra-tools
fi

И добавляем вызов после установки Java в Vagrantfile.

config.vm.provision "shell", path: "install_cassandra.sh"

Пробуем.

$ vagrant provision
$ vagrant ssh -c 'cqlsh -h'
Usage: cqlsh [options] [host [port]]
CQL Shell for Apache Cassandra
Options:
    --version show program's version number and exit
    -h, --help show this help message and exit
    -C, --color Always use color output
...
Connection to 127.0.0.1 closed.
$ vagrant ssh -c 'ps -uxa | grep cassandra'
warning: bad ps syntax, perhaps a bogus '-'?
See http://gitorious.org/procps/procps/blobs/master/Documentation/FAQ
106 6872 9.4 68.0 2232184 698812 ? SLl 20:23 0:09 java -ea -javaagent:/usr/s...org.apache.cassandra.service.CassandraDaemon
vagrant 7182 0.0 0.1 10768 1468 pts/0 Ss+ 20:25 0:00 bash -l -c ps -uxa | grep cassandra
vagrant 7186 0.0 0.0 7836 884 pts/0 S+ 20:25 0:00 grep cassandra
Connection to 127.0.0.1 closed.

Cassandra установлена и даже запущена. Реализовывать скрипты для каждого приложения крайне утомительно и хотелось бы иметь средство для установки прямо из puppet'а. Собственно, в puppet уже об этом позаботились и реализовали огромное количество модулей для установки разнообразного софта.

Давайте установим postgresql и настроим основные параметры. Для этого воспользуемся модулем puppet-postgresql ( https://forge.puppetlabs.com/puppetlabs/postgresql )

Для начала данный модуль надо установить. Поэтому добавим следующие строки в Vagrantfile (добавим немного оптимизаций для ускорения процесса повторного provisioning'а).

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.box = "debian77"
    config.vm.box_url = "https://s3.eu-central-1.amazonaws.com/ffuenf-vagrantboxes/debian/debian-7.7.0-amd64_virtualbox.box"

    config.vm.provision "shell", :inline => <<-SHELL
        if [ ! -d /etc/puppet/ ]; then
            apt-get update
            apt-get install -y puppet
        fi
        if [ ! -d /etc/puppet/modules/postgresql ]; then
            puppet module install puppetlabs/postgresql
        fi
    SHELL

    config.vm.provision "shell", path: "install_java.sh"
    config.vm.provision "shell", path: "install_cassandra.sh"

    config.vm.provision "puppet" do |puppet|
        puppet.manifests_path = "manifests"
        puppet.manifest_file = "default.pp"
    end
end

Теперь добавим следующие строки в default.pp.

# global PostgreSQL settings
# see: http://www.rozumim.cz/it/2014/10/21/run-your-own-postgresql-server-using-vagrant-and-puppet.html
class { 'postgresql::globals':
    encoding => 'UTF8',
}

class { 'postgresql::server':
    listen_addresses => '*',
    postgres_password => 'postgrespassword',
    # https://docs.puppetlabs.com/puppet/latest/reference/lang_relationships.html
    require => Class['postgresql::globals'],
}

# create db + user
postgresql::server::db { 'testdb':
    user => 'testuser',
    password => postgresql_password('testuser', 'testpassword'),
}

# rule for remote connections
postgresql::server::pg_hba_rule { 'allow remote connections with password':
    type => 'host',
    database => 'all',
    user => 'all',
    address => 'all',
    auth_method => 'md5',
}

# PostgreSQL password
file {'.pgpass-vagrant':
    path => '/home/vagrant/.pgpass',
    ensure => present,
    mode => 0600,
    content => "localhost:5432:testdb:testuser:testpassword",
    owner => "vagrant",
    group => "vagrant",
}

# initialize the content of your new database
#exec { "populate_postgresql":
# command => "/usr/bin/psql -d testdb -U testuser -h localhost -p 5432 --no-password < /vagrant/psql-db/psql-dump.sql",
# path => "/usr/vagrant/", # there is .pgpass file
# user => 'vagrant',
# logoutput => true,
#
#
# require => [ File['.pgpass-vagrant'],
# Postgresql::Server::Db['testdb'],
# Postgresql::Server::Pg_hba_rule['allow remote connections with password'] ]
#}

Пробуем.

$ vagrant provision

[default] Running provisioner: shell...

[default] Running: inline script

stdin: is not a tty

Preparing to install into /etc/puppet/modules ...

Downloading from http://forge.puppetlabs.com ...

. . . notice: Finished catalog run in 37.07 seconds

$ vagrant ssh -c 'ps -uxa | grep postgre'

postgres 10051 0.9 0.9 101112 9748 ? S 20:37 0:00 /usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf

postgres 10053 0.0 0.2 101096 2372 ? Ss 20:37 0:00 postgres: writer process

postgres 10054 0.0 0.1 101096 2052 ? Ss 20:37 0:00 postgres: wal writer process

postgres 10055 0.0 0.2 101836 3052 ? Ss 20:37 0:00 postgres: autovacuum launcher process

postgres 10056 0.0 0.1 69528 2000 ? Ss 20:37 0:00 postgres: stats collector process

vagrant 10297 0.0 0.1 10768 1468 pts/0 Ss+ 20:37 0:00 bash -l -c ps -uxa | grep postgre

vagrant 10301 0.0 0.0 7836 884 pts/0 S+ 20:37 0:00 grep postgre

Connection to 127.0.0.1 closed.

PostgreSQL установлен и запущен. И даже настроен: пользователи, база и т. д. Можно даже дамп БД развернуть.

Мы потратили всего 10 минут, а получили полноценное окружение для разработки. Самое главное, что это окружение повторяемое. Больше времени было потрачено на гугление, чем на реальную настройку. Сценарии использования.

Тут я постараюсь привести несколько сценариев, чтобы показать как именно Vagrant может нам помочь.

В команду «вливается» новый человек. Ему прислали ссылку на репозиторий, но он понятия не имеет, что именно ему понадобиться в работе. Да, есть файлы config.devel.inc или что-то подобное, но бывает очень трудно подготовить окружение для начала разработки. В описанном случае, всё окружение уже в виртуальной машине: базы, пакеты, сервисы и т. д. Достаточно сделать vagrant up и получить виртуалку, в которой уже всё работает.

QA. Специалист QA проверяет версию приложения. Он понятия не имеет, что именно ему понадобиться для тестов. Ему нужно уточнить: где тестовая база? как туда попасть? параметры подключений? Права? Установка пакетов, софта? А ещё QA может работает на Windows? В описанном случае, специалист QA просто выгружает из репозитория нужную версию, стартует виртуалку и тестирует.

«На моей машине всё работает.» Разработчик что-то установил на своей машине, но не помнит что именно. В результате в QA и у админов появляется головная боль, связанная с неповторяемостью окружения. При использовании виртуалок все действия записаны и выяснить причину гораздо проще.

Continious integration. Это кстати очень популярная тема ( http://www.larrycaiyu.com/blog/2011/10/21/make-ci-easier-with-jenkins-ci-and-vagrant/ ). Мы сможем проверять процес развёртывания приложения и иметь истинно повторямое окружение без странных неповторяемых ошибок.

Представим ситуацию. На production'е выявили некоторый баг, который надо пофиксить, но за время разработки ветка разработки, база данных, схемы в Solr и т. д. Уже ушли вперёд. Если мы перейдём к коммиту и попробуем поднять приложение, то оно может не стартовать из-за изменений сделанных в процессе разработки в сторонних ресурсах. С использованием виртуального окружения мы можем развернуть именно то окружение, которое было для правки бага именной той версии.

У нас имеется группа разработки, пусть из 3 человек, которые работают над одним проектом. Разработчик 1 вносит изменения в БД на devel сервере, а разработчик 2 изменения в RabbitMQ, в результате у всех неработающее приложение, до тех пор пока они не сольют изменения вместе. Можно, конечно, делать релизы и коммитить почаще, но это не спасает от всех ошибок. При использовании виртуального окружения, у всех разработчиков своя песочница, никто никому не мешает.

Админы могут попробовать работу софта на разных версиях (например, обновить базу) или, например, отладить автоматизированные скрипты на случай включения репликации. Вариантов использования может быть очень много. Самое главное, что админы сразу видят, как надо подготавливать окружение и все действия происходят в «песочнице». Ещё админы могут достаточно просто проверить развёртывание софта в другой операционке, например, из Debian в RedHat.

Разработчик проводит разработку удалённо дома. В случае использования devel-сервера, необходимо иметь постоянный доступ по VPN в сеть офиса и гонять данные туда сюда. Если по каким-то причинам, доступа к девелу нет, то разрабатывать уже нельзя. В случае с виртуальным окружением, можно сделать все изменения и просто закоммитить их, а все ресурсы у нас есть изолированно и локально.

Вы ведёте разработку на одной машине, вам необходимо перейти на другую машину. Поменяли ноут, работаете из дома и т. д. В случае обычной разработки вам нужно мучительно вспоминать, что именно вам нужно. В случае виртуальной разработки достаточно выгрузить репозиторий проекта и сделать vagrant up.

Clone this wiki locally