Test Kitchen 是一個用於測試基礎設施程式碼的框架,讓開發者能以自動化的方式驗證 Ansible Playbook 的正確性。透過結合 Vagrant 或 Docker 等虛擬化技術,Test Kitchen 能夠快速建立和銷毀測試環境,並使用 ServerSpec 進行驗證,確保 Playbook 的變更不會影響現有功能。此流程能有效提升 Playbook 的可靠性和可維護性,並降低基礎設施佈署的風險。文章將以一個簡單的 Nginx 安裝案例,逐步說明如何使用 Test Kitchen 進行測試。首先,設定測試環境,包含定義 .kitchen.yml 檔案,指定使用 Vagrant 或 Docker 作為驅動程式,並設定 Ansible Playbook 的路徑。接著,編寫 ServerSpec 測試案例,驗證 Nginx 套件是否已安裝、服務是否正在執行,以及是否監聽正確的埠。最後,執行 kitchen verify 命令,自動執行測試並輸出結果。
此圖示
此圖示顯示了 Test Kitchen 的工作流程和相關工具之間的關係,包括 Vagrant、Ansible playbook 和 ServerSpec 等。
解說:
- Test Kitchen 主要命令:圖表顯示了 Test Kitchen 的四個主要命令:
kitchen create、kitchen converge、kitchen verify和kitchen destroy。 - 相關工具:每個命令都與特定的工具或技術相關聯,例如
kitchen create與 Vagrant 相關,kitchen converge與 Ansible playbook 相關,kitchen verify與 ServerSpec 相關。 - 工作流程:圖表呈現了 Test Kitchen 的工作流程,從建立環境到執行測試,最後銷毀環境。
透過此圖示,我們可以清晰地瞭解 Test Kitchen 的工作流程和相關工具之間的關係,有助於更好地理解和使用 Test Kitchen 對 Ansible playbook 進行測試。
使用 Test Kitchen 進行測試
編寫第一個測試
第一個測試將會是一個簡單的範例。首先會執行一個安裝 nginx 的 playbook,並撰寫一個測試來確保 nginx 套件已安裝且正在正確的埠號上監聽。
定義測試環境
首先,需要定義測試環境。這是透過建立 .kitchen.yml 檔案並定義驅動程式、供應器和測試平台來完成的。在 ansible-kitchen 目錄下建立 .kitchen.yml 檔案,並加入以下內容:
---
driver:
name: vagrant
provisioner:
name: ansible_playbook
playbook: playbook.yml
hosts: all
require_chef_for_busser: false
require_ruby_for_busser: true
platforms:
- name: ubuntu
driver_config:
box: "ubuntu/trusty64"
suites:
- name: default
verifier:
ruby_bindir: '/usr/bin'
這裡指定了使用 Vagrant 來管理測試機器,並使用 ubuntu/trusty64 映象。建立此檔案後,可以執行 bundle exec kitchen create 來啟動測試機器。
建立 Playbook
接下來,需要建立一個 playbook 來執行。已經在 .kitchen.yml 中指定了 playbook 的名稱為 playbook.yml,因此需要在同一個目錄下建立 playbook.yml 檔案,並加入以下內容:
---
- hosts: all
tasks:
- apt: name=nginx state=installed
- service: name=nginx state=restarted
執行 Converge
要將變更套用到測試機器上,需要執行 bundle exec kitchen converge。這將會在測試機器上執行 Ansible,並安裝 nginx。
使用 ServerSpec 編寫測試
首先,需要登出測試機器並建立測試環境。執行以下指令來建立必要的資料夾和範例測試檔案:
mkdir -p test/integration/default/serverspec
這將會建立一個整合測試的資料夾。接下來,需要建立 spec_helper.rb 和 default_spec.rb 檔案。
spec_helper.rb 的內容如下:
require 'serverspec'
set :backend, :exec
default_spec.rb 的內容如下:
require 'spec_helper'
describe 'nginx installation' do
context package('nginx') do
it { should be_installed }
end
end
這個測試檢查 nginx 套件是否已安裝。
執行測試
最後,可以執行 bundle exec kitchen verify 來執行測試。
程式碼詳細解析:
以下對上述程式碼進行詳細解析:
.kitchen.yml
---
driver:
name: vagrant
provisioner:
name: ansible_playbook
playbook: playbook.yml
hosts: all
require_chef_for_busser: false
require_ruby_for_busser: true
platforms:
- name: ubuntu
driver_config:
box: "ubuntu/trusty64"
suites:
- name: default
verifier:
ruby_bindir: '/usr/bin'
內容解密:
- 指定使用 Vagrant 作為驅動程式。
- 設定 Ansible Playbook 的相關引數,包括 Playbook 的路徑和主機。
- 指定不需要安裝 Chef,但需要 Ruby 來安裝 Busser。
- 定義測試平台為 Ubuntu,並指定使用的 Vagrant box。
- 定義預設的測試套件,並設定 Ruby 的執行路徑。
playbook.yml
---
- hosts: all
tasks:
- apt: name=nginx state=installed
- service: name=nginx state=restarted
內容解密:
- 指定 Playbook 要執行的主機群組為所有主機。
- 定義兩個任務:安裝 nginx 和重啟 nginx 服務。
- 使用 Apt 模組來安裝 nginx。
- 使用 Service 模組來重啟 nginx 服務。
spec_helper.rb
require 'serverspec'
set :backend, :exec
內容解密:
- 載入 ServerSpec 函式庫。
- 設定 ServerSpec 的後端為執行(exec),表示將在本地端執行命令。
default_spec.rb
require 'spec_helper'
describe 'nginx installation' do
context package('nginx') do
it { should be_installed }
end
end
內容解密:
- 載入 spec_helper.rb,初始化 ServerSpec 環境。
- 定義一個描述區塊,描述的是 nginx 的安裝。
- 使用 context 定義一個上下文,檢查 nginx 套件。
- 使用 it 定義一個測試專案,檢查 nginx 是否已安裝。
使用 Test Kitchen 進行測試
介紹 Test Kitchen 與其支援工具
Test Kitchen 是用於測試基礎設施程式碼的工具,能夠讓開發者對其 Ansible Playbook 進行自動化測試。本章節將介紹如何使用 Test Kitchen 來測試你的 Ansible Playbook。
編寫第一個 ServerSpec 測試
首先,你需要編寫一個 ServerSpec 測試,以確保 nginx 已正確安裝。以下是一個簡單的測試範例:
context package('nginx') do
it { should be_installed }
end
這個測試檢查 nginx 套件是否已安裝。你可以使用 kitchen verify 命令來執行這個測試。
內容解密:
context用於定義測試的上下文。package('nginx')指定要測試的套件。it { should be_installed }檢查該套件是否已安裝。
你可以進一步新增測試,以確保 nginx 正在監聽預設的 80 埠:
context port(80) do
it { should be_listening }
end
內容解密:
port(80)指定要測試的埠。it { should be_listening }檢查該埠是否正在監聽。
你還可以使用 curl 命令來檢查 nginx 是否傳回正確的內容:
context command('curl http://localhost') do
its(:stdout) do
should contain 'Welcome to nginx'
end
end
內容解密:
command('curl http://localhost')指定要執行的命令。its(:stdout)檢查命令的輸出。should contain 'Welcome to nginx'檢查輸出是否包含特定的字串。
更輕量級的測試
使用 Docker 取代 Vagrant 可以顯著提高測試的速度。首先,你需要更新 .kitchen.yml 檔案,以使用 Docker 驅動程式:
driver:
name: docker
use_sudo: false
provisioner:
name: ansible_playbook
playbook: playbook.yml
hosts: all
platforms:
- name: ubuntu
driver_config:
image: ubuntu:14.04
suites:
- name: default
verifier:
ruby_bindir: '/usr/bin'
內容解密:
driver.name指定使用的驅動程式。platforms指定要測試的平台。driver_config.image指定要使用的 Docker 映象。
接下來,你需要更新 Gemfile 以包含 kitchen-docker:
source 'https://rubygems.org'
gem 'test-kitchen', '~> 1.0'
gem 'kitchen-ansible', '~> 0.44'
gem 'kitchen-docker', '~> 2.5'
gem 'serverspec', '~> 2.36'
內容解密:
source指定 Gem 的來源。gem指定要安裝的 Gem。
測試 WordPress Role
現在,你可以開始為 WordPress Role 編寫測試。首先,建立一個新的 .kitchen.yml 檔案,並組態 Test Kitchen 以使用 Docker 驅動程式:
driver:
name: docker
use_sudo: false
provisioner:
name: ansible_playbook
playbook: playbook.yml
hosts: all
platforms:
- name: ubuntu
driver_config:
image: ubuntu:14.04
suites:
- name: default
verifier:
ruby_bindir: '/usr/bin'
這個組態檔案將使用現有的 playbook.yml 檔案來組態 Test Kitchen 環境。接下來,你可以開始編寫測試,以確保 WordPress Role 的正確性。
進階 Ansible 測試與應用
使用 Test Kitchen 進行測試
在前面的章節中,我們已經瞭解如何使用 Ansible 建立 WordPress 環境。現在,我們將介紹如何使用 Test Kitchen 對 Ansible Playbook 進行測試。Test Kitchen 是一個測試框架,能夠幫助我們驗證 Playbook 的正確性。
首先,我們需要在專案中安裝 Test Kitchen。由於我們之前使用了 Bundler 安裝 Test Kitchen,因此它被安裝在專案的本地環境中。請確保目前所在的目錄是 playbook.yml 所在的目錄,並建立一個名為 Gemfile 的檔案,內容如下:
source 'https://rubygems.org'
gem 'test-kitchen', '~> 1.0'
gem 'kitchen-ansible', '~> 0.44'
gem 'kitchen-docker', '~> 2.5'
gem 'serverspec', '~> 2.36'
接著,執行 bundle install --path vendor/bundle 以下載所需的依賴套件。完成後,執行 bundle exec kitchen converge 將建立一個 Docker 容器並執行 Playbook,以安裝 WordPress 及其依賴套件。
編寫測試
建立測試目錄結構和 Serverspec Helper:
mkdir -p test/integration/default/serverspec
在 test/integration/default/serverspec/ 目錄下建立 spec_helper.rb:
require 'serverspec'
set :backend, :exec
接下來,建立 default_spec.rb 以編寫測試:
require 'spec_helper'
describe 'nginx installation' do
context package('nginx') do
it { should be_installed }
end
context service('nginx') do
it { should be_running }
end
end
describe 'mysql installation' do
context package('mysql-server-5.6') do
it { should be_installed }
end
context service('mysql') do
it { should be_running }
end
end
describe 'php installation' do
context package('php') do
it { should be_installed }
end
context service('php7.0-fpm') do
it { should be_running }
end
context command('php --version') do
its(:stdout) { should contain 'PHP 7' }
end
end
describe 'wordpress' do
context file('/var/www/book.example.com/wp-config.php') do
it { should exist }
end
context command('mysql -u root michaelwp -e "SELECT post_title FROM wp_posts WHERE id=1;"') do
its(:stdout) { should contain 'Hey There' }
end
end
執行測試
執行 bundle exec kitchen verify 以執行測試。如果所有測試透過,將顯示類別似以下的輸出:
nginx installation
Package "nginx"
should be installed
Service "nginx"
should be running
mysql installation
Package "mysql-server-5.6"
should be installed
Service "mysql"
should be running
php installation
Package "php"
should be installed
Service "php7.0-fpm"
should be running
Command "php --version"
stdout
should contain "PHP 7"
wordpress
File "/var/www/book.example.com/wp-config.php"
should exist
Command "mysql -u root michaelwp -e \"SELECT post_title FROM wp_posts WHERE id=1;\""
stdout
should contain "Hey There"
Finished in 0.35718 seconds (files took 0.51265 seconds to load)
9 examples, 0 failures
重構與驗證
未來若對 WordPress Role 有任何變更,只需重新執行這些測試,即可確認變更是否正確。這樣可以提高對 Playbook 的信心,確保相關軟體安裝和組態正確。
Ansible 命令列工具
除了執行 Playbook,Ansible 也提供了 ansible 命令列工具,用於執行臨時命令。雖然通常建議將所有操作寫入 Playbook 以便版本控制和稽核,但 ansible 命令列工具仍有其用途。
使用範例
要使用 ansible 命令列工具在 Web 群組中的所有主機上安裝 nginx,可以執行以下命令:
ansible web –i /path/to/inventory –m apt –a 'name=nginx state=installed'
這對於需要臨時升級套件或處理安全性問題時很有用,但相較於使用 Playbook,這種方式缺乏可重現性。