Ansible Inventory 檔案是定義和管理主機的重要元件,讓管理員能有效執行自動化任務。本文除了介紹 Inventory 檔案的基本結構、群組和變數設定外,更探討動態 Inventory 的應用,說明如何使用可執行檔案或指令碼生成動態 Inventory 內容,以應對大規模環境的管理需求。文章也示範如何結合 Vagrant 和 Ansible 建立 WordPress 開發環境,並逐步說明安裝 PHP、MySQL 和 Nginx 的 Ansible playbook 設定,包含 MySQL 的安全強化步驟,例如設定 root 密碼、移除預設匿名使用者和測試資料函式庫等,提供讀者一個完整的 Ansible 自動化 WordPress 環境佈署範例。
Ansible Inventory 檔案詳解
Ansible 的 Inventory 檔案是用於定義和管理主機群組的重要元件。透過適當地組態 Inventory 檔案,管理員能夠輕鬆地對不同主機或主機群組執行 Ansible 指令。本文將探討 Inventory 檔案的結構、變數設定以及動態 Inventory 的應用。
Inventory 檔案基礎
Inventory 檔案採用 INI 格式,使用方括號 [] 來標記不同的主機群組。例如:
[web]
web1.example.com
web2.example.com
[database]
db.example.com
在這個範例中,我們定義了兩個群組:web 和 database。當執行 Ansible 指令時,可以指定特定的群組來執行任務,例如:
ansible web -i /path/to/inventory -m ping
這條指令會對 web 群組中的所有主機執行 ping 模組。
群組變數設定
除了定義主機群組外,我們還可以為特定的群組設定變數。這些變數將在 Ansible 執行期間對該群組中的所有主機可用。例如:
[web:vars]
apache_version=2.4
engage_flibbit=true
在這個範例中,我們為 web 群組設定了兩個變數:apache_version 和 engage_flibbit。
群組巢狀結構
Ansible 支援建立群組的巢狀結構,也就是說一個群組可以包含其他群組。這種結構使得管理複雜的環境變得更加容易。例如:
[web_centos5]
host1.example.com
host2.example.com
[web_centos6]
shinynewthing.example.com
[centos5:children]
web_centos5
database_centos5
[centos6:children]
web_centos6
reporting_centos6
在這個範例中,我們建立了 centos5 和 centos6 兩個群組,分別包含不同的子群組。
實際範例
以下是一個真實的 Inventory 檔案範例,展示了一個包含多個主機和群組的環境:
[web_centos5]
fe1.example.com ansible_user=michael ansible_ssh_private_key_file=michael.key
fe2.example.com ansible_user=michael ansible_ssh_private_key_file=michael.key
[web_centos6]
web[1:3].example.com ansible_user=automation ansible_port=50022 ansible_ssh_private_key_file=/path/to/auto.key
[database_centos6]
db.example.com ansible_user=michael ansible_ssh_private_key_file=/path/to/db.key
[loadbalancer_centos6]
lb.example.com ansible_user=automation ansible_port=50022 ansible_ssh_private_key_file=/path/to/lb.key
[web:children]
web_centos5
web_centos6
[database:children]
database_centos6
[loadbalancer:children]
loadbalancer_centos6
這個範例展示瞭如何定義不同的主機群組、設定變數以及建立群組的巢狀結構。
程式碼解析:
[web_centos5]
fe1.example.com ansible_user=michael ansible_ssh_private_key_file=michael.key
fe2.example.com ansible_user=michael ansible_ssh_private_key_file=michael.key
內容解密:
[web_centos5]定義了一個名為web_centos5的群組。fe1.example.com和fe2.example.com是該群組中的主機。ansible_user=michael指定了連線這些主機時使用的 SSH 使用者名稱。ansible_ssh_private_key_file=michael.key指定了用於 SSH 連線的私鑰檔案路徑。
動態 Inventory
當需要管理的伺服器數量龐大時,手動維護 Inventory 檔案變得困難且容易出錯。此時,動態 Inventory 成為一個理想的解決方案。動態 Inventory 是根據 JSON 格式的檔案,包含了所有主機的相關資料。
Ansible 支援使用可執行檔案作為動態 Inventory 的來源。當 Ansible 檢測到指定的 Inventory 檔案是可執行的,它將執行該檔案並解析其輸出的 JSON 資料。
使用可執行檔案建立動態庫存
在 Ansible 中,您可以使用可執行檔案來讀取機器庫存資料。這些資料可以來自任何地方:遠端 API、本地資料函式庫、一組您解析和整理的檔案等。只要能夠填充要執行的伺服器列表,就可以將其用作庫存檔案。
Ansible 預期任何用於提供機器庫存的可執行檔案都傳回特定的 JSON 格式。如下所示:
{
"my_script": ["dev2", "dev"],
"_meta": {
"hostvars": {
"dev2": {
"ansible_host": "dev2.example.com",
"ansible_user": "ansible"
},
"dev": {
"ansible_host": "dev.example.com",
"ansible_port": "50022",
"ansible_user": "automation"
}
}
}
}
第一個鍵是指令碼的名稱,值是庫存檔案中要使用的主機名。然後,對於每個名稱,都有一些後設資料,其中包含要使用的 SSH 主機、登入使用者和 SSH 埠。
動態庫存的實作
假設您有一個資料函式庫列出了所有機器,並且想要使用該資料函式庫作為庫存檔案。您的可執行檔案可能如下所示:
# 從資料函式庫中取得機器資訊
machines = fetch_rows("SELECT hostname, user, key, port FROM active_machines")
hostnames = [m.hostname for m in machines]
metadata = {'hostvars': {}}
# 遍歷機器列表,構建後設資料
for m in machines:
metadata['hostvars'][m.hostname] = {
'ansible_user': m.user,
'ansible_port': m.port,
'ansible_ssh_private_key_file': m.key
}
# 輸出 JSON 格式的庫存資料
output_json({
'my_script': hostnames,
'_meta': metadata
})
內容解密:
fetch_rows函式用於從資料函式庫中讀取活動機器的資訊,包括主機名、使用者、金鑰和埠。- 將機器主機名提取到
hostnames列表中。 - 初始化
metadata物件,並為每個主機建立hostvars。 - 將每個主機的連線資訊(如使用者、埠和私鑰檔案)新增到
metadata中。 - 使用
output_json函式輸出符合 Ansible 預期的 JSON 格式。
多個庫存的管理
如果您的基礎設施中同時包含物理硬體和雲伺服器,可以透過將庫存路徑指向一個目錄來合併多個庫存檔案。Ansible 將讀取該目錄中的所有檔案,並將它們合併為一個庫存。
安裝 WordPress
現在您已經熟悉瞭如何設定 Ansible 的開發環境,接下來我們將編寫一個 playbook 來下載並組態 WordPress。
WordPress 的依賴
WordPress 需要 PHP(版本需大於 5.2)、Web 伺服器和 MySQL 資料函式庫。在本章中,我們將安裝所有必需的依賴項,並自動安裝新的 WordPress 例項。
環境組態
首先,建立一個新的 Vagrant 環境:
mkdir ansible-wordpress
cd ansible-wordpress
vagrant init ubuntu/trusty64
修改 Vagrantfile 以啟用網路並分配更多的記憶體給虛擬機器:
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "private_network", ip: "192.168.33.20"
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
end
內容解密:
- 使用
mkdir和cd命令建立並進入新目錄。 - 使用
vagrant init初始化新的 Vagrant 環境。 - 修改 Vagrantfile 以設定虛擬機器的網路和記憶體組態。
config.vm.network用於設定私有網路的 IP 地址。config.vm.provider用於設定虛擬機器的記憶體大小,以滿足 MySQL 的需求。
在虛擬機器上安裝 WordPress 的 Ansible 指令碼實作
虛擬機器的建立與基本組態
首先,透過 Vagrant 建立一個虛擬機器,並使用 Ansible 進行組態。以下為 Vagrantfile 的關鍵組態:
config.vm.define "wordpress" do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.network "private_network", ip: "192.168.33.20"
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
config.vm.provision "ansible" do |ansible|
ansible.playbook = "provisioning/playbook.yml"
end
end
內容解密:
config.vm.define定義了一個名為 wordpress 的虛擬機器組態區塊。config.vm.box指定使用的虛擬機器映像檔為 ubuntu/trusty64。config.vm.network設定虛擬機器的私有網路 IP 為 192.168.33.20。config.vm.provider組態虛擬機器的記憶體為 1 GB。config.vm.provision指定使用 Ansible 進行組態,playbook 路徑為 provisioning/playbook.yml。
安裝 WordPress 的依賴套件
要執行 WordPress,需要安裝 PHP、nginx 和 MySQL。首先,建立一個簡單的 Ansible playbook 來確認 Ansible 可以正確連線到 Vagrant 虛擬機器。
建立 provisioning 目錄並建立 playbook.yml:
mkdir provisioning
touch provisioning/playbook.yml
在 provisioning/playbook.yml 中定義初始 playbook:
---
- hosts: all
become: true
tasks:
- name: 確認連線
ping:
內容解密:
hosts: all表示該 playbook 將對所有主機執行。become: true表示以提升許可權(通常是 root)執行任務。tasks下定義了要執行的任務列表,第一個任務是使用ping模組確認連線。
安裝 PHP
WordPress 可以在 PHP 5.2 及以上版本執行,但建議使用最新版本。以下為安裝 PHP 的 Ansible 任務:
# PHP
- name: 新增 ondrej PHP PPA
apt_repository: repo='ppa:ondrej/php'
- name: 更新 apt 快取
apt: update_cache=yes cache_valid_time=3600
- name: 安裝 PHP
apt: name={{item}} state=installed
with_items:
- php
- php-fpm
- php-mysql
- php-xml
- name: 移除 apache2
apt: name=apache2 state=removed
內容解密:
- 使用
apt_repository模組新增 ondrej PHP PPA,以安裝最新版本的 PHP。 - 更新 apt 快取以確保可以安裝最新套件。
- 使用迴圈安裝多個 PHP 相關套件。
- 由於安裝 PHP 時會一併安裝 Apache2,因此需要手動移除 Apache2。
安裝 MySQL
接下來,安裝 MySQL 資料函式庫伺服器並進行基本的安全設定:
# MySQL
- name: 安裝 MySQL
apt: name={{item}} state=installed
with_items:
- mysql-server-5.6
- python-mysqldb
- name: 生成新的 root 密碼
command: openssl rand -hex 7
register: mysql_new_root_pass
- name: 移除匿名使用者
mysql_user: name="" state=absent
- name: 移除測試資料函式庫
mysql_db: name=test state=absent
- name: 修改 root 密碼
mysql_user: name=root host={{ item }} password={{ mysql_new_root_pass.stdout }}
with_items:
- "{{ ansible_hostname }}"
- 127.0.0.1
- ::1
- localhost
內容解密:
- 安裝 MySQL 伺服器和 Python MySQLdb 套件。
- 使用
openssl命令生成一個隨機的 root 密碼,並將結果儲存在變數mysql_new_root_pass中。 - 使用
mysql_user和mysql_db模組移除匿名使用者和測試資料函式庫。 - 修改 MySQL 的 root 使用者密碼,並針對不同的主機名稱(包括 localhost 的不同表示方式)進行設定。
使用Ansible自動化安裝與設定WordPress
自動化MySQL安全設定
在佈署WordPress的過程中,MySQL資料函式庫的安全性至關重要。本章節將介紹如何使用Ansible自動化MySQL的安全設定。
步驟一:安裝MySQL伺服器
首先,使用Ansible的apt模組安裝MySQL伺服器和相關套件:
- name: Install MySQL
apt: name={{item}} state=present
with_items:
- mysql-server-5.6
- python-mysqldb
步驟二:生成新的root密碼
為了提高安全性,我們需要為MySQL的root使用者生成一個新的密碼。利用openssl命令生成隨機密碼:
- name: Generate new root password
command: openssl rand -hex 7 creates=/root/.my.cnf
register: mysql_new_root_pass
此步驟檢查是否存在/root/.my.cnf檔案,如果不存在,則執行密碼生成命令。
步驟三:移除匿名使用者和測試資料函式庫
移除MySQL中的匿名使用者和測試資料函式庫,以增強安全性:
- name: Remove anonymous users
mysql_user: name="" state=absent
when: mysql_new_root_pass.changed
- name: Remove test database
mysql_db: name=test state=absent
when: mysql_new_root_pass.changed
這些任務在生成新root密碼後執行,確保只有授權的使用者可以存取資料函式庫。
步驟四:更新root密碼並建立MySQL設定檔
更新root使用者的密碼,並建立/root/.my.cnf設定檔,以便Ansible無需密碼即可執行MySQL命令:
- name: Update root password
mysql_user: name=root host={{item}} password={{mysql_new_root_pass.stdout}}
with_items:
- "{{ ansible_hostname }}"
- 127.0.0.1
- ::1
- localhost
when: mysql_new_root_pass.changed
- name: Create my.cnf
template: src=templates/mysql/my.cnf dest=/root/.my.cnf
when: mysql_new_root_pass.changed
my.cnf檔案的內容如下:
[client]
user=root
password={{ mysql_new_root_pass.stdout }}
程式碼解析
- name: Generate new root password
command: openssl rand -hex 7 creates=/root/.my.cnf
register: mysql_new_root_pass
內容解密:
name: 定義任務名稱。command: 指定要執行的命令,此處為生成隨機密碼。creates: 如果指定的檔案存在,則不執行該命令。register: 將命令的輸出結果註冊到變數mysql_new_root_pass。
安裝nginx
完成MySQL的設定後,接下來需要安裝nginx作為Web伺服器,以處理HTTP請求並轉發給PHP處理WordPress的請求。
安裝nginx
使用Ansible的apt模組安裝nginx:
# nginx
- name: Install nginx
apt: name=nginx state=installed
程式碼解析
- name: Install nginx
apt: name=nginx state=installed
內容解密:
name: 定義任務名稱為"Install nginx"。apt: 使用Ansible的套件管理模組。name=nginx: 指定要安裝的套件名稱為nginx。state=installed: 確保nginx套件已安裝。