Przejdź do treści
DevOps

Ansible - Automatyzacja konfiguracji serwerów

Opublikowano:
·6 min czytania·Autor: MDS Software Solutions Group

Ansible Automatyzacja konfiguracji

devops

Ansible - Automatyzacja konfiguracji serwerow

Zarzadzanie infrastruktura serwerowa recznie to droga donikad. Kazdy administrator, ktory kiedykolwiek konfigurowel dziesiatki serwerow wie, ze powtarzalne czynnosci pochlaniaaja ogromna ilosc czasu i sa podatne na bledy. Ansible, stworzone przez Michaela DeHaana i obecnie rozwijane przez Red Hat, rozwiazuje ten problem w sposob elegancki i prosty. W tym przewodniku przedstawimy wszystko, co musisz wiedziec, aby skutecznie automatyzowac konfiguracje serwerow za pomoca Ansible.

Czym jest Ansible?#

Ansible to narzedzie do automatyzacji IT typu open-source, ktore umozliwia zarzadzanie konfiguracja, wdrazanie aplikacji oraz orkiestracje infrastruktury. W przeciwienstwie do wielu innych narzedzi, Ansible wyroznia sie prostota - uzywa jezyka YAML do definiowania zadan, co sprawia, ze playbooki sa czytelne nawet dla osob bez doswiadczenia programistycznego.

Glowne zastosowania Ansible obejmuja:

  • Zarzadzanie konfiguracja - instalacja pakietow, konfiguracja uslug, zarzadzanie plikami
  • Wdrazanie aplikacji - automatyczne deploymenty na wielu serwerach jednoczesnie
  • Orkiestracja - koordynacja zlozonych procesow wieloetapowych
  • Prowizjonowanie - przygotowanie nowych serwerow od zera
  • Bezpieczenstwo i compliance - egzekwowanie polityk bezpieczenstwa

Architektura bezagentowa (Agentless)#

Jednym z najwazniejszych wyroznikow Ansible jest jego architektura bezagentowa. Oznacza to, ze na zarzadzanych serwerach nie trzeba instalowac zadnego dodatkowego oprogramowania. Ansible komunikuje sie z maszynami docelowymi wylacznie przez SSH (dla systemow Linux/Unix) lub WinRM (dla systemow Windows).

Ta architektura niesie ze soba wiele korzysci:

  • Brak narzutu - nie ma agentow zuzywaajacych zasoby na serwerach docelowych
  • Brak dodatkowego utrzymania - nie trzeba aktualizowac agentow na setkach maszyn
  • Bezpieczenstwo - mniejsza powierzchnia ataku, brak otwartych portow dla agentow
  • Latwy poczatek - wystarczy SSH i Python na maszynach docelowych
# Wymagania na maszynach docelowych:
# - Serwer SSH (OpenSSH)
# - Python 3.x
# - Uzytkownik z uprawnieniami sudo (opcjonalnie)

Na maszynie kontrolnej (z ktorej uruchamiamy Ansible) potrzebujemy jedynie zainstalowac sam Ansible:

# Instalacja na Ubuntu/Debian
sudo apt update
sudo apt install ansible

# Instalacja przez pip
pip install ansible

# Instalacja na CentOS/RHEL
sudo dnf install ansible-core

# Weryfikacja instalacji
ansible --version

Plik inwentarza (Inventory)#

Inwentarz to plik definiujacy hosty i grupy hostow, na ktorych Ansible bedzie wykonywal zadania. Domyslnie Ansible szuka pliku /etc/ansible/hosts, ale mozna wskazac dowolny plik za pomoca flagi -i.

# inventory.ini - format INI

[webservers]
web1.example.com
web2.example.com
web3.example.com ansible_port=2222

[dbservers]
db1.example.com ansible_user=dbadmin
db2.example.com

[loadbalancers]
lb1.example.com

[production:children]
webservers
dbservers
loadbalancers

[webservers:vars]
http_port=80
max_clients=200

Inwentarz mozna rowniez definiowac w formacie YAML, co daje wiecej mozliwosci:

# inventory.yml - format YAML
all:
  children:
    webservers:
      hosts:
        web1.example.com:
          http_port: 80
        web2.example.com:
          http_port: 8080
      vars:
        ansible_user: deploy
        nginx_version: "1.24"
    dbservers:
      hosts:
        db1.example.com:
          postgresql_version: "16"
        db2.example.com:
          postgresql_version: "16"
      vars:
        ansible_user: dbadmin
    production:
      children:
        webservers:
        dbservers:

Playbooki i zadania (Playbooks & Tasks)#

Playbooki to serce Ansible. Sa to pliki YAML definiujace serie zadan do wykonania na okreslonych grupach hostow. Kazdy playbook sklada sie z jednego lub wiecej "play", a kazdy play zawiera liste taskow.

# site.yml - przykladowy playbook
---
- name: Konfiguracja serwerow webowych
  hosts: webservers
  become: yes
  vars:
    app_name: mojaaplikacja
    app_port: 8080

  tasks:
    - name: Aktualizacja cache apt
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Instalacja wymaganych pakietow
      apt:
        name:
          - nginx
          - curl
          - git
          - ufw
        state: present

    - name: Uruchomienie i wlaczenie Nginx
      service:
        name: nginx
        state: started
        enabled: yes

    - name: Otwarcie portu HTTP w firewallu
      ufw:
        rule: allow
        port: "80"
        proto: tcp

    - name: Otwarcie portu HTTPS w firewallu
      ufw:
        rule: allow
        port: "443"
        proto: tcp

Uruchomienie playbooka:

# Podstawowe uruchomienie
ansible-playbook -i inventory.ini site.yml

# Z podaniem hasla sudo
ansible-playbook -i inventory.ini site.yml --ask-become-pass

# Dry run (sprawdzenie bez wykonania zmian)
ansible-playbook -i inventory.ini site.yml --check

# Ograniczenie do konkretnego hosta
ansible-playbook -i inventory.ini site.yml --limit web1.example.com

# Ze zwiekszonym poziomem logowania
ansible-playbook -i inventory.ini site.yml -vvv

Moduly Ansible#

Moduly to jednostki pracy w Ansible. Kazdy modul realizuje konkretne zadanie. Ansible posiada setki wbudowanych modulow. Oto najczesciej uzywane:

Modul apt/yum - zarzadzanie pakietami#

# Dla systemow Debian/Ubuntu
- name: Instalacja wielu pakietow
  apt:
    name:
      - nginx
      - postgresql
      - python3-pip
      - certbot
    state: present
    update_cache: yes

# Dla systemow CentOS/RHEL
- name: Instalacja pakietow na CentOS
  yum:
    name:
      - httpd
      - mariadb-server
      - php
    state: latest

# Usuniecie pakietu
- name: Usuniecie pakietu Apache
  apt:
    name: apache2
    state: absent
    purge: yes

Modul copy - kopiowanie plikow#

- name: Skopiowanie pliku konfiguracyjnego
  copy:
    src: files/nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: "0644"
    backup: yes

- name: Utworzenie pliku z zawartoscia
  copy:
    content: |
      # Konfiguracja aplikacji
      APP_ENV=production
      APP_DEBUG=false
      APP_PORT=8080
    dest: /etc/myapp/.env
    owner: www-data
    group: www-data
    mode: "0600"

Modul template - szablony Jinja2#

- name: Wdrozenie konfiguracji Nginx z szablonu
  template:
    src: templates/nginx-vhost.conf.j2
    dest: "/etc/nginx/sites-available/{{ app_name }}"
    owner: root
    group: root
    mode: "0644"
  notify: Restart Nginx

Modul service - zarzadzanie uslugami#

- name: Restart i wlaczenie PostgreSQL
  service:
    name: postgresql
    state: restarted
    enabled: yes

- name: Zatrzymanie Apache (jesli jest zainstalowany)
  service:
    name: apache2
    state: stopped
    enabled: no
  ignore_errors: yes

Zmienne i szablony Jinja2#

System szablonow Jinja2 jest fundamentalnym elementem Ansible. Pozwala na dynamiczne generowanie plikow konfiguracyjnych w oparciu o zmienne.

# group_vars/webservers.yml
---
nginx_worker_processes: auto
nginx_worker_connections: 1024
server_name: "{{ inventory_hostname }}"
app_root: /var/www/{{ app_name }}
php_version: "8.3"
php_memory_limit: "256M"
php_max_execution_time: 30
ssl_enabled: true
ssl_certificate: "/etc/letsencrypt/live/{{ server_name }}/fullchain.pem"
ssl_certificate_key: "/etc/letsencrypt/live/{{ server_name }}/privkey.pem"

Przykladowy szablon Jinja2 dla konfiguracji Nginx:

{# templates/nginx-vhost.conf.j2 #}
server {
    listen 80;
    server_name {{ server_name }};

{% if ssl_enabled %}
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name {{ server_name }};

    ssl_certificate {{ ssl_certificate }};
    ssl_certificate_key {{ ssl_certificate_key }};
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
{% endif %}

    root {{ app_root }}/public;
    index index.php index.html;

    access_log /var/log/nginx/{{ app_name }}_access.log;
    error_log /var/log/nginx/{{ app_name }}_error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php{{ php_version }}-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}

Jinja2 oferuje rowniez zaawansowane konstrukcje:

{# Petle i warunki w szablonach #}
{% for upstream_server in upstream_servers %}
    server {{ upstream_server }}:{{ app_port }} weight=1;
{% endfor %}

{% if environment == 'production' %}
    error_page 500 502 503 504 /50x.html;
{% else %}
    # W srodowisku deweloperskim pokazujemy szczegolowe bledy
{% endif %}

Handlery (Handlers)#

Handlery to specjalne taski, ktore wykonuja sie tylko wtedy, gdy zostana wywolane przez dyrektywe notify. Sa idealne do restartowania uslug po zmianie konfiguracji:

---
- name: Konfiguracja Nginx
  hosts: webservers
  become: yes

  tasks:
    - name: Wdrozenie konfiguracji Nginx
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify:
        - Walidacja konfiguracji Nginx
        - Restart Nginx

    - name: Wdrozenie konfiguracji PHP-FPM
      template:
        src: templates/php-fpm.conf.j2
        dest: "/etc/php/{{ php_version }}/fpm/pool.d/www.conf"
      notify: Restart PHP-FPM

  handlers:
    - name: Walidacja konfiguracji Nginx
      command: nginx -t
      changed_when: false

    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

    - name: Restart PHP-FPM
      service:
        name: "php{{ php_version }}-fpm"
        state: restarted

Wazna cecha handlerow jest to, ze wykonuja sie tylko raz na koncu play, nawet jesli zostana wywolane wielokrotnie. Gwarantuje to, ze usluga nie bedzie restartowana wielokrotnie niepotrzebnie.

Role i Ansible Galaxy#

Role to sposob na organizacje i ponowne wykorzystanie kodu Ansible. Rola grupuje taski, handlery, zmienne, szablony i pliki w ustrukturyzowany sposob.

# Struktura roli
roles/
  webserver/
    tasks/
      main.yml
    handlers/
      main.yml
    templates/
      nginx-vhost.conf.j2
    files/
      ssl-params.conf
    vars/
      main.yml
    defaults/
      main.yml
    meta/
      main.yml
# roles/webserver/tasks/main.yml
---
- name: Instalacja Nginx
  apt:
    name: nginx
    state: present
    update_cache: yes

- name: Instalacja PHP i rozszerzen
  apt:
    name:
      - "php{{ php_version }}-fpm"
      - "php{{ php_version }}-cli"
      - "php{{ php_version }}-pgsql"
      - "php{{ php_version }}-mbstring"
      - "php{{ php_version }}-xml"
      - "php{{ php_version }}-curl"
      - "php{{ php_version }}-zip"
    state: present

- name: Konfiguracja virtual host
  template:
    src: nginx-vhost.conf.j2
    dest: "/etc/nginx/sites-available/{{ app_name }}"
  notify: Restart Nginx

- name: Aktywacja virtual host
  file:
    src: "/etc/nginx/sites-available/{{ app_name }}"
    dest: "/etc/nginx/sites-enabled/{{ app_name }}"
    state: link
  notify: Restart Nginx

- name: Usuniecie domyslnej konfiguracji
  file:
    path: /etc/nginx/sites-enabled/default
    state: absent
  notify: Restart Nginx
# roles/webserver/defaults/main.yml
---
php_version: "8.3"
app_name: myapp
app_port: 8080
nginx_worker_processes: auto
ssl_enabled: false

Ansible Galaxy to repozytorium spolecznosciowych rol i kolekcji:

# Instalacja roli z Galaxy
ansible-galaxy install geerlingguy.nginx
ansible-galaxy install geerlingguy.postgresql
ansible-galaxy install geerlingguy.php

# Instalacja rol z pliku requirements
ansible-galaxy install -r requirements.yml

# Tworzenie szkieletu nowej roli
ansible-galaxy init moja_nowa_rola
# requirements.yml
---
roles:
  - name: geerlingguy.nginx
    version: "3.2.0"
  - name: geerlingguy.postgresql
    version: "3.4.0"
  - name: geerlingguy.php
    version: "6.0.0"
  - name: geerlingguy.certbot
    version: "4.1.0"

collections:
  - name: community.postgresql
    version: "3.2.0"
  - name: ansible.posix
    version: "1.5.0"

Uzycie rol w playbooku:

# site.yml
---
- name: Prowizjonowanie serwera webowego
  hosts: webservers
  become: yes
  vars:
    app_name: produkcja
    php_version: "8.3"

  roles:
    - role: geerlingguy.nginx
    - role: geerlingguy.php
      vars:
        php_packages:
          - "php{{ php_version }}-fpm"
          - "php{{ php_version }}-pgsql"
    - role: webserver

- name: Konfiguracja bazy danych
  hosts: dbservers
  become: yes

  roles:
    - role: geerlingguy.postgresql
      vars:
        postgresql_version: "16"

Praktyczny przyklad - prowizjonowanie serwera Nginx + PHP + PostgreSQL#

Ponizej kompletny playbook prowizjonujacy serwer produkcyjny z pelnym stosem technologicznym:

# provision-webserver.yml
---
- name: Prowizjonowanie serwera produkcyjnego
  hosts: webservers
  become: yes
  vars:
    app_name: mojaplikacja
    app_user: deploy
    app_root: "/var/www/{{ app_name }}"
    php_version: "8.3"
    node_version: "20"
    postgresql_version: "16"
    db_name: "{{ app_name }}_production"
    db_user: "{{ app_name }}_user"
    db_password: "{{ vault_db_password }}"
    server_name: app.example.com

  tasks:
    # === PODSTAWOWA KONFIGURACJA ===
    - name: Aktualizacja systemu
      apt:
        upgrade: dist
        update_cache: yes
        cache_valid_time: 3600

    - name: Instalacja podstawowych pakietow
      apt:
        name:
          - curl
          - git
          - unzip
          - ufw
          - fail2ban
          - htop
          - supervisor
        state: present

    - name: Utworzenie uzytkownika aplikacji
      user:
        name: "{{ app_user }}"
        shell: /bin/bash
        groups: www-data
        append: yes
        create_home: yes

    # === FIREWALL ===
    - name: Konfiguracja UFW - domyslna polityka
      ufw:
        direction: incoming
        policy: deny

    - name: UFW - zezwolenie na SSH
      ufw:
        rule: allow
        port: "22"
        proto: tcp

    - name: UFW - zezwolenie na HTTP/HTTPS
      ufw:
        rule: allow
        port: "{{ item }}"
        proto: tcp
      loop:
        - "80"
        - "443"

    - name: Wlaczenie UFW
      ufw:
        state: enabled

    # === NGINX ===
    - name: Instalacja Nginx
      apt:
        name: nginx
        state: present

    - name: Wdrozenie konfiguracji Nginx
      template:
        src: templates/nginx-vhost.conf.j2
        dest: "/etc/nginx/sites-available/{{ app_name }}"
      notify: Restart Nginx

    - name: Aktywacja strony
      file:
        src: "/etc/nginx/sites-available/{{ app_name }}"
        dest: "/etc/nginx/sites-enabled/{{ app_name }}"
        state: link
      notify: Restart Nginx

    # === PHP ===
    - name: Dodanie repozytorium PHP
      apt_repository:
        repo: "ppa:ondrej/php"
        state: present

    - name: Instalacja PHP i rozszerzen
      apt:
        name:
          - "php{{ php_version }}-fpm"
          - "php{{ php_version }}-cli"
          - "php{{ php_version }}-pgsql"
          - "php{{ php_version }}-mbstring"
          - "php{{ php_version }}-xml"
          - "php{{ php_version }}-curl"
          - "php{{ php_version }}-zip"
          - "php{{ php_version }}-gd"
          - "php{{ php_version }}-intl"
          - "php{{ php_version }}-redis"
        state: present
        update_cache: yes

    - name: Konfiguracja PHP-FPM
      template:
        src: templates/php-fpm-pool.conf.j2
        dest: "/etc/php/{{ php_version }}/fpm/pool.d/{{ app_name }}.conf"
      notify: Restart PHP-FPM

    # === POSTGRESQL ===
    - name: Instalacja PostgreSQL
      apt:
        name:
          - "postgresql-{{ postgresql_version }}"
          - "postgresql-client-{{ postgresql_version }}"
          - python3-psycopg2
        state: present

    - name: Uruchomienie PostgreSQL
      service:
        name: postgresql
        state: started
        enabled: yes

    - name: Utworzenie bazy danych
      become_user: postgres
      community.postgresql.postgresql_db:
        name: "{{ db_name }}"
        encoding: UTF-8
        lc_collate: pl_PL.UTF-8
        lc_ctype: pl_PL.UTF-8

    - name: Utworzenie uzytkownika bazy danych
      become_user: postgres
      community.postgresql.postgresql_user:
        name: "{{ db_user }}"
        password: "{{ db_password }}"
        db: "{{ db_name }}"
        priv: ALL
        state: present

    # === KATALOG APLIKACJI ===
    - name: Utworzenie katalogu aplikacji
      file:
        path: "{{ app_root }}"
        state: directory
        owner: "{{ app_user }}"
        group: www-data
        mode: "0755"

    - name: Utworzenie katalogow storage
      file:
        path: "{{ app_root }}/{{ item }}"
        state: directory
        owner: "{{ app_user }}"
        group: www-data
        mode: "0775"
      loop:
        - storage
        - storage/logs
        - storage/cache
        - storage/uploads

    # === SSL (Certbot) ===
    - name: Instalacja Certbot
      apt:
        name:
          - certbot
          - python3-certbot-nginx
        state: present

    - name: Uzyskanie certyfikatu SSL
      command: >
        certbot certonly --nginx
        -d {{ server_name }}
        --non-interactive
        --agree-tos
        --email admin@example.com
      args:
        creates: "/etc/letsencrypt/live/{{ server_name }}/fullchain.pem"

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

    - name: Restart PHP-FPM
      service:
        name: "php{{ php_version }}-fpm"
        state: restarted

Wdrazanie aplikacji z Ansible#

Ansible doskonale nadaje sie do automatyzacji procesu wdrazania (deploymentu) aplikacji:

# deploy.yml
---
- name: Wdrazanie aplikacji
  hosts: webservers
  become: yes
  become_user: deploy
  vars:
    app_name: mojaplikacja
    app_root: /var/www/mojaplikacja
    repo_url: "git@github.com:firma/mojaplikacja.git"
    branch: main
    release_dir: "{{ app_root }}/releases/{{ ansible_date_time.epoch }}"
    shared_dir: "{{ app_root }}/shared"
    current_link: "{{ app_root }}/current"

  tasks:
    - name: Utworzenie katalogu release
      file:
        path: "{{ release_dir }}"
        state: directory

    - name: Klonowanie repozytorium
      git:
        repo: "{{ repo_url }}"
        dest: "{{ release_dir }}"
        version: "{{ branch }}"
        depth: 1
        accept_hostkey: yes

    - name: Instalacja zaleznosci Composer
      composer:
        command: install
        working_dir: "{{ release_dir }}"
        no_dev: yes
        optimize_autoloader: yes

    - name: Linkowanie katalogow wspoldzielonych
      file:
        src: "{{ shared_dir }}/{{ item }}"
        dest: "{{ release_dir }}/{{ item }}"
        state: link
        force: yes
      loop:
        - .env
        - storage
        - node_modules

    - name: Migracja bazy danych
      command: php artisan migrate --force
      args:
        chdir: "{{ release_dir }}"

    - name: Budowanie assetow front-end
      command: npm run build
      args:
        chdir: "{{ release_dir }}"

    - name: Czyszczenie cache
      command: "php artisan {{ item }}"
      args:
        chdir: "{{ release_dir }}"
      loop:
        - cache:clear
        - config:cache
        - route:cache
        - view:cache

    - name: Przelaczenie symlinku na nowy release
      file:
        src: "{{ release_dir }}"
        dest: "{{ current_link }}"
        state: link
        force: yes

    - name: Restart PHP-FPM
      become_user: root
      service:
        name: "php8.3-fpm"
        state: restarted

    - name: Usuniecie starych release'ow (zostawiamy 5 ostatnich)
      shell: |
        ls -dt {{ app_root }}/releases/*/ | tail -n +6 | xargs rm -rf
      args:
        warn: false
      changed_when: false

Idempotentnosc - kluczowa cecha Ansible#

Idempotentnosc oznacza, ze wielokrotne uruchomienie tego samego playbooka daje identyczny rezultat. Ansible sprawdza biezacy stan systemu i wykonuje tylko te zmiany, ktore sa konieczne:

# Ten task jest idempotentny - jesli pakiet jest juz zainstalowany,
# Ansible nie podejmie zadnej akcji
- name: Instalacja Nginx
  apt:
    name: nginx
    state: present
  # Wynik: "ok" jesli juz zainstalowany, "changed" jesli zainstalowany teraz

# Ten task NIE jest idempotentny - zawsze sie wykona
- name: Restart aplikacji (zly przyklad)
  command: systemctl restart nginx
  # Wynik: zawsze "changed"

# Lepsze podejscie - idempotentne
- name: Upewnienie sie, ze Nginx dziala
  service:
    name: nginx
    state: started
  # Wynik: "ok" jesli juz dziala, "changed" jesli uruchomiony teraz

Dzieki idempotentnosci mozna bezpiecznie uruchamiac playbooki wielokrotnie bez obawy o niechciane efekty uboczne. Jest to kluczowa roznica miedzy Ansible a tradycyjnymi skryptami bash.

Ansible vs Puppet vs Chef#

| Cecha | Ansible | Puppet | Chef | |-------|---------|--------|------| | Architektura | Bezagentowa (SSH) | Agent na kazdym hoście | Agent na kazdym hoscie | | Jezyk konfiguracji | YAML | Puppet DSL | Ruby DSL | | Krzywa uczenia | Lagodna | Srednia | Stroma | | Idempotentnosc | Tak | Tak | Tak | | Push vs Pull | Push (domyslnie) | Pull | Pull | | Spolecznosc | Bardzo duza | Duza | Srednia | | Najlepsze dla | Wdrazan i orkiestracji | Zarzadzania konfiguracja | Zlozonych srodowisk |

Ansible wygrywa prostota i niskim progiem wejscia. Nie wymaga nauki dedykowanego jezyka programowania, a playbooki YAML sa czytelne dla kazdego czlonka zespolu. Puppet i Chef moga byc lepszym wyborem w bardzo duzych, statycznych srodowiskach, gdzie model pull jest bardziej odpowiedni.

Ansible Tower / AWX#

Ansible Tower (komercyjny) i AWX (open-source) to platformy webowe do zarzadzania Ansible w skali organizacji:

# Przykladowy job template w Tower/AWX
# Definiowany przez API lub interfejs webowy:
#
# - Nazwa: "Deploy Production"
# - Playbook: deploy.yml
# - Inventory: Production
# - Credentials: SSH Key + Vault Password
# - Schedule: On-demand
# - Notifications: Slack #deployments
# - RBAC: Tylko zespol DevOps

Glowne funkcje Tower/AWX:

  • Interfejs webowy - wizualne zarzadzanie playbookami i inwentarzami
  • Kontrola dostepu (RBAC) - granularne uprawnienia dla zespolow
  • Harmonogramy - automatyczne uruchamianie playbookow
  • Powiadomienia - integracja ze Slack, email, webhooks
  • API REST - pelna automatyzacja przez API
  • Audyt - pelen log kto, co i kiedy uruchomil

Integracja z CI/CD#

Ansible doskonale integruje sie z popularnymi narzedzami CI/CD:

# .github/workflows/deploy.yml - GitHub Actions
name: Deploy to Production
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Instalacja Ansible
        run: pip install ansible

      - name: Konfiguracja klucza SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts

      - name: Uruchomienie playbooka deploy
        run: |
          ansible-playbook \
            -i "${{ secrets.SERVER_IP }}," \
            --user deploy \
            --extra-vars "branch=${{ github.sha }}" \
            deploy.yml
        env:
          ANSIBLE_HOST_KEY_CHECKING: "false"
# .gitlab-ci.yml - GitLab CI
stages:
  - test
  - deploy

deploy_production:
  stage: deploy
  image: python:3.11
  only:
    - main
  before_script:
    - pip install ansible
    - mkdir -p ~/.ssh
    - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
    - chmod 600 ~/.ssh/id_rsa
  script:
    - ansible-playbook -i inventory/production deploy.yml
  environment:
    name: production
    url: https://app.example.com

Dobre praktyki#

Na zakonczenie, kilka sprawdzonych praktyk pracy z Ansible:

  1. Uzywaj Ansible Vault do przechowywania hasel i sekretow:
ansible-vault create secrets.yml
ansible-vault edit secrets.yml
ansible-playbook site.yml --ask-vault-pass
  1. Strukturyzuj projekt wedlug oficjalnych zalecen:
project/
  inventory/
    production/
    staging/
  group_vars/
  host_vars/
  roles/
  playbooks/
  ansible.cfg
  requirements.yml
  1. Testuj playbooki za pomoca Molecule i ansible-lint:
pip install molecule ansible-lint
ansible-lint site.yml
molecule test
  1. Uzywaj tagow do selektywnego uruchamiania taskow:
- name: Instalacja Nginx
  apt:
    name: nginx
    state: present
  tags: [nginx, install]
  1. Stosuj zmienne srodowiskowe zamiast hardkodowanych wartosci.

  2. Pisz czytelne nazwy taskow - kazdy task powinien miec opisowa nazwe.

Podsumowanie#

Ansible to niezastapione narzedzie w arsenakie kazdego zespolu DevOps. Dzieki prostej skladni YAML, architekturze bezagentowej i ogromnej bibliotece modulow pozwala na szybka i niezawodna automatyzacje infrastruktury. Niezaleznie od tego, czy zarzadzasz jednym serwerem, czy setkami maszyn, Ansible pomoze Ci zaoszczedzic czas i wyeliminowac bledy wynikajace z recznej konfiguracji.

Kluczowe wnioski:

  • Prostota - YAML jest czytelny dla kazdego
  • Bezagentowosc - brak dodatkowego oprogramowania na serwerach
  • Idempotentnosc - bezpieczne wielokrotne uruchamianie
  • Skalowalnosc - od jednego serwera do tysiecy maszyn
  • Spolecznosc - ogromna baza rol i kolekcji w Galaxy

Potrzebujesz pomocy z automatyzacja infrastruktury?#

W MDS Software Solutions Group specjalizujemy sie w automatyzacji infrastruktury i procesow DevOps. Oferujemy:

  • Projektowanie i wdrazanie automatyzacji z Ansible
  • Konfiguracje pipeline'ow CI/CD
  • Audyt i optymalizacje istniejaacej infrastruktury
  • Migracje do chmury (Azure, AWS, GCP)
  • Szkolenia z Ansible i praktyk DevOps
  • Wsparcie i utrzymanie infrastruktury 24/7

Skontaktuj sie z nami, aby omowic automatyzacje Twojej infrastruktury!

Autor
MDS Software Solutions Group

Zespół ekspertów programistycznych specjalizujących się w nowoczesnych technologiach webowych.

Ansible - Automatyzacja konfiguracji serwerów | MDS Software Solutions Group | MDS Software Solutions Group