本文說明如何使用 Terraform 管理雲端資源狀態,包含移除不需要的資源和匯入現有資源到 Terraform 管理,並示範如何使用 Ansible 自動化設定和佈署伺服器。文章涵蓋了 Terraform 的 state rm、import 等重要指令,以及 Ansible 的 inventory 檔案設定、SSH 金鑰管理、和 playbook 撰寫等實務技巧。讀者將學習如何結合 Terraform 和 Ansible,實作基礎設施即程式碼和自動化組態管理,提升 DevOps 工作流程效率。
Terraform 狀態管理對於維護基礎設施的一致性至關重要。terraform state rm 命令可以從狀態中移除資源,但不會影響實際資源。移除資源時,務必注意狀態一致性和資源依賴關係,並備份狀態檔案。terraform import 命令可以將現有資源匯入 Terraform 狀態,整合現有基礎設施到 IaC 流程。匯入時,需要正確識別資源 ID 和型別,確保 Terraform 組態與現有資源屬性比對,並處理好資源依賴關係。terraform console 可以檢視狀態資訊,terraform graph 可以生成資源依賴圖,協助理解和管理資源關係。terraform destroy 可以清理資源,但在生產環境需謹慎操作。
為了有效管理伺服器,需要建立 Ansible 控制節點與受控伺服器之間的連線。建立名為 ansible 的專用使用者,並設定免密碼 SSH 連線,可以簡化 Ansible 操作。Ansible 使用 inventory 檔案管理節點,可以根據角色對受控節點進行分組。Inventory 檔案的 ansible_host 變數可以為主機定義別名,簡化主機管理。Ansible 的設定檔可以自定義 Ansible 行為,建議在專案的 Git 儲存函式庫中包含 ansible.cfg 檔案,確保組態的版本控制。可以使用 ansible-inventory、ansible --list-hosts 和 ansible -m ping 等指令檢查和管理 inventory 組態。Ansible 的核心功能是透過任務和模組實作的,ansible <options> <inventory> 是基本任務執行語法。shell 模組可以用於執行遠端指令。
從 Terraform 狀態中移除資源與匯入現有資源:深入解析與最佳實踐
在現代化的 DevOps 實踐中,Terraform 作為基礎設施即程式碼 (IaC) 的核心工具,其狀態管理功能對於維護基礎設施的一致性和可靠性至關重要。本文將探討如何從 Terraform 狀態中移除資源以及如何匯入現有資源,同時涵蓋相關的最佳實踐和注意事項。
從狀態中移除資源:操作與注意事項
當需要從 Terraform 狀態中移除資源時,通常是因為該資源已經在 Terraform 之外被修改或刪除。正確地移除資源需要謹慎的操作,以避免對實際的基礎設施造成不必要的變更。
使用 terraform state rm 命令
terraform state rm 命令允許使用者從 Terraform 狀態檔案中移除指定的資源。這個操作僅僅是從狀態記錄中刪除資源,而不會影響實際的雲端資源。
terraform state rm azurerm_virtual_machine.main
執行此命令後,Terraform 將不再管理該虛擬機器,但該虛擬機器本身在 Azure 上仍然存在。建議在執行此操作前,先確認資源不再需要,或已經在其他地方被妥善管理。
重要注意事項
- 狀態一致性:移除資源後,確保 Terraform 狀態與實際基礎設施狀態保持一致。
- 資源依賴:檢查被移除資源的依賴關係,避免因移除資源導致其他資源建立或銷毀失敗。
- 備份狀態檔案:在進行狀態修改前,務必備份狀態檔案,以防意外情況發生。
匯入現有資源到 Terraform 狀態
對於已經存在的基礎設施,Terraform 提供了 terraform import 命令來將這些資源納入管理。這對於整合現有資源到 IaC 流程中至關重要。
使用 terraform import 命令
terraform import 命令的基本語法如下:
terraform import <resource_type>.<resource_name> <resource_id>
例如,要匯入一台名為 httpd 的虛擬機器,可以執行:
terraform import -var env=dev azurerm_virtual_machine.main "/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/terraform-ws-dev/providers/Microsoft.Compute/virtualMachines/httpd"
匯入過程中的注意事項
- 資源識別:正確識別要匯入資源的 ID 和型別。
- 組態比對:確保 Terraform 組態與現有資源的屬性相比對。
- 依賴管理:處理好匯入資源的依賴關係,確保 Terraform 能夠正確管理資源。
使用 terraform console 檢視狀態資訊
terraform console 提供了一個互動式環境,用於查詢和驗證 Terraform 狀態中的資源屬性。
terraform console
> azurerm_virtual_machine.main.resource_group_name
"terraform-ws-dev"
> azurerm_virtual_machine.main.id
"/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/terraform-ws-dev/providers/Microsoft.Compute/virtualMachines/httpd"
> exit
這個工具對於除錯和驗證資源屬性非常有用。
資源依賴關係與圖表生成
Terraform 內建了依賴圖生成功能,可以幫助理解和管理資源之間的依賴關係。
使用 terraform graph 命令
terraform graph > vm.dot
然後使用 Graphviz 將 .dot 檔案轉換為 PNG 影像:
sudo apt install graphviz -y
cat vm.dot | dot -T png -o vm.png
生成的圖表直觀地展示了資源之間的依賴關係,有助於最佳化 IaC 組態。
清理與銷毀資源
在開發和測試環境中,使用 terraform destroy 可以快速清理不再需要的資源。
terraform destroy -var env=dev -auto-approve
銷毀資源的注意事項
- 生產環境謹慎操作:在生產環境中使用
terraform destroy時需格外小心,避免誤刪重要資源。 - 替代方案:考慮從組態中移除不需要的資源,然後執行
terraform apply進行增量更新。
Terraform 狀態管理流程
流程說明
上述 Plantuml 圖表展示了 Terraform 狀態管理的關鍵命令及其功能:
terraform state rm:從狀態中移除資源。terraform import:匯入現有資源到 Terraform 狀態。terraform console:互動式檢視狀態資訊。terraform graph:生成資源依賴圖。terraform destroy:銷毀由 Terraform 管理的資源。
連線 Ansible 控制節點與受控伺服器
為了有效管理伺服器,我們需要建立 Ansible 控制節點與受控伺服器之間的連線。以下步驟將引導您建立名為 ansible 的 Ansible 專用使用者,並設定免密碼 SSH 連線,以便從 Ansible 控制節點連線到受控伺服器。
建立 Ansible 使用者和設定 SSH 金鑰
在您的控制節點上執行以下指令,建立 ansible 使用者,將其新增至 sudoers 列表,並產生 SSH 金鑰對以進行免密碼驗證:
sudo su - root
useradd -m ansible
echo 'ansible ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
sudo su - ansible
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
內容解密:
此步驟建立了一個名為 ansible 的專用使用者,用於執行 Ansible 相關任務。透過將其新增至 sudoers 列表並設定免密碼 sudo 存取,確保 ansible 使用者可以執行管理任務。隨後產生的 SSH 金鑰對將用於與受控節點建立安全連線。
設定受控節點的 SSH 公鑰
產生金鑰後,使用以下指令印出公鑰:
cat ~/.ssh/id_rsa.pub
複製輸出的公鑰。接著,登出 ansible 和 root 使用者,使用您在 Terraform 範本中定義的使用者 SSH 登入 web 伺服器:
ssh web
流程說明:
此圖展示了控制節點與多個受控節點之間的連線設定。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Terraform Ansible 自動化資源管理與佈署
package "Terraform 工作流程" {
actor "DevOps" as dev
package "本地開發" {
component [.tf 設定檔] as tf
component [terraform.tfvars] as vars
component [.tfstate] as state
}
package "Terraform Core" {
component [Init] as init
component [Plan] as plan
component [Apply] as apply
component [Destroy] as destroy
}
package "Providers" {
cloud "AWS" as aws
cloud "GCP" as gcp
cloud "Azure" as azure
}
database "Remote State" as remote
}
dev --> tf : 編寫配置
tf --> init : 初始化
init --> plan : 規劃變更
plan --> apply : 執行變更
apply --> aws : 建立資源
apply --> gcp : 建立資源
apply --> azure : 建立資源
apply --> state : 更新狀態
state --> remote : 同步狀態
@enduml輸入密碼後,您應該會登入 web 伺服器。在 web 伺服器上重複與控制節點相同的步驟來建立 ansible 使用者:
sudo su - root
useradd -m ansible
echo 'ansible ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
sudo su - ansible
mkdir -p ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
接著,將先前複製的控制節點的公鑰新增至 web 伺服器 ansible 使用者的 authorized_keys 檔案中:
vim ~/.ssh/authorized_keys
將公鑰貼上到檔案中,然後儲存並離開。
內容解密:
在受控節點上建立 ansible 使用者並設定 authorized_keys 檔案可讓控制節點透過 SSH 金鑰驗證進行免密碼存取。這種方法增強了安全性和自動化效率。
測試 SSH 連線
完成後,登出 web 伺服器,回到控制節點。在控制節點上,切換至 ansible 使用者,並嘗試使用 SSH 連線到 web 伺服器:
sudo su - ansible
ssh web
如果您成功登入 web 伺服器而無需輸入密碼,則表示免密碼驗證設定正確。對 db 伺服器重複相同的步驟。
設定 Ansible Inventory 檔案
Ansible 使用 inventory 檔案來管理節點。Inventory 檔案允許您根據角色對受控節點進行分組,例如,您可以定義 webserver 和 dbserver 等角色,並將相關伺服器分組在一起。
設定 Inventory 檔案內容
在我們的案例中,我們有一個名為 web 的 web 伺服器和一個名為 db 的 db 伺服器。hosts 檔案內容如下:
[webservers]
web ansible_host=web
[dbservers]
db ansible_host=db
[all:vars]
ansible_python_interpreter=/usr/bin/python3
內容解密:
此 inventory 設定將受控節點分為 webservers 和 dbservers 兩個群組。它使用 ansible_host 變數將主機別名對映到實際主機名稱。 [all:vars] 部分定義了所有主機共用的變數,在此指定使用 Python 3 作為 Ansible 的 Python 直譯器。
管理 Inventory 檔案許可權
Ansible inventory 檔案的預設位置是 /etc/ansible/hosts。由於我們希望使用 ansible 使用者,因此需要將 /etc/ansible 目錄及其子目錄和檔案的所有權變更為 ansible:
sudo chown -R ansible:ansible /etc/ansible
然後,切換至 ansible 使用者,並將包含必要檔案的 Git 儲存函式庫複製到控制伺服器:
sudo su - ansible
cd ~/modern-devops/ch7/ansible-exercise
Ansible 自動化佈署
inventory 組態與主機管理
在現代 IT 基礎設施管理中,Ansible 提供了一個強大的自動化解決方案。本章節將詳細介紹如何組態 Ansible inventory 並管理遠端主機,同時確保設定的版本控制和可維護性。
主機別名組態與最佳實踐
使用 ansible_host 變數為主機定義別名是一種常見的做法。例如,將 web 定義為指向實際主機名稱或 IP 位址的別名。這種方法特別適用於需要維護多個具有相似組態的主機環境。
# hosts 檔案範例
[webservers]
web ansible_host=webserver.local
[dbservers]
db ansible_host=database.local
這種組態方式不僅簡化了主機管理,還提高了 inventory 的可讀性。透過將功能相似的主機分組,可以輕鬆地對特定群組應用統一的組態變更。
設定 Ansible 組態檔的最佳實踐
Ansible 的行為可以透過設定檔進行自定義。系統按照特定順序搜尋設定檔,包括環境變數 ANSIBLE_CONFIG、目前目錄、使用者家目錄和 /etc/ansible 目錄。建議在專案的 Git 儲存函式庫中包含 ansible.cfg 檔案,以實作 GitOps 流程並確保組態的版本控制。
# ansible.cfg 範例
[defaults]
inventory = ./hosts
host_key_checking = False
這種設定方法確保了專案組態的獨立性和可移植性。每個專案都可以維護自己的設定,而不會影響其他專案的組態。
inventory 管理與驗證
正確組態 inventory 後,需要進行驗證以確保設定的正確性。Ansible 提供了多個指令來檢查和管理 inventory 組態:
清單管理指令
列出詳細的 inventory 組態
ansible-inventory --list -y此指令以 YAML 格式顯示 inventory 的詳細組態,有助於檢查主機分組和變數設定。
列出所有主機
ansible --list-hosts all顯示 inventory 中定義的所有主機,驗證主機清單的完整性。
檢查特定群組的主機
ansible --list-hosts webservers列出屬於
webservers群組的所有主機,方便進行群組層級的管理。測試連線性
ansible all -m ping對所有主機執行連線測試,確保 Ansible 可以成功連線到受控節點。
Ansible 任務與模組的使用
Ansible 的核心功能是透過任務(tasks)和模組(modules)來實作的。任務是 Ansible 自動化的基本單位,而模組則是實作特定功能的程式碼單元。
基本任務執行語法
ansible <options> <inventory>
使用 shell 模組執行遠端指令
以下範例展示瞭如何使用 shell 模組在所有受控節點上執行 uname 指令:
ansible -m shell -a "uname" all
此指令的組成部分包括:
-m shell:指定要使用的模組名稱-a "uname":提供給模組的引數all:執行任務的目標主機範圍
執行結果將傳回每個受控節點的作業系統資訊,透過傳回碼和輸出確認指令的執行狀態。