Ansible自動化部署實戰手冊:由零開始管理Linux Server

前言 — 點解你要學Ansible? 喂,今日同大家探討下一個好實用嘅topic:Ansible自動化部署。如果你仲係逐部機SSH入去人手打command裝package、改config file,咁你真係要停一停,睇下呢篇文。 想像下你管10部server,要做一次security update、改個Nginx config、加個firewall rule——你打算ssh 10次?定係你會整個s...

前言 — 點解你要學Ansible?

喂,今日同大家探討下一個好實用嘅topic:Ansible自動化部署。如果你仲係逐部機SSH入去人手打command裝package、改config file,咁你真係要停一停,睇下呢篇文。

想像下你管10部server,要做一次security update、改個Nginx config、加個firewall rule——你打算ssh 10次?定係你會整個shell script for loop?前者慢到喊,後者容易出事。Ansible就係為咗解決呢個問題而生嘅。

Ansible係Red Hat旗下嘅開源自動化工具,佢最大嘅賣點係agentless——即係唔使喺target server度裝任何額外軟件,只要target機有Python同SSH就得。你用YAML寫playbook,人讀得明、機又執行到。今次我會帶你由零開始,用Ansible部署一個Nginx web server,step by step。

Step 1:安裝Ansible(Control Node)

首先你要有一部機做control node(你部laptop或者跳板機都得)。Ansible唔support Windows做control node,所以用Linux或者macOS。

Ubuntu/Debian:

sudo apt update
sudo apt install -y ansible
ansible --version

macOS:

brew install ansible
ansible --version

裝完之後,check下版本,正常應該見到類似 ansible [core 2.17.x] 嘅輸出。

Step 2:設定Inventory檔案

Inventory係Ansible知道要管邊啲機嘅清單。最簡單係一個INI格式嘅file:

# inventory.ini
[webservers]
web01 ansible_host=192.168.1.10 ansible_user=ubuntu
web02 ansible_host=192.168.1.11 ansible_user=ubuntu

[db]
db01 ansible_host=192.168.1.20 ansible_user=ubuntu

呢度我定義咗兩個group:webserversdb,方便之後用group做target。記得要先set好SSH key-based login,唔係次次要打password就玩死自己:

ssh-copy-id ubuntu@192.168.1.10
ssh-copy-id ubuntu@192.168.1.11

之後test下Ansible認唔認到你啲機:

ansible all -i inventory.ini -m ping

如果見到 "ping": "pong" 綠色output,恭喜你,連接成功!

Step 3:寫第一個Playbook

Playbook係Ansible嘅核心,用YAML寫。我而家寫一個playbook去裝Nginx:

# playbooks/nginx.yml
---
- name: Deploy Nginx on web servers
  hosts: webservers
  become: yes
  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
      when: ansible_os_family == "Debian"

    - name: Install Nginx
      apt:
        name: nginx
        state: latest
      when: ansible_os_family == "Debian"

    - name: Ensure Nginx is running and enabled
      systemd:
        name: nginx
        state: started
        enabled: yes

    - name: Deploy custom index.html
      copy:
        content: "<h1>Deployed by Ansible!</h1>"
        dest: /var/www/html/index.html
        owner: www-data
        group: www-data
        mode: '0644'

    - name: Allow HTTP through UFW
      ufw:
        rule: allow
        port: '80'
        proto: tcp

呢個playbook做咗5樣嘢:update apt cache → 裝Nginx → 確保service行緊兼開機自動啟動 → 放一個custom index.html → 開firewall port 80。

執行佢:

ansible-playbook -i inventory.ini playbooks/nginx.yml

你會見到Ansible逐個task出結果,綠色=冇變動,黃色=做咗改動,紅色=出事。第一次run應該全部黃色(因為全部嘢都係新裝)。

Step 4:用Variables同Templates進階化

hard code晒啲value唔係好做法。Ansible支援variables同Jinja2 templates,等你可以同一套playbook部署唔同environment。

先整個variable file:

# group_vars/webservers.yml
nginx_port: 80
nginx_server_name: "molious.com"
nginx_root: "/var/www/molious"

然後改用template module放Nginx config:

# templates/nginx.conf.j2
server {
    listen {{ nginx_port }};
    server_name {{ nginx_server_name }};

    root {{ nginx_root }};
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Playbook加返template task:

    - name: Deploy Nginx config from template
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: restart nginx

  handlers:
    - name: restart nginx
      systemd:
        name: nginx
        state: restarted

留意 notify: restart nginx —— 呢個係Ansible嘅handler機制,只係config file有改動先會trigger restart,冇改就skip,好聰明。

Step 5:善用Roles組織大型Project

當你playbook越來越大,你要用Roles去組織。一個role嘅directory structure係咁:

roles/
  nginx/
    tasks/
      main.yml
    handlers/
      main.yml
    templates/
      nginx.conf.j2
    vars/
      main.yml

然後喺playbook度refer返個role:

- name: Deploy full web stack
  hosts: webservers
  become: yes
  roles:
    - nginx
    - certbot    # auto SSL cert
    - ufw

咁樣你可以重用role,甚至直接用人哋Ansible Galaxy上面嘅community role,例如:

ansible-galaxy install geerlingguy.nginx

常見Trap同Tips

玩Ansible有幾個位好易中伏:

1. Idempotency(冪等性) — Ansible嘅設計理念係「同一條playbook run 10次,結果都一樣」。寫task嘅時候避免用 shellcommand module做configuration,盡量用專用module(lineinfiletemplatesysctl 等),唔係第二次run就會爆。

2. become(sudo) — 大部份system-level task都要 become: yes,但如果target user冇sudo權限就會停晒。建議用 --become --ask-become-pass 或者set好NOPASSWD sudo。

3. Vault加密敏感資料 — password、API key呢啲唔好plain text放喺variable file。用 ansible-vault encrypt

ansible-vault encrypt group_vars/all/secrets.yml
ansible-playbook ... --ask-vault-pass

4. Check Mode — 驚run錯嘢?先用 --check --diff dry-run睇下會有咩改動先。

總結

Ansible絕對係DevOps工具鏈入面最易上手嘅一員。由簡單ping開始,到寫playbook、用template、玩roles,慢慢你就會發現自己管理server嘅效率提升咗幾倍。仲有Inventory可以dynamic pull from AWS/Azure、可以用Ansible Automation Platform做centralized management…但呢啲留返下次再傾。

今日講住咁多先!你哋有用Ansible嘅經驗嗎?有冇試過run錯playbook搞到全公司server down晒嘅慘痛經歷?😂 分享下喺comment啦!

#Linux #自動化 #SSH #部署 #firewall