Learn Chef Rally 學習筆記 part1 — 基本 resource 範例

Luyo
verybuy-dev
Published in
13 min readJul 21, 2017

從以前就一直很想把公司的機器架設方式版本化,所以開始接觸 Docker,但後來發現 Docker 並不是這麼適合用來做這件事,於是才又開始想學 Chef。

但 Chef 看來也並不是簡單到拿別人寫好的東西改一改就可以用的一套工具,那麼就從頭學吧,進入 Learn Chef Rally 註冊了帳號,順著教學一步一步來。

Learn Chef Rally 裡的課程由許多小單元 (module) 組成,分成兩個教學系統:Tracks 及 Modules。Tracks 就是帶你從頭開始一步一步學習,共有 13 個 Track,每個主題裡又有若干個 module,Track 的招牌上都有預估的課程耗時,數字還蠻嚇人的,動不動就是 8 小時;Modules 則是把所有小單元一字排開,如果想跳著學的人會比較方便。

本文記錄以下章節的學習歷程:

  1. Track — Getting Started > Module — 1 Getting started with Learn Chef Rally
  2. Track — Infrastructure Automation > Module — 1 Learn the Chef basics 的 0% — 60%。

Track — Getting Started > Module — 1 Getting started with Learn Chef Rally

這個單元以介紹為主,以下節錄重點:

  • Learn Chef Rally 這個地方可以幫助你建立 Chef 及 DevOps 的技術能力。
  • 課程以 Tracks 的學習系統為主,一個 Track 裡會有幾個 module,每個 module 裡可能又會分成若干章節。
  • 在 module 的課程章節裡章節中的結尾會有一些小測驗,要全部答對才可以往前邁進。
  • 當你完成一個 module 的課程後會幫你在 Track 上蓋個章,讓你比較有成就感。
  • 如果你有註冊帳號,從不同裝置登入就可以同步你的學習進度,並且在網站推出新內容時收到通知。

以下節錄文章內提到的 Chef 開發資源:

然後我查了一下,rally 這個字是拉力賽的意思,可見這條學習之路肯定是不輕鬆啊……

Track — Infrastructure Automation > Module — 1 Learn the Chef basics

這個單元一開始就會問你使用的環境是什麼。我選的環境如下:

  • server platform: Red Hat Enterprise Linux
  • operating environment: Amazon Web Services

接著它告訴我們這一個單元結束後,你會學到:

  • 說明 Chef 跑起來之後會發生什麼事
  • 編寫一段基本的 Chef 程式碼
  • 在你的機器上運行這段程式碼

[Set up an AWS instance to manage]

這個章節一開始就是要你開一台新的 CentOS 7 起來並連線進去,因為這個動作很基本也常常在做,所以這部分就不記錄了。

接下來就是安裝 Chef:

curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P chefdk -c stable -v 0.16.28

然後把自己習慣的編輯器裝一下,我用的是 vim:

sudo yum install vim -y

文章最後提醒大家如果不用了一定要把機器關掉,不然放著不用就會一直噴錢。

[Configure a resource]

一開始有兩個常用名詞 “Chef resource”、”Chef recipe” 的意義要強調一下:

KEY POINT: A Chef resource describes one part of the system, such as a file or a package. A Chef recipe is a file that groups related resources, such as everything needed to configure a web server, database server, or a load balancer.

resource 直接翻譯就是「資源」,對我來說這段話的意思大致上是:

一個 “Chef recipe” 是由多個 “Chef resource” 組成的,這些 resource 有可能是 web server, database server 或是 load balancer 之類的系統資源。

因為我也是新手,所以上面解讀不保證正確,請斟酌。

接下來是一個 “Message of the Day” (MOTD) 的範例。

1. 設定工作目錄

$ mkdir ~/chef-repo
$ cd ~/chef-repo

2. 新增 MOTD 檔案

新增一個檔案,檔名為 hello.rb,內容為

file '/tmp/motd' do
content 'hello world'
end

接下來執行 chef-client 指令

$ chef-client --local-mode hello.rb
[2017-07-20T09:33:06+00:00] WARN: No config file found or specified on command line, using command line options.
[2017-07-20T09:33:06+00:00] WARN: No cookbooks directory found at or above current directory. Assuming /home/yo/chef-repo.
Starting Chef Client, version 12.12.15
resolving cookbooks for run list: []
Synchronizing Cookbooks:
Installing Cookbook Gems:
Compiling Cookbooks...
[2017-07-20T09:33:07+00:00] WARN: Node ip-172-31-18-184.ap-southeast-1.compute.internal has an empty run list.
Converging 1 resources
Recipe: @recipe_files::/home/yo/chef-repo/hello.rb
* file[/tmp/motd] action create
- create new file /tmp/motd
- update content in file /tmp/motd from none to b94d27
--- /tmp/motd 2017-07-20 09:33:07.892346028 +0000
+++ /tmp/.chef-motd20170720-4378-1lu4jjv 2017-07-20 09:33:07.892346028 +0000
@@ -1 +1,2 @@
+hello world
- restore selinux security context
Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 01 seconds

這個 hello.rb 裡定義了檔案系統中要有一個檔案叫做 /tmp/motd ,檔案內容是 hello world,執行 chef-client 指令之後,chef 會自動去產生這個檔案並寫入內容。

所以這時候你就可以去檢查一下 /tmp/motd 這個檔案是否存在,內容是不是 hello world。理論上結果會長這樣:

$ more /tmp/motd
hello world

註:這邊的 chef-client 指令使用 --local-mode 這個 option,意思就是直接在 local 端執行。

同樣的指令再執行一次

因為我們本來沒有 /tmp/motd 這個檔案,所以 chef 幫我們產生了這個檔案。但現在這個檔案已經存在了,再度執行同樣的 chef-client 指令會發生什麼事?

$ chef-client --local-mode hello.rb
(略)
Recipe: @recipe_files::/home/yo/chef-repo/hello.rb
* file[/tmp/motd] action create (up to date)
Running handlers:
Running handlers complete
Chef Client finished, 0/1 resources updated in 01 seconds

它告訴我們這個檔案的狀態是 update to date,就不多做事了。

確認 /tmp/motd

$ more /tmp/motd
hello world

跟原來是一樣的。

3. 更新範例內容

接下來更改 hello.rb 檔案內容為:

file '/tmp/motd' do
content 'hello chef'
end

檔案內容本來是 hello world,改成 hello chef。接著再次執行 chef-client 指令:

$ chef-client --local-mode hello.rb
(略)
Recipe: @recipe_files::/home/yo/chef-repo/hello.rb
* file[/tmp/motd] action create
- update content in file /tmp/motd from b94d27 to c38c60
--- /tmp/motd 2017-07-20 09:33:07.892346028 +0000
+++ /tmp/.chef-motd20170720-4820-58a1d5 2017-07-20 09:58:29.849339598 +0000
@@ -1,2 +1,2 @@
-hello world
+hello chef
- restore selinux security context
Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 01 seconds

檢查 /tmp/motd

$ more /tmp/motd
hello chef

可以發現檔案內容被更新了。

4. 確保檔案內容不會被變更

現在我們把 /tmp/motd 的內容改掉:

$ echo 'hello robots' > /tmp/motd

檢查 /tmp/motd

$ more /tmp/motd
hello robots

接著再度執行一次同樣的 chef-client 指令:

$ chef-client --local-mode hello.rb
(略)
Recipe: @recipe_files::/home/yo/chef-repo/hello.rb
* file[/tmp/motd] action create
- update content in file /tmp/motd from 548078 to c38c60
--- /tmp/motd 2017-07-20 10:03:41.524851889 +0000
+++ /tmp/.chef-motd20170720-5050-q6agkv 2017-07-20 10:04:55.755639563 +0000
@@ -1,2 +1,2 @@
-hello robots
+hello chef
- restore selinux security context
Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 01 seconds

檢查 /tmp/motd

$ more /tmp/motd
hello chef

檔案內容雖被改過,但此時已被還原成 hello chef 了。可見 Chef 可以幫我們確保 /tmp/motd 這個檔案的內容是 hello.rb 裡面定義的 hello chef 而不是其他的內容。

5. 刪除範例檔案

~/chef-repo 底下新增並編輯檔案 goodbye.rb

file '/tmp/motd' do
action :delete
end

然後以 chef-client 執行這支檔案:

$ chef-client --local-mode goodbye.rb
[2017-07-20T10:14:28+00:00] WARN: No config file found or specified on command line, using command line options.
[2017-07-20T10:14:28+00:00] WARN: No cookbooks directory found at or above current directory. Assuming /home/yo/chef-repo.
Starting Chef Client, version 12.12.15
resolving cookbooks for run list: []
Synchronizing Cookbooks:
Installing Cookbook Gems:
Compiling Cookbooks...
[2017-07-20T10:14:30+00:00] WARN: Node ip-172-31-18-184.ap-southeast-1.compute.internal has an empty run list.
Converging 1 resources
Recipe: @recipe_files::/home/yo/chef-repo/goodbye.rb
* file[/tmp/motd] action delete
- delete file /tmp/motd
Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 01 seconds

檢查 /tmp/motd

$ more /tmp/motd
/tmp/motd: 沒有此一檔案或目錄

檔案 /tmp/motd 就被我們刪掉了。

小結

  • 在 chef recipe 中,每個 chef resource 只需要「宣告」整個系統的特定部分會「長得什麼樣子」,而非「如何讓它長成那個樣子」。「如何」的這個部分 Chef 會幫你做掉。
  • 上面範例的 hello.rb 就是一個所謂 recipe 的範例;內容裡的 file '/tmp/motd' 就是所謂的 resource,而開頭的 "file" 是這個 resource 的類型。

測驗

What is a resource?

  • Read-only data identified by a type and a name.
  • A description of some piece of a system and its desired state.
  • An ordered series of configuration states.

What is a recipe?

  • A file that groups related resources.
  • A file that configures the chef-client run.
  • A file that configures your workstation.

What happens when you don’t specify a resource’s action?

  • You get an error message but the chef-client run continues.
  • You get an error message and the chef-client run halts.
  • The default action is assumed.

答案是 2, 1, 3。

--

--