Marcin Lewandowski
Marcin Lewandowski
Programista PHP ( Symfony ), blogger, trener oraz miłośnik kawy. Na co dzień pracuję z Symfony, RabbitMQ, ElasticSearch, Node.js, Redis, Docker, MySQL.

Puppet czyli jak udoskonalić instalację aplikacji w Vagrancie

Puppet czyli jak udoskonalić instalację aplikacji w Vagrancie

W poprzednich wpisach serii dotyczącej wirtualizacji pokazałem jak szybko i łatwo można uruchamiać środowiska deweloperskie czy też produkcyjne. Jednak jeśli coś wygląda na zbyt dobre, aby było prawdziwe to oznacza że gdzieś jest haczyk 😉

W przypadku Vagranta jest ich kilka, ja jednak skupię się na jednym. Chodzi mi o proces instalacji i konfiguracji aplikacji na wirtualnej maszynie, obecnie odbywa się to poprzez wywołanie skryptu powłoki. Skrypt instaluje i konfiguruje nam odpowiednio środowisko, jednak zmiana dystrybucji czy też jej aktualizacja, może pociągać za sobą konieczność wprowadzenia wielu modyfikacji 🙁 Rozwiązaniem tej sytuacji jest Puppet.

Czym jest Puppet

Puppet jest oprogramowaniem pozwalającym na kompleksowe zarządzanie serwerami. Umożliwia on instalację oprogramowania, monitorowanie procesów, konfigurację poszczególnych serwerów na maszynie, tworzenie plików, zmiany uprawnień oraz wiele więcej. Oprogramowanie to jest w pełni darmowe i dostępne niemal na każdy system operacyjny. Dla nas jednak najistotniejsze jest to, że Vagrant wspiera Puppet-a.

Zaczynamy pracę z Puppet-em

Naszym celem na dziś będzie instalacja Nginx oraz jego uruchomienie. Pozwoli to nam na zapoznanie się z podstawami używania Puppet-a jako narzędzia do instalacji i uruchamiania aplikacji.

Vagrant

Jako że Puppet ma być kolejnym krokiem na drodze do automatyzacji budowania środowisk deweloperskich oraz produkcyjnych to zaczynamy od pliku Vagrantfile.

Vagrant.configure("2") do |config|
 
  config.vm.box = "ubuntu/xenial64"
 
  config.vm.network :private_network, ip: "192.168.33.10"
 
  config.vm.provider "virtualbox" do |vb|
 
      vb.name = "WebServer"
      vb.cpus = 1
      vb.memory = 1024
      vb.gui = false
 
  end
 
end

Mamy praktycznie czysty plik uruchamiający obraz Ubuntu. Teraz czas na wzbogacenie go współpracę z Puppet-em, w tym celu dodajemy wpis:

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

Poszczególne parametry mówią o:

  • puppet.manifests_path – ścieżka do katalogu z plikiem konfiguracyjnym,
  • puppet.manifest_file – nazwa pliku z rozszerzeniem “.pp”, które to jest domyślnym rozszerzeniem plików Puppet-a

Pierwszy plik

Skoro jest wpis w pliku Vagrantfile czas utworzyć nasz pierwszy plik. W katalogu głównym tworzymy katalog manifests, a następnie tworzymy plik default.pp. Pliki z rozszerzeniem “.pp” nazywamy recepturami, gdyż zawierają wszelkie informacje o tym jak powinien być skonfigurowany nasz serwer. Nasz plik, zawiera w sobie zgrupowane informacje dotyczące konfiguracji poszczególnych elementów serwera. Taką grupę nazywamy zasobem (resource), oczywiście mogą być one różnego typu np. aplikacja jest takim zasobem i zapis przedstawiający taki zasób wygląda następująco:

package { 'nginx':
 
}

Powyższy zasób jest typu package następnie nazwa aplikacji nginx. Teraz musimy zastanowić się jakie mamy wymagania co do Puppet-a w stosunku do aplikacji Nginx. I w tym przypadku ma być ona zainstalowana co definiujemy poprzez dodanie parametru ensure.

package { 'nginx':
 ensure => installed
}

Teraz gdy mamy pewność, że serwer Nginx jest zainstalowany przydała by się pewność, że jest on uruchomiony. Do tego celu posłużymy się zasobem typu service.

service { 'nginx':
 ensure => running
}

Konstrukcja niemal identyczna jak poprzednia jednak, aby dobrze pełniła swoją rolę powinniśmy ją wzbogacić o wymagania jakie muszą być spełnione przed zadbaniem o uruchomienie serwera. Naszym wymaganiem będzie zainstalowany serwer Nginx, co zapisujemy w prosty sposób:

service { 'nginx':
 ensure => running,
 require => Package['nginx']
}

Pojawił się wpis require, który mówi że wymagana jest aplikacja nginx. Jeśli wymaganych było by więcej aplikacji to kolejne definiujemy po przecinku, gdyż jest to zapis tablicy.

Pierwsze uruchomienie

Mamy już plik Vagrantfile oraz prostą instalację serwera www Nginx za pomocą Puppet-a. Czas sprawdzić czy wszystko zadziała według oczekiwań. Uruchamiamy polecenie budujące obraz:

vagrant up

I tutaj może spotkać nas niemiła niespodzianka. Bowiem możecie zobaczyć poniższy komunikat:

Jest to spowodowane faktem, że część obrazów nie ma zainstalowanego Puppet-a. Wymusza to na nas napisanie polecenia, które go zainstaluje. Polecenie to zapewne będzie zależne od dystrybucji której użyjemy. W tym przypadku do pliku Vagrantfile dodajemy:

$provision_script= <<SCRIPT
    if [[ $(which puppet) != '/usr/bin/puppet' ]]; then
      sudo apt-get install -y puppet
    fi
SCRIPT
 
  config.vm.provision :shell, :inline => $provision_script

Dodany fragment sprawdza poleceniem which, czy jest w systemie zainstalowana aplikacja o nazwie puppet. Jeśli nie zostanie zwrócona poprawna ścieżka to zostanie wywołane polecenie instalujące aplikację. Po zmianach cały nasz plik Vagrantfile powinien wyglądać następująco:

Vagrant.configure("2") do |config|
 
  config.vm.box = "ubuntu/xenial64"
 
  config.vm.network :private_network, ip: "192.168.33.10"
 
  config.vm.provider "virtualbox" do |vb|
 
      vb.name = "WebServerPuppet"
      vb.cpus = 1
      vb.memory = 1024
      vb.gui = false
 
  end
 
$provision_script= <<SCRIPT
    if [[ $(which puppet) != '/usr/bin/puppet' ]]; then
      sudo apt-get install -y puppet
    fi
SCRIPT
 
  config.vm.provision :shell, :inline => $provision_script
 
  config.vm.provision "puppet" do |puppet|
    puppet.manifests_path = "manifests"
    puppet.manifest_file = "default.pp"
  end
 
end

Teraz możemy zniszczyć maszynę na której nie było Puppet-a poleceniem vagrant destroy, a następnie rozpocząć budowę nowej poleceniem vagrant up. Po zakończeniu budowy maszyny powinniśmy zobaczyć w konsoli fragment mówiący o uruchomieniu naszej receptury.

Teraz możemy przejść do przeglądarki i zweryfikować czy serwer Nginx rzeczywiście działa i wyświetli nam komunikat powitalny.

Podsumowanie

Ten prosty przykład instalacji oraz uruchomienia serwera Nginx mam nadzieję pokazał, że można w prosty, opisowy sposób stworzyć konfigurację serwera. Taka konfiguracja jest niezależna od dystrybucji czy systemu na którym przyjdzie nam pracować. Stwarza to możliwość łatwego testowania różnych dystrybucji linux-a bez czasochłonnego przepisywania skryptu instalacyjnego.

Wpis ten to dopiero początek przygody z Puppet-em, który nie musi być wykorzystywany razem z Vagrant-em. Możecie śmiało instalować go na waszych lokalnych maszynach i testować możliwości.