Korzystaliście kiedyś z Ansible? W tym artykule postaram się przybliżyć zagadnienia związane z jego używaniem, a także szerzej omówić jego wdrożenie oraz korzyści z korzystania z tego narzędzia.
Bez dobrze zaprojektowanej i zarządzanej infrastruktury, a także przemyślanego procesu wdrażania i aktualizacji, większość systemu gotowego do obsługi dużej liczby klientów, przy jednoczesnym zachowaniu stabilności działania usług po prostu by nie powstała. Niezależnie od tego, czy w naszej infrastrukturze jest kilka, czy kilka tysięcy serwerów, na pewno warto skorzystać z narzędzia do zarządzania konfiguracją.
Jakie korzyści możemy odnieść z wykorzystania Ansible?
Ansible jest narzędziem do zarządzania stanem infrastruktury. Pozwala nam na wdrażanie systemów i aplikacji w spójny, powtarzalny sposób przy wykorzystaniu natywnych protokołów SSH oraz WinRM. Jest narzędziem open source, które używa zarówno języków deklaratywnych, jak i proceduralnych do zarządzania konfiguracją. Praca z Ansible pozwala zarówno na wykonywanie komend ad-hoc, jak i na przetwarzanie wcześniej zdefiniowanych w języku YAML plików konfiguracyjnych, tzw. scenariuszy (playbooków). Platformę można wykorzystać także do zarządzania wieloma urządzeniami sieciowymi popularnych producentów, co znacznie ułatwia zmianę konfiguracji w switchach, routerach czy innych urządzeniach sieciowych.
Ansible kontra inne narzędzia do zarządzania konfiguracją
Prawdopodobnie największą zaletą Ansible jest możliwość działania bez konieczności użycia agenta. Oznacza to, iż nie potrzebujemy instalować żadnego dodatkowego systemu na zarządzanych serwerach klientów poza Pythonem, który jest w tej chwili dostępny niemal w każdym systemie operacyjnym. Użycie natywnych protokołów SSH oraz WinRM zapewnia dodatkowe bezpieczeństwo. Wdrożenie nie wymaga więc wielkich zmian w politykach bezpieczeństwa czy otwierania dodatkowych portów.
Dzięki swojej prostocie, wszechstronności i skalowalności — Ansible pozostaje jednym z najbardziej dynamicznie rozwijających się projektów na Github, z zaangażowaną i aktywną społecznością (ponad 55 tysięcy gwiazdek według danych na listopad 2022) wyprzedzając konkurencyjne narzędzia typu Chef, Puppet, SaltStack. Ma wyjątkowe wsparcie od wszystkich popularnych dostawców chmury. Udostępnia tysiące modułów (małych programów tymczasowo umieszczonych na zarządzanych maszynach do czasu zakończenia scenariusza), ułatwiających szybkie i przejrzyste opracowywanie scenariuszy, a później uruchamianie ich na setkach, tysiącach systemów naraz.
Przykładowy fragment scenariusza do zarządzania LAMP (Linux, Apache, MySQL, PHP):
[crayon-63a0218e9e76b177478069 inline="true" ]--- - name: LAMP stack configuration hosts: all become: true tasks: - name: Ensure latest version of all required packages is installed ansible.builtin.apt: pkg: - apache2 - mariadb-server - php - php-mysql state: latest[/crayon]Organizowanie kodu automatyzacji
Wraz z upływem czasu ilość kodu w naszym projekcie będzie się powiększać, więc o ile wszystkie zadania zdefiniujemy w jednym scenariuszu, możemy sobie wyobrazić, jak trudno będzie nim zarządzać, czytać kod, analizować potencjalne problemy. Na szczęście Ansible oferuje bardzo wiele możliwości dzielenia kodu na mniejsze fragmenty.
Najważniejszą z nich jest tworzenie ról. Role umożliwiają automatyczne ładowanie powiązanych zmiennych, plików, zadań, procedur obsługi i innych artefaktów Ansible w oparciu o znaną strukturę plików. Po pogrupowaniu treści w role możemy z łatwością ponownie ich używać i udostępniać je innym użytkownikom.
Do zarządzania administrowanymi serwerami służą pliki ewidencji (inventory). Plik ewidencji może być globalny (znajdujący się w katalogu, gdzie zainstalowano Ansible) oraz lokalny, np. na potrzeby jednego projektu. Ich użycie wymaga przekazania do komendy odpowiedniej flagi. Pliki ewidencji mogą być utworzone w formacie INI lub YAML, pozwalają nam na grupowanie zarządzanych serwerów oraz definiowanie zmiennych wykorzystywanych później w scenariuszach lub komendach wykonywanych ad-hoc.
Ansible obsługuje dwa rodzaje ewidencji: statyczną oraz dynamiczną. Statyczna pozostaje niezmieniona aż do chwili, gdy będzie zmodyfikowana przez użytkownika. W przypadku ewidencji dynamicznej Ansible ma możliwość pobierania danych z wszelkich plików wykonywalnych, dane wyjściowe muszą być jednak w formacie JSON. Na szczęście w czasach, gdy dodatkowe hosty gwałtownie pojawiają się i znikają w odpowiedzi na stale rosnące wymagania biznesowe, wielu popularnych dostawców chmury takich jak Amazon AWS, Microsoft Azure, OpenStack dostarcza skrypty do zarządzania ewidencją dynamiczną.
Możemy również tworzyć własne skrypty, które będą pobierały dane do ewidencji, gdzie źródłem danych będzie niestandardowa, korporacyjna bazy danych CMDB lub katalogi LDAP. Aby wyświetlić informację o dostępnych pluginach, możemy użyć komendy ansible-doc -t inventory -l.
Przykładowe użycie pluginu aws_ec2 (Musimy upewnić się, iż w naszej sekcji [inventory] w pliku ansible.cfg będzie zmienna enable_plugins = aws_ec2):
[crayon-63a0218e9e76d977646947 inline="true" ]plugin: aws_ec2 regions: - us-east-1 - us-west-1 strict: False keyed_groups: - prefix: arch key: 'architecture' - prefix: tag key: tags - prefix: instance_type key: instance_type - key: 'security_groups|json_query("[].group_id")' prefix: 'security_groups' - key: tags.Application separator: '' - key: placement.region prefix: aws_region - key: tags['Role'] prefix: foo parent_group: "project"[/crayon]Zbieranie faktów Ansible, Jinja2
Przed przystąpieniem do wykonania zadań zawartych w scenariuszu, Ansible przy użyciu modułu setup wykonuje proces zbierania faktów, który może zostać wyłączony przez dodanie zmiennej „gather_facts: false”. Jest on bardzo istotny, ponieważ wiele modułów korzysta z zebranych w ten sposób informacji.
W zaawansowanych scenariuszach często zdarza się, iż wykorzystujemy zebrane fakty, szczególnie w instrukcjach warunkowych. By sprawdzić przykładową listę zbieranych faktów, możemy użyć komendy ansible nazwa_hosta -m setup | less. Możemy zebrać między innymi takie dane jak: interfejsy IPv4/IPv6: ansible_all_ipv4_addresses/ansible_all_ipv6_addresses, dystrybucja systemu operacyjnego: ansible_distribution/ansible_distribution_version, wersji kernela: ansible_kernel, wielkości pamięci ram na danym hoście: ansible_memtotal_mb, ilości vcpu: ansible_processor_vcpus, wersji Pythona: ansible_python_version.
Zbieranie faktów oferuje nam ogromne, wręcz nieograniczone możliwości zarządzania konfiguracją. Wyobraźmy sobie, iż w infrastrukturze składającej się z tysięcy fizycznych oraz wirtualnych hostów mamy kilka starych fizycznych maszyn posiadających 192vCPU, działających na kernelu 2.6.x pod kontrolą RedHata 6. Naszym zadaniem jest upewnienie się, iż na każdej z nich zostały ustawione odpowiednie parametry kernela. Dzięki zbieraniu faktów Ansible oraz dodaniu odpowiednich warunków w kodzie swojego scenariusza — Ansible bez problemu zrealizuje nam to zadanie na maszynach, na których chcemy, by zostało zrealizowane bez konieczności definiowania żadnych nowych zmiennych.
Ansible został stworzony w Pythonie i dziedziczy po nim silnik szablonów Jinja 2. Dzięki zastosowaniu silnika generowania szablonów możemy dynamicznie tworzyć pliki konfiguracyjne na podstawie zadanego szablonu. To potężny framework oferujący szeroki wachlarz możliwości operowania danymi i ich konwertowania. Dzięki odpowiednim filtrom Jinja2 możemy np. konwertować ciąg tekstowy na zawierający tylko małe litery, wyszukiwać dane według wzorca i zastąpić je innymi.