Ansible 作為常用的自動化工具,簡化了複雜的 IT 基礎架構管理工作。本文從 Ansible 的 Inventory 設定檔格式(INI 和 YAML)開始,逐步介紹 Playbook 的基本結構、撰寫方式和執行方法,並輔以實際案例說明如何使用 Ansible 進行任務的自動化組態和管理。接著,文章探討 Ansible 的進階功能,例如 Ansible Facts 如何收集系統資訊、Magic Variables 的使用技巧、Ansible Vault 如何加密敏感資料、Ansible Templates 如何靈活生成組態檔案、Plugins 如何擴充套件 Ansible 的功能,以及 Roles 如何提升程式碼的重用性,最後搭配程式碼範例展示如何在實際場景中應用這些進階功能,讓讀者能更有效地運用 Ansible 進行更進階的自動化任務管理。

Ansible 設定檔與 Playbook 基礎

Ansible 是一款強大的自動化工具,其設定檔格式主要支援 INI 和 YAML 兩種格式。本章節將探討這兩種格式的特性與使用方式,並介紹 Ansible Playbook 的基本結構。

INI 格式的 Inventory 設定檔

INI 格式是 Ansible 最直觀的 inventory 格式,適用於 Windows 和 Linux 的組態檔案。在 INI 檔案中,可以使用 name=value 的欄位來定義主機屬性。例如,在下面的範例中,定義了一個未分組的主機 bastion.example.com 和一個名為 web 的群組,其中包含了 web1.example.comweb2.example.com

清單 2-1:INI 格式範例

bastion.example.com ansible_user=ansible
[web]
web[1:2].example.com
[web:vars]
ansible_user=devops

內容解密:

  • bastion.example.com ansible_user=ansible:定義主機 bastion.example.com 並指定其 Ansible 使用者為 ansible
  • [web]:定義一個名為 web 的群組。
  • web[1:2].example.com:使用範圍表示法定義主機 web1.example.comweb2.example.com
  • [web:vars]:為 web 群組定義變數。
  • ansible_user=devops:指定 web 群組中的主機使用 devops 使用者進行連線。

YAML 格式的 Inventory 設定檔

YAML 是一種易讀的資料序列化格式,常用於 Ansible 的 inventory 設定。YAML 格式對縮排非常敏感,不同層級的內容需要正確縮排。

清單 2-2:YAML 格式範例

---
all:
  hosts:
    bastion.example.com:
      vars:
        ansible_user: ansible
  children:
    web:
      hosts:
        web1.example.com
        web2.example.com
      vars:
        ansible_user: devops

內容解密:

  • all:代表所有主機的根節點。
  • hosts:定義主機列表。
  • bastion.example.com:指定主機並定義其變數。
  • vars:定義變數區塊。
  • ansible_user: ansible:設定 bastion.example.com 的 Ansible 使用者為 ansible
  • children:定義子群組。
  • web:定義名為 web 的子群組,並包含主機和變數。

Ansible Playbook

Ansible Playbook 是針對 inventory 定義的一系列任務,用於自動化組態和管理目標主機。Playbook 使用 YAML 格式編寫,易於閱讀和維護。

清單 2-3:簡單的 Hi.yml Playbook

---
- name: Hi example
  hosts: all
  tasks:
    - name: Hi message
      ansible.builtin.debug:
        msg: "Hi!"
...

內容解密:

  1. `

表示 YAML 檔案的開始。 2.- name: Hi example定義 Playbook 的名稱。 3.hosts: all指定目標主機為 inventory 中的所有主機。 4.tasks定義任務列表。 5.- name: Hi message定義第一個任務的名稱。 6.ansible.builtin.debug使用 debug 模組輸出訊息。 7.msg: “Hi!"定義要輸出的訊息內容。 8.…` 表示 YAML 檔案的結束。

Ansible Playbook 的執行

執行 Ansible Playbook 需要使用 ansible-playbook 命令列工具。基本的命令格式如下:

$ ansible-playbook hi.yml

圖表說明

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Ansible 設定檔 Playbook 自動化技術

package "Ansible 架構" {
    component [Control Node] as control

    package "Ansible 組件" {
        component [Inventory] as inventory
        component [Playbooks] as playbooks
        component [Roles] as roles
        component [Modules] as modules
    }

    package "Managed Nodes" {
        component [Web Server] as web
        component [DB Server] as db
        component [App Server] as app
    }
}

control --> inventory : 主機清單
control --> playbooks : 任務定義
playbooks --> roles : 引用角色
roles --> modules : 使用模組
control --> web : SSH 連線
control --> db : SSH 連線
control --> app : SSH 連線

note right of control
  無需在目標主機安裝 Agent
  透過 SSH 執行任務
end note

@enduml

圖表翻譯: 此圖示展示了 Ansible Controller 如何透過 ansible-playbook 命令與目標主機進行互動。Ansible Controller 將 Playbook 傳送到目標主機,目標主機根據 Playbook 中的任務進行組態和變更。

提升許可權

在某些情況下,需要以提升許可權的方式執行任務。Ansible 提供了一系列引數來實作許可權提升:

  • become:啟用許可權提升。
  • become_method:選擇許可權提升的方法(如 sudo)。
  • become_user:指定提升後的使用者(預設為 root)。

清單 2-4:安裝 fail2ban 的 Playbook 範例

---
- name: install fail2ban
  hosts: all
  become: true
  become_method: sudo
  become_user: root

內容解密:

  • - name: install fail2ban 定義 Playbook 名稱。
  • hosts: all 指定目標主機為所有 inventory 中的主機。
  • become: true 啟用許可權提升。
  • become_method: sudo 指定使用 sudo 方法進行許可權提升。
  • become_user: root 指定提升後的使用者為 root。

Ansible 自動化技術深度解析

任務自動化與模組應用

在現代 IT 環境中,自動化是提升效率和可靠性的關鍵。Ansible 作為領先的自動化工具,提供了一系列強大的功能來簡化系統管理任務。本文將探討 Ansible 的核心概念和技術細節,特別是在任務自動化、變數處理和條件控制方面的應用。

安裝 Fail2ban 服務例項

以下是一個使用 Ansible 安裝 Fail2ban 的典型範例:

- name: install fail2ban
  ansible.builtin.apt:
    name: fail2ban
    state: present
    update_cache: true

內容解密:

  1. ansible.builtin.apt 模組用於管理 Debian 系統的軟體套件。
  2. name: fail2ban 指定要安裝的軟體名稱。
  3. state: present 確保該軟體已安裝在目標系統上。
  4. update_cache: true 在執行安裝前更新套件快取。

除錯與驗證機制

Ansible 提供了多種方式來進行除錯和驗證:

  1. 檢查模式:使用 --check 引數進行乾跑(dry run),預覽將要執行的變更。
  2. 詳細輸出:透過 -v-vvvv 的不同詳細程度引數,取得更豐富的執行資訊。
  3. 除錯模組:使用 ansible.builtin.debug 模組輸出自訂的除錯資訊。

變數與範本處理

變數在 Ansible 中扮演著至關重要的角色,使 Playbook 更加靈活和可重用。主要變數型別包括:

  1. 使用者自定義變數:在 Playbook 中使用 vars 區塊定義。
  2. 額外變數:透過命令列 -e 引數傳遞,實作動態組態。
  3. 註冊變數:儲存任務輸出的結果,用於後續任務的條件判斷。

陣列變數應使用案例項

cars:
  bmw:
    model: M1
    fuel: petrol
  tesla:
    model: Model S
    fuel: electric

內容解密:

  1. 定義了一個名為 cars 的字典變數,包含兩個子專案:bmwtesla
  2. 每個子專案下又有 modelfuel 屬性。
  3. 可以使用點記法或方括號記法存取這些屬性,如 cars.bmw.fuelcars['bmw']['fuel']

篩選器與資料處理

Ansible 藉助 Jinja2 篩選器提供強大的資料處理能力,常見的應用包括:

  1. 預設值設定:使用 default 篩選器為變數提供預設值。
  2. 資料格式轉換:將資料轉換為 JSON 或 YAML 格式。
  3. 正規表示式處理:使用 regex_replace 進行字串替換操作。

篩選器應使用案例項

{{ variable_name | default(5) }}
{{ status | ternary('restart', 'continue') }}
{{ variable_name | to_json }}

內容解密:

  1. 第一行設定變數的預設值為 5。
  2. 第二行根據 status 的真偽值傳回不同的字串。
  3. 第三行將變數內容格式化為 JSON 字串輸出。

條件控制與流程管理

條件陳述式使 Ansible 能根據不同情況執行不同的任務,主要透過 when 陳述式實作。

條件控制例項

- name: reload ssh
  ansible.builtin.service:
    name: nginx
    state: reloaded
  when: reload_ssh

內容解密:

  1. reload_ssh 變數為真時,才會執行服務過載操作。
  2. 使用布林邏輯控制任務是否執行。

事件處理機制

Handler 是 Ansible 中一種特殊的任務,只有在被通知且相關任務發生變更時才會執行。

Handler 使用案例項

- name: handler demo
  hosts: all
  tasks:
    - name: latest package
      ansible.builtin.yum:
        name: httpd
        state: latest
      notify: httpd update
  handlers:
    - name: httpd update
      ansible.builtin.debug:
        msg: "Webserver updated!"

內容解密:

  1. httpd 軟體套件更新時,會通知 httpd update handler。
  2. handler 只在相關任務報告變更時執行。

重複任務處理

迴圈陳述式使重複性任務的自動化變得簡單,主要有以下幾種形式:

  1. loop 陳述式:用於遍歷列表執行相同任務。
  2. with_items:簡化列表遍歷,特別適合簡單資料結構。
  3. with_fileglob:用於匹配特定模式的檔案列表。

迴圈應使用案例項

- name: Check services
  hosts: all
  tasks:
    - name: services running
      ansible.builtin.service:
        name: "{{ item }}"
        state: started
      loop:
        - apache2
        - sshd

內容解密:

  1. 使用 loop 對多個服務名稱進行迭代。
  2. 在每次迭代中,將當前元素指定給 item 變數。
  3. 確保指定的服務處於執行狀態。

Ansible 進階功能詳解

Ansible Facts:系統資訊的強大工具

Ansible Facts 是與遠端系統相關的變數,能夠提供主機的全面資訊,包括作業系統、發行版本、IP 位址、網路組態和儲存組態等。透過 Ansible Facts,我們可以利用一個系統的狀態或行為來組態其他系統。

使用 Ansible Facts

要使用 Ansible Facts,必須在 Play 區段中啟用 gather_facts(參見清單 2-9)。gather_facts 變數預設為啟用,並在每次 Ansible Playbook 執行開始時新增一個額外的「Fact Gathering」任務。

---
- name: 列印 facts
  hosts: all
  gather_facts: true
  tasks:
    - name: 列印 facts
      ansible.builtin.debug:
        var: ansible_facts

上述 Playbook 會列印目標系統的所有 Ansible Facts。例如,ansible_date_time fact 會顯示目前的日期和時間。

Ansible Magic Variables:內部變數的妙用

Magic Variables 是 Ansible 的內部變數,在某些情況下非常實用。以下是五個最常用的 Magic Variables:

  • hostvars:存取為任何主機定義的變數
  • groups:列出 inventory 中的所有群組
  • group_names:列出目前主機所屬的群組
  • inventory_hostname:在 inventory 中組態的主機名稱
  • ansible_version:Ansible 版本資訊

使用 Magic Variables

這些變數可以幫助我們更好地管理和組態主機。例如,hostvars 可以用來存取其他主機的變數,而 groups 可以用來列出所有的群組。

Ansible Vault:加密變數和檔案的安全管理

Ansible Vault 允許我們儲存加密的變數和檔案,並在 Playbooks 或 Roles 中使用它們,指定密碼。最新的 Ansible 版本使用 AES 256 密碼進行強加密。

建立 Ansible Vault

建立新的 Ansible Vault 非常簡單:

$ ansible-vault create secret.yml

在 Playbook 中使用 Ansible Vault

可以在任何 Ansible Playbook 中使用 Ansible Vault,只需在命令列中指定 --vault-id @prompt 引數。

Ansible Templates:組態檔案的靈活生成

Ansible Templates 有助於將變數值套用到組態檔案中。Ansible Templates 利用 Jinja2 程式語言和 Ansible 的內建範本模組。

使用 Ansible Templates

以下範例(清單 2-10)將 hi.txt.j2 範本中的 example 變數值填入,並儲存到 /tmp/hi.txt 檔案中。

---
- name: 範本演示
  hosts: all
  vars:
    example: Hi
  tasks:
    - name: 套用範本
      ansible.builtin.template:
        src: templates/hi.txt.j2
        dest: /tmp/hi.txt

範本檔案範例

{{ example }}

結果會生成一個包含以下內容的檔案:

Hi

Ansible Plugins:擴充套件 Ansible 的功能

Plugins 擴充套件了 Ansible 的功能,使其能夠與更多服務和應用程式領域互動。所有的 Ansible Plugins 都在 Ansible 控制節點上執行。

常見的 Ansible Plugin Types

  • action:在模組執行前於背景執行
  • become:擴充套件許可權提升系統
  • cache:緩衝收集的事實或 inventory 資料來源資料

使用 Lookup Plugins

Lookup Plugins 使我們能夠擴充套件 Jinja2,以在 Playbooks 中存取外部資料來源。常見的 Lookup Plugins 使用案例包括:

  • 從 Windows INI 風格檔案讀取(ini)
  • 從 CSV 檔案讀取(csvfile)
  • 聆聽符合 shell 表示式(fileglob)

Ansible Roles:程式碼重用的最佳實踐

Ansible Role 使程式碼重用成為可能,建立了一個標準格式來分發 Playbook 程式碼。標準結構將 Ansible Playbook 陳述式分割到本地檔案系統中的資料夾中。

建立 Ansible Role

可以使用包含在每個 Ansible 安裝中的 ansible-galaxy 命令列工具來管理 Ansible Roles。

$ ansible-galaxy role init role-example

上述命令會建立一個名為 role-example 的新 Role。