概要
Chefでのテンプレート操作をキャッチアップした時の備忘録です。
この記事では、下記を整理しています。
- テンプレートResourceの使い方
-
Role
で変数を設定する方法 -
Enviroment
で変数を設定する方法
テンプレートとは、静的テキストファイルを動的に生成するために利用します。
テンプレートファイルはERBが利用されます。
Hello <%= @name %>.
↓ 置換イメージ
Hello XXX.
また、Role
やEnviroment
は下記を参考にさせていただきました。
https://qiita.com/kkojima0127/items/a96fe991b6630d4d277d
01. 事前準備
-
chefdk
をinstall済み - ローカル環境を汚したくない場合、docker等のVM内で実行すること
$ chef -v
ChefDK version: 4.13.3
Chef Infra Client version: 15.14.0
Chef InSpec version: 4.24.8
Test Kitchen version: 2.8.0
Foodcritic version: 16.3.0
Cookstyle version: 5.23.0
02. テンプレートのレシピを試す
作業用リポジトリを作成する。
$ chef generate repo chef-repo
Generating Chef Infra repo chef-repo
- Ensuring correct Chef Infra repo file content
Your new Chef Infra repo is ready! Type `cd chef-repo` to enter it.
$ tree chef-repo/
chef-repo/
|-- LICENSE
|-- README.md
|-- chefignore
|-- cookbooks
| |-- README.md
| `-- example
| |-- README.md
| |-- attributes
| | `-- default.rb
| |-- metadata.rb
| `-- recipes
| `-- default.rb
|-- data_bags
| |-- README.md
| `-- example
| `-- example_item.json
`-- policyfiles
`-- README.md
まずは/templates
ディレクトリを作成し、テンプレートを追加する。
chef generate template
コマンドを利用すれば、対象のcookbooksに簡単に追加できる。
$ chef generate template ./chef-repo/cookbooks/example hello
Recipe: code_generator::template
* directory[./chef-repo/cookbooks/example/templates] action create
- create new directory ./chef-repo/cookbooks/example/templates
* template[./chef-repo/cookbooks/example/templates/hello.erb] action create
- create new file ./chef-repo/cookbooks/example/templates/hello.erb
- update content in file ./chef-repo/cookbooks/example/templates/hello.erb from none to e3b0c4
(diff output suppressed by config)
# templateファイルが作成される
$ tree chef-repo/cookbooks/example/
chef-repo/cookbooks/example/
|-- README.md
|-- attributes
| `-- default.rb
|-- metadata.rb
|-- recipes
| `-- default.rb
`-- templates
`-- hello.erb
テンプレートファイルの中身を編集する。
今回は、name
変数を置換してファイル配置する感じになります。
Hello <%= @name %>.
テンプレート作成が完了したら、レシピに作ったテンプレートを適用するように記述を追加します。
template '/tmp/hello.txt' do
source 'hello.erb'
variables(
:name => 'UserA'
)
end
テンプレートレシピをローカルにデプロイする。
--local-mode
オプションを指定することで、Chef Infra Server
を介さず直接レシピをローカルに適応できます。
-o
オプションを指定することでrun-list
を上書きできる。
$ chef-client --local-mode -o "recipe[example::default]"
[2022-02-13T04:57:35+00:00] WARN: Original Run List: []
[2022-02-13T04:57:35+00:00] WARN: Overridden Run List: [recipe[example::default]]
resolving cookbooks for run list: ["example::default"]
Synchronizing Cookbooks:
- example (1.0.0)
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 1 resources
Recipe: example::default
* template[/tmp/hello.txt] action create
- create new file /tmp/hello.txt
- update content in file /tmp/hello.txt from none to 157fff
--- /tmp/hello.txt 2022-02-13 04:57:35.649783300 +0000
+++ /tmp/.chef-hello20220213-3298-1tkrpnp.txt 2022-02-13 04:57:35.649783300 +0000
@@ -1 +1,2 @@
+Hello UserA.
[2022-02-13T04:57:35+00:00] WARN: Skipping final node save because override_runlist was given
ファイルが作成されているかmore
コマンドで確認します。
テンプレート中の<%= @name %>
がUserA
に置換されてファイル作成できていることを確認できました!!
$ more /tmp/hello.txt
Hello UserA.
03. テンプレート変数をRoleで設定する
02
でテンプレートレシピを扱いましたが、変数の値をレシピに直書きしていました。
これでは、環境毎に設定値を変えて利用することが難しいです。
今回は、Role
毎に値を変更できるようにしてみます。
まず、Role
を作るためにknife
をローカルで動く設定を行います。
$ mkdir .chef
$ echo 'local_mode true' > .chef/knife.rb
次に、Role
を作成します。
今回はrole1
、role2
と作成し、attributes
のname
をRole別に変更しています。
$ EDITOR=vi knife role create role1
Created role[role1]
$ EDITOR=vi knife role create role2
Created role[role2]
# 変更点は★の箇所のみ
{
"name": "role{1|2}", // ★
"description": "",
"json_class": "Chef::Role",
"default_attributes": {
"example": {
"name": "role{1|2}" // ★
}
},
"override_attributes": {
},
"chef_type": "role",
"run_list": [
"example::default"
],
"env_run_lists": {
}
}
次に、02
で作ったレシピを変更します。
variables
に設定していた固定値を、attributes
から取得するようにします。
template '/tmp/hello.txt' do
source 'hello.erb'
variables(
:name => node["example"]["name"]
)
end
最後に、Role
の設定を元にテンプレートが変更できるか確認してみます。
role1
では、ファイルにHello role1.
が設定されていることが確認できます。
# node(ローカル端末)のrun_listにrole1を追加
$ knife node run_list add 0612a2a79715 "role[role1]"
0612a2a79715:
run_list: role[role1]
# 実行
$ chef-client --local-mode
Recipe: example::default
* template[/tmp/hello.txt] action create
- create new file /tmp/hello.txt
- update content in file /tmp/hello.txt from none to a5d764
--- /tmp/hello.txt 2022-02-13 06:48:48.729783300 +0000
+++ /tmp/.chef-hello20220213-3708-1trtj7q.txt 2022-02-13 06:48:48.729783300 +0000
@@ -1 +1,2 @@
+Hello role1.
# 確認
$ more /tmp/hello.txt
Hello role1.
続いて、Role2
も確認してみます。
role2
では、ファイルにHello role2.
が設定されていることが確認できます。
# role1を削除
$ knife node run_list remove 0612a2a79715 "role[role1]"
0612a2a79715:
run_list:
# role2を追加
$ knife node run_list add 0612a2a79715 "role[role2]"
0612a2a79715:
run_list: role[role2]
# 実行
$ chef-client --local-mode
Recipe: example::default
* template[/tmp/hello.txt] action create
- update content in file /tmp/hello.txt from a5d764 to 3b949b
--- /tmp/hello.txt 2022-02-13 06:48:48.729783300 +0000
+++ /tmp/.chef-hello20220213-3774-uzt0b8.txt 2022-02-13 06:52:23.899783300 +0000
@@ -1,2 +1,2 @@
-Hello role1.
+Hello role2.
# 確認
$ more /tmp/hello.txt
Hello role2.
04. テンプレート変数をEnvironmentsで設定する
03
ではRole
のattributes
を元にテンプレート変数の値を変更しました。
今回は、Environment
毎に値を変更できるようにしてみます。
まずはEnvironment
を作成します。
今回はdev
、stg
を作成し、attributes
のname
を環境毎に変更しています。
$ EDITOR=vi knife environment create dev
Created dev
$ EDITOR=vi knife environment create stg
Created stg
# 変更点は★の箇所のみ
{
"name": "{dev|stg}", // ★
"description": "",
"cookbook_versions": {
},
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {
"example": {
"name": "{dev|stg}" // ★
}
},
"override_attributes": {
}
}
次に、先ほど設定したRole
を削除し、Environment
をnodeに設定します。
$ knife node run_list remove 0612a2a79715 "role[role2]"
0612a2a79715:
run_list:
$ knife node environment set 0612a2a79715 "dev"
chef_environment: dev
最後に、Environment
の設定を元にテンプレートが変更できるか確認してみます。
dev
では、ファイルにHello dev.
が設定されていることが確認できます。
# 実行
$ chef-client --local-mode -o "recipe[example::default]"
Recipe: example::default
* template[/tmp/hello.txt] action create
- update content in file /tmp/hello.txt from 3b949b to 78e244
--- /tmp/hello.txt 2022-02-13 06:52:23.899783300 +0000
+++ /tmp/.chef-hello20220213-3860-hxp62w.txt 2022-02-13 07:23:26.119783300 +0000
@@ -1,2 +1,2 @@
-Hello role2.
+Hello dev.
# 確認
$ more /tmp/hello.txt
Hello dev.
続いて、stg
も確認してみます。
stg
では、ファイルにHello stg.
が設定されていることが確認できます。
# environmentをstgに変更
knife node environment set 0612a2a79715 "stg"
chef_environment: dev
# 実行
$ knife node environment set 0612a2a79715 "stg"
chef_environment: stg
$ chef-client --local-mode -o "recipe[example::default]"
Recipe: example::default
* template[/tmp/hello.txt] action create
- update content in file /tmp/hello.txt from 78e244 to e51b89
--- /tmp/hello.txt 2022-02-13 07:23:26.119783300 +0000
+++ /tmp/.chef-hello20220213-3926-1hkb2i7.txt 2022-02-13 07:25:50.449783300 +0000
@@ -1,2 +1,2 @@
-Hello dev.
+Hello stg.
$ more /tmp/hello.txt
Hello stg.
まとめ
chef
のtemplate
リソースを利用したファイル操作方法を学びました。
静的ファイルを動的に変更できるので、環境毎に設定値を変更する等で活用することができそうですね!