Ansible 提供了強大的 setupshell 模組,方便查詢目標主機的環境資訊,例如軟體版本、網路設定等。然而,在處理敏感資料時,安全性至關重要。Ansible Vault 正是為此而生,它允許使用 AES 加密演算法保護密碼、金鑰等機密資訊,避免以明文形式儲存於程式碼函式庫中。此外,Ansible Galaxy 作為 Ansible 的官方角色倉函式庫,提供了大量的現成角色,方便使用者快速佈署和管理各種應用程式和服務。透過 ansible-galaxy 命令列工具,可以輕鬆地安裝、移除、搜尋和管理角色及其依賴關係,大幅簡化了 Ansible 的使用流程。

進階 Ansible 技術

環境查詢

Ansible 命令列工具的一個非常有用的實作是使用 setupshell 模組查詢環境。例如,您可以找出所有安裝了版本為 1.4.6 的 nginx 的機器,命令如下:

ansible web -i inventory -m shell -a 'dpkg -s nginx | grep Version | grep 1.4.6'

這個命令將對所有符合條件的機器報告成功,對不符合條件的機器報告失敗。例如,當對一個包含兩台機器的 inventory 檔案執行時,其中一台執行正確版本,另一台不是,您將得到以下輸出:

host1.example.com | success | rc=0 >>
Version: 1.4.6-1ubuntu3.5
host2.example.com | FAILED | rc=1 >>

您也可以使用 Ansible 取得環境資訊。您可以結合 setup 模組和篩選引數來顯示機器上預設的 ipv4 連線資訊:

$ ansible all -i inventory -m setup -a 'filter=ansible_default_ipv4'
192.168.33.20 | SUCCESS => {
    "ansible_facts": {
        "ansible_default_ipv4": {
            "address": "10.0.2.15",
            "alias": "eth0",
            "broadcast": "10.0.2.255",
            "gateway": "10.0.2.2",
            "interface": "eth0",
            "macaddress": "08:00:27:86:81:4f",
            "mtu": 1500,
            "netmask": "255.255.255.0",
            "network": "10.0.2.0",
            "type": "ether"
        }
    },
    "changed": false
}

內容解密:

此範例展示瞭如何使用 Ansible 的 setup 模組查詢機器的預設 ipv4 連線資訊。透過篩選引數 filter=ansible_default_ipv4,Ansible 只會傳回與預設 ipv4 連線相關的資訊。這對於需要取得特定網路組態資訊的場合非常有用。

Ansible Vault

Ansible Vault 是 Ansible 的檔案加密工具。當處理敏感資料(如存取金鑰或密碼)時,您可能不想將它們以純文字形式儲存在儲存函式庫中的任何地方。Ansible Vault 是一個用於使用 AES 加密演算法加密檔案的命令列工具。由於 AES 是根據共用秘密的,因此在建立檔案時需要提供一個秘密金鑰,在嘗試讀取檔案時(例如,執行 playbook 時)也需要提供相同的共用秘密。

讓我們建立一個簡單的範例,使用加密的變數檔案作為資料來源,並在磁碟上建立一個檔案。首先,建立一個新的 playbook:

mkdir -p ansible-encrypted/roles
cd ansible-encrypted
touch Vagrantfile playbook.yml

編輯 Vagrantfile 並新增以下內容:

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.network "private_network", ip: "192.168.33.50"
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
  end
end

然後,編輯 playbook.yml 並新增以下內容:

---
- hosts: all
  roles:
    - mheap.demo

接下來,建立您的角色。使用 ansible-galaxy 初始化一個空角色:

cd roles
ansible-galaxy init mheap.demo
cd ..

現在,您已經具備了測試 ansible-vault 的環境。執行 vagrant up 建立環境,然後執行您的空角色。

內容解密:

此範例展示瞭如何使用 Ansible Vault 加密變數檔案。首先,我們建立了一個新的 playbook 和一個 Vagrantfile,用於設定測試環境。然後,我們使用 ansible-galaxy 初始化了一個新的角色。這些步驟為後續使用 Ansible Vault 做好了準備。

使用 Ansible Vault 加密變數檔案

接下來,讓您的角色做一些事情。開啟 roles/mheap.demo/tasks/main.yml 並新增一個任務,將檔案寫入磁碟:

---
- copy: content="{{introduction}}" dest=/tmp/encrypted_output

您還需要編輯 roles/mheap.demo/vars/main.yml,並確保 introduction 變數被設定:

---
introduction: Hello, my name is Michael

此時,您可以執行 vagrant up 建立虛擬機器,執行您的 playbook,並將檔案寫出。假設您的介紹是敏感的,您不想讓人們能夠讀取它,除非他們知道密碼。您可以使用 ansible-vault 加密您的變數檔案:

$ ansible-vault encrypt roles/mheap.demo/vars/main.yml
New Vault password:
Confirm New Vault password:
Encryption successful

Vault 將要求您輸入密碼,然後確認該密碼。一旦您提供了密碼,Vault 將加密檔案並將其寫入磁碟。如果您檢視該檔案,您將看到資料不再是純文字:

$ cat roles/mheap.demo/vars/main.yml
$ANSIBLE_VAULT;1.1;AES256
3235393239383137653031663739333737313135393066653835653434323333613766356539
32653138623736353266303233653366613830616638356435640a666239386366303139646
562306161393061333534333832643336313038323334613332386364636263666431666362
346538653064363737333363343936310a65343662616530333634333764386234353437396
362646266346438663830643265373561383766393231393261336263343032333263383730
6261366538396166653339313132656464643062316233323039333937643836666132633632

內容解密:

此範例展示瞭如何使用 Ansible Vault 加密變數檔案。首先,我們在 roles/mheap.demo/tasks/main.yml 中新增了一個任務,將變數 introduction 的內容寫入 /tmp/encrypted_output。然後,我們使用 ansible-vault 加密了 roles/mheap.demo/vars/main.yml 檔案。加密後,檔案內容變成了不可讀的純文字。

如果您嘗試再次執行 vagrant provision,您將看到一個錯誤:- ERROR! Decryption failed. 這是因為 Ansible 沒有解密變數檔案所需的密碼。如果您使用 ansible-playbook 而不是 vagrant provision,您將新增 --ask-vault-pass 標誌,如下所示:

ansible-playbook –i /path/to/inventory playbook.yml --ask-vault-pass

由於您正在使用 vagrant provision,您需要透過 Vagrantfile 告訴 Ansible 請求 Vault 密碼。在您的 Vagrantfile 的第 6 行(即 ansible.playbook = "playbook.yml" 之後的行)新增以下內容:

ansible.ask_vault_pass = true

這告訴 Vagrant 在呼叫 Ansible 時指定 --ask-vault-pass。再次執行 vagrant provision,並提供用於加密變數檔案的密碼。這次,Ansible 的執行應該會順利完成,如果您使用 vagrant ssh 登入您的環境,您應該會看到 /tmp/encrypted_output 已被建立,並且它包含了您的介紹。

內容解密:

此範例展示瞭如何在使用 vagrant provision 時提供 Vault 密碼。透過在 Vagrantfile 中設定 ansible.ask_vault_pass = true,Vagrant 將在呼叫 Ansible 時請求 Vault 密碼。這樣,Ansible 就能夠解密變數檔案,並順利執行 playbook。

第9章 ■ 高階Ansible技術

使用Ansible Vault保護敏感資訊

在前面的章節中,我們已經學習瞭如何使用Ansible來自動化佈署和管理伺服器。但是,在實際的應用中,我們經常需要處理一些敏感資訊,例如密碼、SSL憑證等。為了保護這些敏感資訊,Ansible提供了一個名為ansible-vault的工具。

編輯加密檔案

當我們需要修改加密檔案中的變數值時,不能直接使用文字編輯器開啟檔案。相反,我們需要使用ansible-vault edit命令來解密和編輯檔案:

$ ansible-vault edit roles/mheap.demo/vars/main.yml

輸入密碼後,我們可以對檔案進行修改。完成修改後,儲存並關閉編輯器,ansible-vault將重新加密檔案並寫入磁碟。

執行Playbook時輸入Vault密碼

當我們再次執行vagrant provision時,Ansible會提示我們輸入Vault密碼,然後將修改後的介紹寫入環境中的檔案。

Ansible-Vault子命令

ansible-vault提供了多個有用的子命令,如下表所示:

命令說明
ansible-vault create建立新的加密檔案
ansible-vault encrypt加密現有的檔案
ansible-vault decrypt解密現有的加密檔案
ansible-vault edit臨時解密加密檔案以進行編輯
ansible-vault view顯示現有的加密檔案內容
ansible-vault rekey更改用於加密/解密Ansible Vault管理的檔案的金鑰

自動化環境中使用Ansible-Vault

在完全自動化的環境中,我們可能無法手動輸入Vault密碼。這時,我們可以使用--vault-password-file選項指定包含密碼的檔案路徑。或者,我們可以在ansible.cfg中設定vault_password_file選項以指定預設值。

隱藏敏感資訊

雖然我們的資料在資料檔案中是加密的,但是在執行Playbook時,Ansible會解密這些資料並使用它們。預設情況下,在詳細模式下執行Ansible時,這些資訊將顯示在螢幕上。為了隱藏這些資訊,我們可以在任務中新增no_log: true引數:

- shell: echo '{{introduction}}' | wc -c
  no_log: true

這樣,在詳細模式下執行Ansible時,輸出將被隱藏。

Ansible Galaxy

在第4章中,我們簡要介紹了Ansible Galaxy。除了使用它來初始化新的角色外,Ansible Galaxy還提供了其他子命令。

初始化新的角色

我們可以使用ansible-galaxy init命令來建立新的角色:

$ ansible-galaxy init mheap.apache

這將建立如圖9-1所示的預設角色結構。

管理本地角色

Ansible Galaxy命令列工具具有兩個主要功能:安裝本地角色和管理Ansible Galaxy網站上的角色。

此圖示
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Ansible進階技術Vault與Galaxy應用

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

此圖示描述了使用Ansible Vault和執行Playbook的流程。

重點回顧

  • 使用ansible-vault保護敏感資訊
  • 編輯加密檔案
  • 執行Playbook時輸入Vault密碼
  • 使用Ansible Galaxy管理角色

本章內容涵蓋了高階Ansible技術,包括使用ansible-vault和Ansible Galaxy。這些技術可以幫助我們更好地管理和自動化伺服器佈署。

管理 Ansible 角色的最佳實踐

使用 ansible-galaxy 安裝角色

Ansible Galaxy 是 Ansible 官方的角色倉函式庫,提供了豐富的現成角色供使用者下載和使用。透過 ansible-galaxy install 命令,可以輕鬆安裝所需的角色。例如,若要安裝 Jeff Geerling 的 git 角色,可以執行:

$ ansible-galaxy install geerlingguy.git

預設情況下,角色會被安裝在 /etc/ansible/roles 目錄下。若希望將角色安裝在特定目錄,可以使用 -p 選項指定安裝路徑:

$ ansible-galaxy install geerlingguy.git -p roles

對於有多個依賴角色的情況,可以將它們列在 requirements.txt 檔案中,然後使用以下命令批次安裝:

$ ansible-galaxy install -r requirements.txt

requirements.txt 的範例如下:

geerlingguy.git
mheap.apache

使用 requirements.yml 管理依賴

從 Ansible 1.8 版本開始,支援使用 requirements.yml 檔案來定義角色依賴。與 requirements.txt 相比,requirements.yml 提供了更多的靈活性,可以指定角色來源、版本、名稱等資訊。範例如下:

# 從 Ansible Galaxy 安裝
- src: yatesr.timezone

# 從 GitHub 安裝
- src: https://github.com/bennojoy/nginx

# 從 GitHub 安裝並指定版本和名稱
- src: https://github.com/bennojoy/nginx
  version: master
  name: nginx_role

# 從網頁伺服器下載封裝的角色
- src: https://some.webserver.example.com/files/master.tar.gz
  name: http-role

# 從 Bitbucket 安裝
- src: git+http://bitbucket.org/willthames/git-ansible-galaxy
  version: v1.4

# 從 Bitbucket 安裝(替代語法)
- src: http://bitbucket.org/willthames/hg-ansible-galaxy
  scm: hg

# 從 GitLab 或其他 Git 服務安裝
- src: git@gitlab.company.com:mygroup/ansible-base.git
  scm: git
  version: 0.1.0

內容解密:

  1. requirements.yml 檔案結構:該檔案採用 YAML 格式,允許使用者定義多個角色及其來源、版本等屬性。
  2. src 屬性:指定角色的來源,可以是 Ansible Galaxy 的角色名稱、GitHub 或其他 Git 服務的倉函式庫 URL,或是封裝好的角色檔案 URL。
  3. version 屬性:用於指定要安裝的角色版本,可以是分支名稱、標籤或提交雜湊。
  4. name 屬性:允許為下載的角色指定一個新的名稱,避免命名衝突。
  5. scm 屬性:當來源是版本控制系統(如 Git 或 Mercurial)時,需要指定 scm 屬性以告知 Ansible 如何下載該角色。

列出和管理已安裝的角色

使用 ansible-galaxy list 命令可以檢視本機已安裝的角色:

$ ansible-galaxy list
- geerlingguy.git, 1.1.1

若要檢查特定目錄下的角色,可以使用 -p 選項:

$ ansible-galaxy list -p roles
- mheap.demo, (unknown version)

移除已安裝的角色

若需要移除已安裝的角色,可以使用 ansible-galaxy remove 命令:

$ ansible-galaxy remove geerlingguy.git
- successfully removed geerlingguy.git

同樣地,也可以使用 -p 選項指定要移除的角色所在的目錄:

$ ansible-galaxy remove -p roles mheap.demo
- successfully removed mheap.demo

內容解密:

  1. ansible-galaxy remove 命令功能:該命令用於從本機移除指定的 Ansible 角色。
  2. -p 選項的作用:允許使用者指定要操作的角色目錄,而不是預設的 /etc/ansible/roles
  3. 移除結果確認:執行移除命令後,會顯示成功移除的角色名稱,確認操作結果。

搜尋 Ansible Galaxy 中的角色

Ansible 提供了兩種方式來搜尋需要的角色:一是透過網頁介面瀏覽 Ansible Galaxy;二是使用 ansible-galaxy search 命令列工具。

例如,若要搜尋與 git 相關的角色,可以執行:

$ ansible-galaxy search git
Found 160 roles matching your search:
Name Description
---
- 
---
-
---
-
---
rooland-provisioning.gitlab GitLab Git web interface
geerlingguy.gitlab GitLab Git web interface
...

內容解密:

  1. ansible-galaxy search 命令功能:該命令用於在 Ansible Galaxy 中搜尋符合關鍵字的角色。
  2. 搜尋結果展示:命令會列出符合搜尋條件的角色名稱及其簡要描述。
  3. 關鍵字匹配:搜尋根據角色名稱和描述進行匹配,使用者可以根據需要選擇合適的角色。