EuroLinux Obsługa maszyn Vagranta przez Ansible

Obsługa maszyn Vagranta przez Ansible

Automatyzacja i prototypowanie nie są zadaniami trywialnymi, zwłaszcza gdy mowa o zaawansowanych czynnikach. Dlatego w tym artykule pokażemy, jak wykonać prototyp prostej infrastruktury oraz zautomatyzować jej wdrożenie za pomocą współpracujących ze sobą narzędzi Vagrant i Ansible.

W tym artykule pokażemy, jak wykonać prototyp prostej infrastruktury oraz zautomatyzować jej wdrożenie za pomocą współpracujących ze sobą narzędzi Vagrant i Ansible.

Im krótszy czas wprowadzania dopracowanego produktu na rynek, tym większa szansa na jego sukces. Gdy proces ten jest powtarzalny, a zadania mogą zostać zautomatyzowane, można dokonywać ich optymalizacji, aby wyeliminować nadmierne wykorzystanie zasobów, m.in. czasu pracowników. Korzyści automatyzacji mogą rosnąć w nieskończoność, jeśli weźmiemy pod uwagę jej skalowalność.

Przykładowe korzyści automatyzacji:

  • obniżka kosztów i możliwość inwestycji oszczędzonych środków
  • standaryzacja przepływów pracy i produktów – są one spójne i niezawodne
  • pracownicy mogą skupić się na zadaniach wymagających nieszablonowego myślenia, przez co efekt pracy jest bardziej satysfakcjonujący niż wykonywanie nudnych, powtarzalnych czynności.

Prototypowanie polega na stworzeniu uproszczonego, eksperymentalnego modelu rozwiązania, które pozwoli sprawdzić, czy jest ono zgodne z oczekiwaniami użytkowników.

Ta faza wydawania produktu ma następujące korzyści:

  • działające podstawy dające wszystkim interesariuszom obraz korzyści, ryzyk i kosztów
  • wcześniejsze dostrzeganie elementów wartych ulepszenia oraz implementacja zmian
  • możliwość otrzymania informacji zwrotnej, która pozwoli stwierdzić, które implementacje działają zgodnie ze specyfikacją
  • skrócenie czasu wprowadzenia produktu na rynek poprzez zminimalizowanie liczby błędów do poprawienia przed wypuszczeniem produktu na rynek.

Automatyzacja i prototypowanie nie są zadaniami trywialnymi, zwłaszcza gdy mowa o zaawansowanych czynnikach, jak np. idempotentność i reprodukowalność. Istnieje jednak wiele dedykowanych programów, które je zapewniają. Jedną z par narzędzi, które dzisiaj opiszemy jest Ansible i Vagrant.

Ansible

Ansible jest silnikiem Open Source do automatyzacji pod kątem takich zadań jak:

  • wdrażanie oprogramowania i infrastruktury w chmurze
  • zarządzanie konfiguracją
  • orkiestracja wewnątrzusługowa
  • ukierunkowanie na ciągłe dostarczanie (Continuous Delivery).

Ansible wykorzystuje Playbooki do interpretacji zadań do zrealizowania. Playbook to plik tekstowy, który opisuje role, jakie są przydzielone konkretnym maszynom. Pozwala to na reużywanie zadań wdrożeniowych i opisanie pewnej odpowiedzialności w ramach tej sprecyzowanej roli. Wspomniane maszyny są zdefiniowane jako para klucz-wartość w pliku inventory.

Vagrant

Vagrant pozwala na interpretację napisanej przez wdrożeniowca specyfikacji opisanej w pliku Vagrantfile. Zgodnie z nią importuje przygotowane wcześniej obrazy systemów, aplikuje ustawienia dla nowo tworzonej maszyny wirtualnej i wykonuje końcowe zmiany konfiguracji już działającego systemu np. za pomocą Ansible. Specyfikacja ta sprawia, że użytkownik nie musi ręcznie konfigurować swojego środowiska pracy pod konkretne zadanie. Wynikiem użycia Vagranta jest generalizacja środowiska operacyjnego i możliwość zdefiniowania go wprost w pliku tekstowym. Oznacza to, że można go umieścić wraz ze źródłami samego projektu, który wykonywany jest w żądanym ekosystemie.

Tworzenie prostej infrastruktury składającej się z wielu maszyn jest łatwe. Vagrant zajmuje się uruchomieniem wielu maszyn wirtualnych oraz aplikowaniem konfiguracji sieciowej. W przypadku konieczności szybkiej zmiany któregoś z parametrów wystarczy dokonać prostej zmiany w specyfikacji – w przeciwieństwie do ręcznego zarządzania wspomnianymi maszynami jedna po drugiej.

Kooperacja narzędzi

Rzućmy okiem, jak opisane wyżej narzędzia wykorzystywane są w warsztacie DevOpsa w ramach przygotowania i automatyzacji prototypu. W ramach demonstracji przedstawimy okrojoną wersję pewnego produkcyjnego projektu zawierającego serwer hostujący stronę internetową oraz serwer monitoringu. W tym przykładzie dla uproszczenia wdrożenie będzie polegało jedynie na tym, aby działające maszyny były w stanie zakomunikować na prośbę Ansible’a, że są online. Spójrzmy na strukturę plików i katalogów:

.
├── playbooks
│   ├── monitoring.yml
│   └── webserver.yml
├── inventory.ini
└── Vagrantfile

oraz na zawartość plików:

  • Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "eurolinux-vagrant/eurolinux-8"

  config.vm.define "monitoring" do |monitoring|
    monitoring.vm.hostname = "monitoring"
    monitoring.vm.network "private_network", ip: "10.0.0.2"
    monitoring.vm.provision "ansible" do |ansible|
      ansible.playbook = "playbooks/monitoring.yml"
    end
  end

  config.vm.define "webserver" do |webserver|
    webserver.vm.hostname = "webserver"
    webserver.vm.network "private_network", ip: "10.0.0.3"
    webserver.vm.provision "ansible" do |ansible|
      ansible.playbook = "playbooks/webserver.yml"
    end
  end
end
  • inventory.ini
[monitoring]
10.0.0.2

[webserver]
10.0.0.3
  • playbooks/monitoring.yml
---
- hosts: monitoring
  tasks:
    - name: Sample message from first machine
      debug:
        msg: "Monitoring machine is up"
  • playbooks/webserver.yml
---
- hosts: webserver
  tasks:
    - name: Sample message from second machine
      debug:
        msg: "Webserver machine is up"

W tym prostym przykładzie widzimy, że Vagrant zinterpretuje specyfikację w Vagrantfile, uruchamiając dwie maszyny wirtualne. Następnie wykorzysta Ansible do przeczytania inventory.ini i połączenia się z systemami o zdefiniowanych tam adresach. Na danej instancji zostanie wykonany jeden z playbooków zawartych w katalogu playbooks, który został sprecyzowany wcześniej w Vagrantfile.

Można już uruchomić ten stos technologiczny. Dla czytelności dodałem parametr --no-parallel, aby maszyny zostały uruchomione sekwencyjnie, nie równolegle.

$ vagrant up --no-parallel
Bringing machine 'monitoring' up with 'libvirt' provider...
Bringing machine 'webserver' up with 'libvirt' provider...
==> monitoring: Checking if box 'eurolinux-vagrant/eurolinux-8' version '8.5.2' is up to date...
==> monitoring: Creating image (snapshot of base box volume).
==> monitoring: Creating domain with the following settings...
==> monitoring:  -- Name:              sample-ansible-with-vagrant_monitoring
==> monitoring:  -- Domain type:       kvm
==> monitoring:  -- Cpus:              1
==> monitoring:  -- Feature:           acpi
==> monitoring:  -- Feature:           apic
==> monitoring:  -- Feature:           pae
==> monitoring:  -- Clock offset:      utc
==> monitoring:  -- Memory:            512M
==> monitoring:  -- Management MAC:
==> monitoring:  -- Loader:
==> monitoring:  -- Nvram:
==> monitoring:  -- Base box:          eurolinux-vagrant/eurolinux-8
==> monitoring:  -- Storage pool:      default
==> monitoring:  -- Image:             /var/lib/libvirt/images/sample-ansible-with-vagrant_monitoring.img (80G)
==> monitoring:  -- Disk driver opts:  cache='default'
==> monitoring:  -- Kernel:
==> monitoring:  -- Initrd:
==> monitoring:  -- Graphics Type:     vnc
==> monitoring:  -- Graphics Port:     -1
==> monitoring:  -- Graphics IP:       127.0.0.1
==> monitoring:  -- Graphics Password: Not defined
==> monitoring:  -- Video Type:        cirrus
==> monitoring:  -- Video VRAM:        9216
==> monitoring:  -- Sound Type:
==> monitoring:  -- Keymap:            en-us
==> monitoring:  -- TPM Backend:       passthrough
==> monitoring:  -- TPM Path:
==> monitoring:  -- INPUT:             type=mouse, bus=ps2
==> monitoring: Creating shared folders metadata...
==> monitoring: Starting domain.
==> monitoring: Waiting for domain to get an IP address...
==> monitoring: Waiting for SSH to become available...
    monitoring:
    monitoring: Vagrant insecure key detected. Vagrant will automatically replace
    monitoring: this with a newly generated keypair for better security.
    monitoring:
    monitoring: Inserting generated public key within guest...
    monitoring: Removing insecure key from the guest if it's present...
    monitoring: Key inserted! Disconnecting and reconnecting using new SSH key...
==> monitoring: Setting hostname...
==> monitoring: Configuring and enabling network interfaces...
    monitoring: SSH address: 192.168.121.139:22
    monitoring: SSH username: vagrant
    monitoring: SSH auth method: private key
==> monitoring: Rsyncing folder: /home/user/Documents/sample-ansible-with-vagrant/ => /vagrant
==> monitoring: Running provisioner: ansible...
    monitoring: Running ansible-playbook...

PLAY [monitoring] **************************************************************

TASK [Gathering Facts] *********************************************************
ok: [monitoring]

TASK [Sample message from first machine] ***************************************
ok: [monitoring] => {
    "msg": "Monitoring machine is up"
}

PLAY RECAP *********************************************************************
monitoring                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

==> webserver: Checking if box 'eurolinux-vagrant/eurolinux-8' version '8.5.2' is up to date...
==> webserver: Creating image (snapshot of base box volume).
==> webserver: Creating domain with the following settings...
==> webserver:  -- Name:              sample-ansible-with-vagrant_webserver
==> webserver:  -- Domain type:       kvm
==> webserver:  -- Cpus:              1
==> webserver:  -- Feature:           acpi
==> webserver:  -- Feature:           apic
==> webserver:  -- Feature:           pae
==> webserver:  -- Clock offset:      utc
==> webserver:  -- Memory:            512M
==> webserver:  -- Management MAC:
==> webserver:  -- Loader:
==> webserver:  -- Nvram:
==> webserver:  -- Base box:          eurolinux-vagrant/eurolinux-8
==> webserver:  -- Storage pool:      default
==> webserver:  -- Image:             /var/lib/libvirt/images/sample-ansible-with-vagrant_webserver.img (80G)
==> webserver:  -- Disk driver opts:  cache='default'
==> webserver:  -- Kernel:
==> webserver:  -- Initrd:
==> webserver:  -- Graphics Type:     vnc
==> webserver:  -- Graphics Port:     -1
==> webserver:  -- Graphics IP:       127.0.0.1
==> webserver:  -- Graphics Password: Not defined
==> webserver:  -- Video Type:        cirrus
==> webserver:  -- Video VRAM:        9216
==> webserver:  -- Sound Type:
==> webserver:  -- Keymap:            en-us
==> webserver:  -- TPM Backend:       passthrough
==> webserver:  -- TPM Path:
==> webserver:  -- INPUT:             type=mouse, bus=ps2
==> webserver: Creating shared folders metadata...
==> webserver: Starting domain.
==> webserver: Waiting for domain to get an IP address...
==> webserver: Waiting for SSH to become available...
    webserver:
    webserver: Vagrant insecure key detected. Vagrant will automatically replace
    webserver: this with a newly generated keypair for better security.
    webserver:
    webserver: Inserting generated public key within guest...
    webserver: Removing insecure key from the guest if it's present...
    webserver: Key inserted! Disconnecting and reconnecting using new SSH key...
==> webserver: Setting hostname...
==> webserver: Configuring and enabling network interfaces...
    webserver: SSH address: 192.168.121.116:22
    webserver: SSH username: vagrant
    webserver: SSH auth method: private key
==> webserver: Rsyncing folder: /home/user/Documents/sample-ansible-with-vagrant/ => /vagrant
==> webserver: Running provisioner: ansible...
    webserver: Running ansible-playbook...

PLAY [webserver] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [webserver]

TASK [Sample message from second machine] **************************************
ok: [webserver] => {
    "msg": "Webserver machine is up"
}

PLAY RECAP *********************************************************************
webserver                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Podsumowanie

Jak widać, zadanie zostało zakończone pomyślnie. Był to prosty i intuicyjny wstęp do tworzenia większych, skomplikowanych infrastruktur w ramach prototypu. W przypadku krytycznych systemów produkcyjnych istnieje możliwość ponownego użycia zadań zapisanych w playbookach, co znacząco zmniejsza nakład pracy programistów i pozwala zauważyć efekty na warstwie stacji roboczej DevOpsa.

Autorzy

Artykuły na blogu są pisane przez osoby z zespołu EuroLinux. 80% treści zawdzięczamy naszym developerom, pozostałą część przygotowuje dział sprzedaży lub marketingu. Dokładamy starań, żeby treści były jak najlepsze merytorycznie i językowo, ale nie jesteśmy nieomylni. Jeśli zauważysz coś wartego poprawienia lub wyjaśnienia, będziemy wdzięczni za wiadomość.