本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
範例 4:新增流程控制
重要
AWS OpsWorks Stacks 此服務已於 2024 年 5 月 26 日終止,並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載遷移至其他解決方案。如果您對遷移有任何疑問,請透過 AWS re:Post
有些配方只是一系列的 Chef 資源。在這種情況下,當您執行配方時,它僅會依序執行每個資源提供者。不過,有更精密的執行路徑通常會很有幫助。下列是兩個常見情況:
-
您想要某個配方以不同的屬性設定多次執行相同的資源。
-
您想要在不同的作業系統上使用不同的屬性設定。
您可以將 Ruby 控制結構併入配方以處理類似的情況。本節示範如何修改範例 3:建立目錄中的配方來處理這兩種情況。
重複
範例 3:建立目錄示範如何使用 directory 資源來建立目錄或目錄鏈。不過,假設您要建立兩個不同的目錄 /srv/www/config 和 /srv/www/shared。您可以分別為每個目錄實作目錄資源,但如果您想要建立非常多的目錄,這種方法太過繁瑣。下列配方示範處理此任務的較簡單方式。
[ "/srv/www/config", "/srv/www/shared" ].each do |path| directory path do mode 0755 owner 'root' group 'root' recursive true action :create end end
配方使用包含子目錄路徑的字串集合,而不是為每個子目錄分別使用目錄資源。Ruby each 方法從第一個元素開始,為每個集合元素執行一次資源。資源中以 path 變數表示元素,在本例中表示目錄路徑。您可以輕鬆地調整此範例建立任意數目的子目錄。
執行配方
-
留在
createdir目錄中,接下來數個範例都會使用該技術指南。 -
若尚未完成,請執行
kitchen destroy以從乾淨的執行個體開始。 -
以範例取代
default.rb中的程式碼並執行kitchen converge。 -
登入執行個體,您會在
/srv下看到新建立的目錄。
您可以使用雜湊表為每次重複指定兩個值。下列配方建立 /srv/www/config 和 /srv/www/shared,每個都有不同的模式。
{ "/srv/www/config" => 0644, "/srv/www/shared" => 0755 }.each do |path, mode_value| directory path do mode mode_value owner 'root' group 'root' recursive true action :create end end
執行配方
-
若尚未完成,請執行
kitchen destroy以從乾淨的執行個體開始。 -
以範例取代
default.rb中的程式碼並執行kitchen converge。 -
登入執行個體,您會在指定模式的
/srv下看到新建立的目錄。
注意
OpsWorks Stacks 配方通常會使用此方法從堆疊組態和部署 JSON 擷取值,基本上是大型雜湊資料表,並將其插入資源。如需範例,請參閱「部署配方」。
條件式邏輯
您也可以使用 Ruby 條件式邏輯來建立多個執行分支。下列配方使用 if-elsif-else 邏輯來擴展前一個範例,以便建立名為 /srv/www/shared 的子目錄,但只限於 Debian 和 Ubuntu 系統。針對所有其他系統,其會記錄顯示在 Test Kitchen 輸出中的錯誤訊息。
if platform?("debian", "ubuntu") directory "/srv/www/shared" do mode 0755 owner 'root' group 'root' recursive true action :create end else log "Unsupported system" end
執行範例配方
-
如果您的執行個體仍在執行中,請執行
kitchen destroy關閉它。 -
以範例程式碼取代
default.rb中的程式碼。 -
編輯
.kitchen.yml將 CentOS 6.4 系統新增到平台清單。檔案的platforms區段看起來應該如下:... platforms: - name: ubuntu-12.04 - name: centos-6.4 ... -
執行
kitchen converge,這會建立執行個體,並依序為.kitchen.yml中的每個平台執行配方。注意
如果您想收歛成僅只一個執行個體,請將執行個體名稱新增為參數。例如,若要將配方收歛成僅在 Ubuntu 平台,請執行
kitchen converge default-ubuntu-1204。如果您忘記了平台名稱,只要執行kitchen list即可。
您應該會在 Test Kitchen 的 CentOS 部分看到您的日誌訊息,它看起來類似如下:
... Converging 1 resources Recipe: createdir::default * log[Unsupported system] action write[2014-06-23T19:10:30+00:00] INFO: Processing log[Unsupported system] action write (createdir::default line 12) [2014-06-23T19:10:30+00:00] INFO: Unsupported system [2014-06-23T19:10:30+00:00] INFO: Chef Run complete in 0.004972162 seconds
您現在可以登入執行個體並驗證是否已建立目錄。不過,現在無法僅執行 kitchen login。您必須透過附加平台名稱來指定執行個體,例如 kitchen
login default-ubuntu-1204。
注意
如果 Test Kitchen 命令接受執行個體名稱,您就不需要輸入完整的名稱。Test Kitchen 會將執行個體名稱視為 Ruby 規則表達式,因此您只需要可提供唯一相符的足夠字元即可。例如,您可以透過執行 kitchen
converge ub 收歛成僅 Ubuntu 執行個體,或透過執行 kitchen
login 64 登入 CentOS 執行個體。
此時可能有的疑問,是配方如何知道它在哪個平台上執行。Chef 為收集系統資料 (包括平台) 的每個回合都執行名為 Ohaiplatform? 方法使用括號來比較系統和 Ohai 平台值,如果其中一項符合即傳回 true。
您可以使用 node[' 直接參考您程式碼中的節點屬性值。例如,平台值以 attribute_name']node['platform'] 表示。例如,您可能將前述範例撰寫如下。
if node[:platform] == 'debian' or node[:platform] == 'ubuntu' directory "/srv/www/shared" do mode 0755 owner 'root' group 'root' recursive true action :create end else log "Unsupported system" end
在配方中包含條件邏輯的常見原因,是為了因應不同的 Linux 系列有時使用不同的套件名稱、目錄等等。例如,Apache 套件名稱在 CentOS 系統為 httpd,在 Ubuntu 系統為 apache2。
如果只是因為不同的系統需要不同的字串,Chef value_for_platformif-elsif-else 更簡單的解決方案。下列配方在 CentOS 系統中建立 /srv/www/shared 目錄,在 Ubuntu 系統中建立 /srv/www/data 目錄,在所有其他系統中建立 /srv/www/config。
data_dir = value_for_platform( "centos" => { "default" => "/srv/www/shared" }, "ubuntu" => { "default" => "/srv/www/data" }, "default" => "/srv/www/config" ) directory data_dir do mode 0755 owner 'root' group 'root' recursive true action :create end
value_for_platform 將適當的路徑指派給 data_dir,而 directory 資源則使用該值建立目錄。
執行範例配方
-
如果您的執行個體仍在執行中,請執行
kitchen destroy關閉它。 -
以範例程式碼取代
default.rb中的程式碼。 -
執行
kitchen converge,然後登入每個執行個體,以驗證是否有適當的目錄。