管理多個伺服器和環境的配置是使用 Ansible 的一大好處。但是,當配置文件在不同伺服器間有所不同時會發生什麼情況呢?與其為每個伺服器或環境創建獨立的配置,不如研究一下 Ansible 模板。
在這個教程中,您將學習到什麼是 Ansible 模板,它們是如何工作的,以及如何使用Ansible 模板模組來節省大量時間。
先決條件
本文將是一個逐步教程。如果您想跟著操作,請確保您有一個Ansible 控制器主機。本教程將使用 Ansible v2.9.18
什麼是 Ansible 模板?
有時您需要將文本文件傳輸到遠程主機。這些文本文件通常是某種配置文件。例如,如果您正在使用單個伺服器,可能需要創建一個名為app.conf的配置文件,供某個服務使用。
該配置文件可能包含特定於該服務器的信息,如主機名、IP地址等。由於您正在使用單個服務器,您可以在Ansible控制器上創建該文件,然後在playbook中使用copy模塊將其複製到服務器上。
但是,如果您有多個網絡服務器,每個服務器都需要相同的配置文件,但又具有自己的特定值怎麼辦?您不能只將配置文件複製到所有機器上;它只適用於具有特定主機名、IP地址等的單個服務器。您需要一個Ansible模板。
Ansible模板允許您定義帶有變量而不是靜態值的文本文件,然後在playbook運行時替換這些變量。
Ansible模板長什麼樣子?
Ansible模板是使用Jinja2模板語言構建的文本文件,具有j2文件擴展名。Jinja2模板看起來與您想要放在遠程主機上的文本文件完全相同。唯一的不同之處在於,該文件包含變量而不是靜態值。
例如,也許您需要在所有的Web伺服器上取得名為app.conf的配置文件,該文件包含對每個相應伺服器的IP地址、Ansible主機和Ansible用戶的引用。單個伺服器的app.conf文件可能如下所示。
您不能將此文件複製到每個Web伺服器上,因為每個項目都會根據遠程主機的IP、Ansible控制器的主機名和Ansible用戶而唯一。
與其靜態地設置這些值,Ansible模板允許您定義在運行時解釋並在遠程主機上替換的變數。
下面是app.conf.j2模板文件的示例。您現在可以看到,每個靜態值都已被替換為在兩側用雙大括號標記的變數。在這個例子中,這些變數來自Ansible事實。
模板文件始終具有J2文件擴展名,通常與它們在目標主機上創建的文件具有相同的名稱。
如何在遠程主機上創建模板文件?
創建模板後,您需要將該模板文件傳輸到遠程主機並“轉換”為其應該呈現的實際文本文件。為此,您需要在播放書中引用模板文件。
大多數Ansible管理員使用copy模組將文件傳輸到遠程主機,但正如上面所提到的,這對於模板來說是不可行的。
下面是一個簡單的示例參考,從一個playbook將app.conf文件複製到所有playbook的目標主機的/opt目錄中。
現在假設您已經將app.conf配置文件“模板化”,在前一節中涵蓋了Ansible控制器上的app.conf.j2模板文件。現在,您需要確保app.conf仍然到達/opt目錄,但變量被實際值替換。
要告訴playbook在/opt目錄中創建app.conf文件,只需將copy
參考替換為如下所示的template
。這樣做後,Ansible會調用template模組來傳輸模板並將變量替換為靜態值。
一旦playbook中的上述任務執行完畢,Ansible就會將app.conf.j2複製到遠程主機的/opt目錄中,將其中的所有變量替換為靜態值並將文件重命名為app.conf。
當您提供帶有目錄路徑的模板
src
時,Ansible 將在 /<ansible_installation_directory>/files/ 目錄中尋找模板。如果您只提供文件名,則 Ansible 將會在 /<ansible_installation_directory>/templates/ 目錄中尋找該模板。
渲染配置文件:模板示例
現在讓我們進入示範,看看如何設置 Ansible 模板並使用 Ansible 模板模塊動態生成配置文件。在這個示例中,您將在名為/etc的目錄中的一台名為SRV1的服務器上創建一個名為app.conf的文件。
本節中的步驟適用於任何類型的文本文件。本教程將以配置文件作為單個示例。
1. 使用您通常用於管理 Ansible 的用戶 SSH 登錄到 Ansible 控制器主機。
2. 在您的家目錄中創建一個文件夾來存放本教程的演示文件,並將工作目錄更改為該文件夾。
3. 在看起來像下面的目錄中創建一個名為app.conf.j2的模板文件。
您還可以在模板中使用特定於 Ansible 模板模塊本身的各種變量。
4. 在同一目錄中創建一個名為my_playbook.yml的簡單 playbook。此 playbook 將在/etc目錄中創建app.conf文件。
5. 調用 Ansible playbook,將其針對SRV1遠程主機。

6. 現在確認 /etc/app.conf 配置文件是否存在並具有預期的值。

使用模板模塊更新文件權限
現在您已經看到了使用模板模塊的基礎知識,現在讓我們更進一步。對於這個演示,您將創建與之前顯示的相同的 app.conf 文件。但是這一次,您將設置該文件的所有者和權限。
要更改模板模塊創建的文件的權限,您必須在 playbook 內使用三個參數:
- owner – 文件所有者
- group – 文件應該屬於的組
- mode – 權限。此字符串可以使用符號表示,也可以使用八進制數字表示
在符號模式中,
u
代表 “用戶”,g
代表 “組” ,o
代表 “其他”。
假設您仍然擁有之前部分建立的~/ansible_template_demo文件夾,打開my_playbook.yml playbook並將內容替換為下面的內容。在這個示例中,Ansible將使用連接變量將所有者和組設置為Ansible用戶。然後將文件權限設置為0644,代表:
- 所有者具有讀/寫權限
- 組中的用戶和其他所有人具有讀取權限
您可以在Ansible模板模塊文檔中找到所有可用的模板模塊參數。
現在,按照下面的示例再次執行playbook。
現在,您可以看到app.conf具有預期的文件權限。

使用循環模板多個文件
有時候單個文件是不夠的,您需要在遠程主機上添加多個文件。在這種情況下,您可以使用循環與模板模塊。使用loop參數定義循環允許您添加存儲在目錄中的多個文本文件。
假設您仍然擁有之前部分建立的~/ansible_template_demo文件夾,您應該已經有app.conf.j2在其中。
1. 在~/ansible_template_demo文件夾中創建第二個模板文件,名為app2.conf.j2,如下所示。
2. 打開 my_playbook.yml 書籍並用以下 YAML 替換所有內容。此 playbook 使用 {{item}}
變量來表示循環中處理的每個模板文件。然後,loop
參數定義循環要處理的每個模板文件。
3. 現在再次運行 playbook。 ansible-playbook my_playbook.yml --inventory SRV1

結論
Ansible 模板和模板模塊可以為您節省大量時間,並在所有遠程主機上創建動態文本文件。複製模塊提供類似的功能,但如果需要創建動態文本文件,模板模塊就是您的好幫手。