 Autor: [Tomasz Nowosielski](/autorzy/tomasz-nowosielski) Redaktor naczelny, analityk hostingu · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  Ansible Playbook — automatyzacja serwera

# Ansible Playbook — automatyzacja konfiguracji serwera

Opublikowano: 9 kwietnia 2026 · Kategoria: DevOps

Konfiguracja nowego VPS ręcznie to strata czasu i źródło błędów. Zrób to raz przez Ansible Playbook — potem każdy nowy serwer konfigurujesz jedną komendą. Oto jak pisać playbooki od podstaw do zaawansowanych roles.

## Instalacja Ansible

\# Ubuntu/Debian (control node — maszyna z której uruchamiasz Ansible)
sudo apt update && sudo apt install ansible

# macOS
brew install ansible

# pip (zawsze aktualna wersja)
pip3 install ansible

# Sprawdź wersję
ansible --version

## Inventory — lista serwerów

Inventory (hosts.ini lub hosts.yaml) definiuje serwery i ich grupy. Ansible łączy się z nimi przez SSH:

\# hosts.ini

\[webservers\]
web1.example.com ansible\_user=root ansible\_port=22
web2.example.com ansible\_user=ubuntu ansible\_ssh\_private\_key\_file=~/.ssh/id\_rsa

\[databases\]
db1.example.com ansible\_user=root

\[all:vars\]
ansible\_python\_interpreter=/usr/bin/python3

\# Test połączenia z wszystkimi hostami
ansible -i hosts.ini all -m ping

# Test konkretnej grupy
ansible -i hosts.ini webservers -m ping

## Struktura playbooka YAML

Playbook to plik YAML z listą play'ów. Każdy play ma: `hosts` (cel), `tasks` (lista zadań), opcjonalnie `vars`, `handlers`, `roles`:

\# site.yaml — podstawowa struktura

---
- name: Konfiguracja serwera web
  hosts: webservers
  become: yes          # sudo
  vars:
    domain: example.com
    php\_version: "8.3"
    db\_user: appuser
    db\_name: myapp

  handlers:
    - name: reload nginx
      service:
        name: nginx
        state: reloaded

    - name: reload php-fpm
      service:
        name: "php{{ php\_version }}-fpm"
        state: reloaded

  tasks:
    - name: Update apt cache
      apt:
        update\_cache: yes
        cache\_valid\_time: 3600

    - name: Install Nginx
      apt:
        name: nginx
        state: present
      notify: reload nginx

## Przykład playbooka: LEMP + UFW + Certbot

\# lemp-setup.yaml

---
- name: Konfiguracja stosu LEMP
  hosts: webservers
  become: yes
  vars:
    domain: "example.com"
    php\_version: "8.3"
    letsencrypt\_email: "admin@example.com"
    db\_root\_password: "{{ vault\_db\_root\_password }}"

  tasks:
    # --- Nginx ---
    - name: Zainstaluj Nginx
      apt:
        name: nginx
        state: present

    - name: Uruchom i włącz Nginx
      service:
        name: nginx
        state: started
        enabled: yes

    # --- PHP-FPM ---
    - name: Zainstaluj PHP i rozszerzenia
      apt:
        name:
          - "php{{ php\_version }}-fpm"
          - "php{{ php\_version }}-mysql"
          - "php{{ php\_version }}-curl"
          - "php{{ php\_version }}-gd"
          - "php{{ php\_version }}-mbstring"
          - "php{{ php\_version }}-xml"
          - "php{{ php\_version }}-zip"
        state: present

    # --- MySQL ---
    - name: Zainstaluj MySQL Server
      apt:
        name: mysql-server
        state: present

    # --- UFW Firewall ---
    - name: Pozwól SSH przez UFW
      ufw:
        rule: allow
        name: OpenSSH

    - name: Pozwól HTTP i HTTPS
      ufw:
        rule: allow
        port: "{{ item }}"
        proto: tcp
      loop:
        - "80"
        - "443"

    - name: Włącz UFW
      ufw:
        state: enabled
        policy: deny

    # --- Certbot ---
    - name: Zainstaluj snapd
      apt:
        name: snapd
        state: present

    - name: Zainstaluj certbot przez snap
      snap:
        name: certbot
        classic: yes

    - name: Utwórz symlink certbot
      file:
        src: /snap/bin/certbot
        dest: /usr/bin/certbot
        state: link

    - name: Uzyskaj certyfikat SSL
      command: >
        certbot --nginx -d {{ domain }} -d www.{{ domain }}
        --non-interactive --agree-tos -m {{ letsencrypt\_email }}
      args:
        creates: /etc/letsencrypt/live/{{ domain }}/fullchain.pem

\# Uruchomienie playbooka
ansible-playbook -i hosts.ini lemp-setup.yaml

# Dry-run (sprawdź co by się zmieniło bez zmian)
ansible-playbook -i hosts.ini lemp-setup.yaml --check

# Verbose output
ansible-playbook -i hosts.ini lemp-setup.yaml -v

# Tylko jeden tag
ansible-playbook -i hosts.ini lemp-setup.yaml --tags "nginx,php"

## Variables i Jinja2 templates

\# templates/nginx.conf.j2 — szablon Jinja2

server {
    listen 80;
    server\_name {{ domain }} www.{{ domain }};
    return 301 https://$host$request\_uri;
}

server {
    listen 443 ssl http2;
    server\_name {{ domain }};
    root /var/www/{{ domain }}/html;

    ssl\_certificate /etc/letsencrypt/live/{{ domain }}/fullchain.pem;
    ssl\_certificate\_key /etc/letsencrypt/live/{{ domain }}/privkey.pem;

    # PHP-FPM
    location ~ \\.php$ {
        fastcgi\_pass unix:/var/run/php/php{{ php\_version }}-fpm.sock;
        include fastcgi\_params;
        fastcgi\_param SCRIPT\_FILENAME $document\_root$fastcgi\_script\_name;
    }
}

\# Task używający szablonu
- name: Kopiuj konfigurację Nginx
  template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/sites-available/{{ domain }}
    owner: root
    group: root
    mode: '0644'
  notify: reload nginx

## Roles — organizacja złożonych playbooków

\# Struktura katalogów dla roles
roles/
  nginx/
    tasks/main.yml
    handlers/main.yml
    templates/nginx.conf.j2
    defaults/main.yml    # Domyślne wartości zmiennych
    vars/main.yml        # Przesłaniają defaults
  php/
    tasks/main.yml
    handlers/main.yml
  mysql/
    tasks/main.yml

# Pobranie gotowej roli z Ansible Galaxy
ansible-galaxy install geerlingguy.nginx
ansible-galaxy install geerlingguy.mysql

# site.yaml używający roles
---
- name: Serwer web
  hosts: webservers
  become: yes
  roles:
    - nginx
    - php
    - role: mysql
      vars:
        mysql\_root\_password: "tajne\_haslo"

## Ansible Vault — szyfrowanie sekretów

\# Zaszyfruj plik z sekretami
ansible-vault encrypt group\_vars/all/vault.yml

# Edytuj zaszyfrowany plik
ansible-vault edit group\_vars/all/vault.yml

# Uruchom playbook z vault password
ansible-playbook -i hosts.ini site.yaml --ask-vault-pass

# Lub z plikiem hasła (w .gitignore!)
ansible-playbook -i hosts.ini site.yaml --vault-password-file ~/.vault\_pass

**Tip:** Nigdy nie commituj niezaszyfrowanych haseł do git. Używaj `ansible-vault` dla wszystkich sekretów i dodaj `*.vault.yml` do `.gitignore` jeśli nie korzystasz z szyfrowania.

## Najczęstsze pytania

Co to jest idempotentność w Ansible i dlaczego jest ważna? +

Idempotentność oznacza że uruchomienie playbooka wielokrotnie daje ten sam wynik co uruchomienie raz. Jeśli Nginx jest już zainstalowany, task "apt install nginx" zwróci "ok" zamiast ponownie instalować. Dzięki temu możesz bezpiecznie uruchamiać playbook przy każdym provisjonowaniu lub po zmianach — Ansible zmienia tylko to co faktycznie wymaga zmiany. Większość modułów Ansible (apt, copy, template, service) jest idempotentna z natury. Zadania shellowe (shell:, command:) NIE są idempotentne — używaj ich ostrożnie lub dodaj "creates:" / "when:".

Czym różni się Ansible od Terraform? +

Terraform to narzędzie Infrastructure as Code (IaC) — tworzy i zarządza infrastrukturą (VPS, sieci, DNS, bazy managed). Ansible to Configuration Management — konfiguruje oprogramowanie na już istniejących serwerach (instaluje Nginx, kopiuje pliki, ustawia cron). W praktyce używa się obu razem: Terraform tworzy VPS, Ansible go konfiguruje. Terraform ma state file i potrafi niszczyć zasoby. Ansible nie ma state — sprawdza aktualny stan przy każdym uruchomieniu.

Czy Ansible wymaga agenta na serwerze docelowym? +

Nie — Ansible jest agentless. Łączy się przez SSH (Linux/macOS) lub WinRM (Windows) i wykonuje zadania przez Python. Na serwerze docelowym musi być zainstalowany Python 3 (standardowo obecny na Ubuntu/Debian/CentOS). Nie ma żadnego demona, usługi ani agenta do instalacji i utrzymania. To duża przewaga nad Puppet/Chef które wymagają agentów na każdym węźle.

Co to są Ansible roles i kiedy ich używać? +

Role to sposób organizacji playbooków w wielokrotnie używalne moduły. Zamiast jednego długiego playbooka masz role: nginx, php, mysql, certbot — każda z własnym katalogiem tasks/, handlers/, templates/, defaults/. Role możesz pobrać z Ansible Galaxy (ansible-galaxy install geerlingguy.nginx) lub pisać własne. Używaj ról gdy: (1) konfigurujesz wiele serwerów o podobnej roli, (2) chcesz udostępniać konfigurację między projektami, (3) playbook przekroczył ~100 linii.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z SSH access — idealny cel dla Ansible Playbook (LEMP, Docker, backup)

Full Root

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

Mikrus

Tani VPS do testowania Ansible playbooków przed deplojem na produkcję

Dev/Test

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

home.pl

Hosting z automatyczną konfiguracją gdy wolisz nie pisać Ansible playbooków

Managed

[Aktywuj rabat →](/out/home-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/home-pl)

## Powiązane strony

-   [Docker na VPS — instalacja i konfiguracja](/baza-wiedzy/docker-na-vps)
-   [Kubernetes podstawy dla webdeveloperów](/baza-wiedzy/kubernetes-podstawy-hosting)
-   [Certbot + Nginx — SSL/TLS dla własnej domeny](/baza-wiedzy/certbot-nginx-ssl)
-   [Wszystkie artykuły](/baza-wiedzy/)