範例 4:新增流程控制 - AWS OpsWorks

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

範例 4:新增流程控制

重要

該 AWS OpsWorks Stacks 服務於 2024 年 5 月 26 日終止使用壽命,並已針對新客戶和現有客戶停用。我們強烈建議客戶盡快將其工作負載移轉至其他解決方案。如果您對移轉有任何疑問,請透過 AWS Re: post 或透過進AWS 階 Support 與 AWS Support 團隊聯絡。

有些配方只是一系列的 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 變數表示元素,在本例中表示目錄路徑。您可以輕鬆地調整此範例建立任意數目的子目錄。

執行配方
  1. 留在 createdir 目錄中,接下來數個範例都會使用該技術指南。

  2. 若尚未完成,請執行 kitchen destroy 以從乾淨的執行個體開始。

  3. 以範例取代 default.rb 中的程式碼並執行 kitchen converge

  4. 登入執行個體,您會在 /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
執行配方
  1. 若尚未完成,請執行 kitchen destroy 以從乾淨的執行個體開始。

  2. 以範例取代 default.rb 中的程式碼並執行 kitchen converge

  3. 登入執行個體,您會在指定模式的 /srv 下看到新建立的目錄。

注意

AWS OpsWorks 堆棧配方通常使用這種方法從堆棧配置和部署 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
執行範例配方
  1. 如果您的執行個體仍在執行中,請執行 kitchen destroy 關閉它。

  2. 以範例程式碼取代 default.rb 中的程式碼。

  3. 編輯 .kitchen.yml 將 CentOS 6.4 系統新增到平台清單。檔案的 platforms 區段看起來應該如下:

    ... platforms: - name: ubuntu-12.04 - name: centos-6.4 ...
  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 為收集系統資料 (包括平台) 的每個回合都執行名為 Ohai 的工具,在稱為「節點物件」的結構中用一組屬性表示此資料。Chef platform? 方法使用括號來比較系統和 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_platform 方法是比 if-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 資源則使用該值建立目錄。

執行範例配方
  1. 如果您的執行個體仍在執行中,請執行 kitchen destroy 關閉它。

  2. 以範例程式碼取代 default.rb 中的程式碼。

  3. 執行 kitchen converge,然後登入每個執行個體,以驗證是否有適當的目錄。