Przejdź do treści

Ansible: architektura i techniki użycia

🏗️ Architektura Ansible

To, co lubię w Ansible, to prostota i architektura bezagentowa:

  • 📡 model bezagentowy - wykorzystuje istniejące protokoły SSH (Linux/Unix) lub WinRM (Windows) do komunikacji z zarządzanymi hostami
  • 🧩 modularna struktura - wszystko opiera się na deklaratywnych plikach YAML: playbooki, role i inventory
  • ♾️ Idempotentność - operacje można bezpiecznie powtarzać bez ryzyka duplikowania zmian

📂 Organizacja projektu oparta na rolach

Przykład struktury opartej na rolach:

ansible-project/
├── 📁 inventory/
│   ├── 📄 development.yml      # Definicja środowiska dev
│   └── 📄 production.yml       # Definicja środowiska produkcyjnego
├── 📁 group_vars/
│   ├── 📄 all.yml              # Zmienne wspólne dla wszystkich grup
│   ├── 📄 webservers.yml       # Zmienne dla grupy serwerów webowych
│   └── 📄 dbservers.yml        # Zmienne dla grupy serwerów baz danych
├── 📁 host_vars/
│   └── 📄 specific-host.yml    # Zmienne dla konkretnego hosta
├── 📁 roles/
│   ├── 📁 common/              # Wspólna rola dla wszystkich serwerów
│   │   ├── 📁 tasks/
│   │   │   └── 📄 main.yml     # Główne zadania roli
│   │   ├── 📁 handlers/
│   │   │   └── 📄 main.yml     # Handlery
│   │   ├── 📁 templates/
│   │   │   └── 📄 ntp.conf.j2  # Szablony plików konfiguracyjnych
│   │   ├── 📁 files/
│   │   │   └── 📄 banner.txt   # Pliki statyczne
│   │   ├── 📁 vars/
│   │   │   └── 📄 main.yml     # Wewnętrzne zmienne roli
│   │   └── 📁 defaults/
│   │       └── 📄 main.yml     # Domyślne wartości zmiennych
│   ├── 📁 webserver/           # Rola dla serwerów webowych
│   └── 📁 database/            # Rola dla serwerów baz danych
├── 📄 site.yml                 # Główny playbook
├── 📄 webservers.yml           # Playbook dla serwerów webowych
└── 📄 dbservers.yml            # Playbook dla serwerów baz danych

💡 Praktyczne techniki

🔄 Delegacja zadań

Delegacja zadań pozwala na wykonywanie konkretnych operacji na innym hoście niż aktualnie przetwarzany:

- name: Zarejestruj nowy serwer w load balancerze
    shell: /usr/local/bin/register_node.sh {{ inventory_hostname }}
    delegate_to: load_balancer8
    # To zadanie zostanie wykonane na hoście load_balancer8

🗃️ Kolekcje zamiast prostych playbooków

Nie wymyślaj koła na nowo - używaj gotowych kolekcji z Ansible Galaxy:

ansible-galaxy collection install community.docker

# Użycie w playbooku
- name: Uruchom kontener PostgreSQL
    community.docker.docker_container:
        name: db
        image: postgres:13
        ports:
            - "5432:5432"

🔐 Ansible Vault dla danych wrażliwych

# Szyfrowanie plików z hasłami
ansible-vault encrypt group_vars/all/vault.yml

# Uruchamianie playbooków z zaszyfrowanymi danymi
ansible-playbook site.yml --ask-vault-pass

⚡ Optymalizacja wydajności

- hosts: all
    gather_facts: no  # wyłącz zbieranie faktów, gdy nie jest potrzebne
    # lub
    gather_subset: network  # zbieraj tylko wybrane fakty

🕵️ Tryb diff

ansible-playbook webservers.yml --diff --check

Połączenie --diff z --check pozwala zobaczyć, jakie zmiany zostaną wprowadzone bez faktycznego ich dokonywania.

🔄 Strategie wykonywania

- hosts: webservers
    strategy: free  # równoległe wykonywanie zadań bez synchronizacji
    # alternatywy: linear (domyślna), debug (interaktywna)
    tasks:
        # zadania...

🔄 Obsługa błędów i pętle

- name: Uruchom usługi
    service:
        name: "{{ item }}"
        state: started
    loop:
        - nginx
        - redis
        - postgresql
    ignore_errors: yes  # kontynuuj pomimo błędów
    register: service_result

- name: Powiadom o błędach
    mail:
        to: "admin@foobar.com"
        subject: "Błąd uruchomienia usługi"
        body: "Wystąpił problem z uruchomieniem usług"
    when: service_result.failed

🌟 Zaawansowane techniki ról

📋 zależności ról

# roles/webserver/meta/main.yml
dependencies:
    - role: common
    - role: security
        vars:
            security_level: high

🧩 Wielokrotnie używane role z parametrami

# playbook.yml
- hosts: webservers
    roles:
        - role: nginx
            vars:
                nginx_port: 80
                ssl_enabled: true

        - role: nginx
            vars:
                nginx_port: 8080
                server_name: "api.foobar.com"

🔍 Dynamiczne inventory

Zamiast statycznych list hostów, możesz użyć dynamiczne inventory dla infrastruktury chmurowej:

# AWS EC2
ansible-playbook -i inventory_aws_ec2.yml site.yml

# Azure
ansible-playbook -i inventory_azure_rm.yml site.yml

🚦 Sterowanie - obsługa warunkowa

- name: Instaluj pakiety specyficzne dla dystrybucji
    include_tasks: "{{ ansible_os_family | lower }}.yml"
    # automatycznie ładuje debian.yml lub redhat.yml w zależności od systemu

📈 Monitorowanie i debugowanie

🔍 Debugowanie zmiennych

- name: Wyświetl informacje o hoście
    debug:
        var: ansible_facts
        verbosity: 1  # wyświetla tylko z poziomem -v lub wyższym

📊 Wtyczki callback

# ansible.cfg
[defaults]
callback_whitelist = profile_tasks, timer

To włączy wyświetlanie czasu wykonania dla poszczególnych zadań.

🏆 Najlepsze praktyki

  1. 📦 utrzymuj małe, wyspecjalizowane role - każda rola generalnie powinna mieć jeden konkretny cel
  2. 🔄 testuj role w izolacji - używaj molecule do testowania ról
  3. 📝 dokumentuj zmienne - używaj komentarzy w plikach defaults/main.yml
  4. 🔒 nigdy nie przechowuj poświadczeń w postaci zwykłego tekstu - zawsze używaj ansible vault lub innej pochodnej vault'a
  5. 🔧 używaj tagów do selektywnego wykonywania - ansible-playbook site.yml --tags "configuration,packages"
  6. 🧪 sprawdzaj zmiany przed wdrożeniem - używaj --check i --diff

🚀 Podsumowanie

Ansible umożliwia automatyzację infrastruktury bez nadmiernej złożoności. Podejście oparte na rolach zapewnia modułowość, ponowne wykorzystanie kodu i łatwiejsze zarządzanie. Dzięki delegacji zadań, kolekcjom i strategiom wykonywania możesz tworzyć elastyczne i wydajne rozwiązania automatyzacji.


🔗 Przydatne zasoby: