Chefを学ぶのが面倒な人のInfrastructure as Code with JSON
最近、いかにChefの学習コストを小さくしつつ、組織にインフラのコード化(Infrastructure as Code)を導入するか、について悶々と考えていたので、まとめてみた。
Chefの辛み
インフラのコード化をするにあたって、Chefは最初に覚えることが多くてなかなか辛い、という話をよく耳にする。Chefの動作概念、Chefの各種リソースの使い方、Chefの周辺ツール群の使い方、Cookbookのコーディング規約など、Chefを使い始めるために覚えるべき内容は結構多い。組織が大きくなればなるほど学習コストはバカにならないし、インフラエンジニアに日常的にコードを書いてもらうことはなかなか難しい。そんな環境でInfrastructure as Codeを広めようとしても、現実的になかなかうまくいかない。インフラをコード化して業務改善がしたいのに、いつの間にかみんなにChefを広めることが目的になり、疲弊したりする。
Infrastructure as Code with JSON
そんな中、DevOpsの流れとは逆行するが、みんなみんながみんなChefのことわかってCookbookが書ける必要はないんじゃないかとふと思った。大規模な組織では業務内容が細分化されているし、Cookbookの作成は得意な人に任せて、最低限必要な変数(attribute)をJSON ファイルで定義してchefを実行する方法だけ学べばいいのではないかと。まさにInfrastructure as Code with ChefならぬInfrastructure as Code with JSON。JSON を書いてインフラを管理する。Cookbookに比べてある程度柔軟性は無くなるが、最低限の学習コストでChefを導入することができ、業務の自動化ができそう。そうすれば、少しでも手作業による運用、筋肉運用を減らすことができるんじゃないだろうか。
インフラのコード化を進めていく段階を分類するとだいたいこんな感じになる。
理想は3の人が当たり前にいることだが、いきなり1から3にいける人はそこまで多くないと思うし、まずは1から2に持っていくのが改善効果が期待できるし大事だと思う。
Cookbookを書かずにCookbookを使う
Cookbookを使うだけであれば、Berkshelfの使い方と、attributeとrun_listを学ぶだけだ。作業としてはBerkshelf を使ってcookbookをRubyのBundlerのようにgemを手元に取ってきて、Cookbookの実行に必要なattributeとrun_listをNodeのJSON ファイルに定義してChefを実行する。Chefを実行するだけならChefのCookbookを書く必要はない。以下、使い方を紹介したい。なお、紹介のなかで使うNodeのJSONファイルなどはGithubに置いておいた。
1. BerkshelfでCookbooksを取得する
まず、使いたいCookbookを選ぶ。ChefコミュニティのCookbookを使ってもいいし、社内で使ってるCookbookでもいい。Cookbookの取得元は以下の通り。
- コミュニティCookbook置き場 - Supermarket
- 社内のCookbook置き場 - Private supermarketかBerkshelf APIのエンドポイント
timezone-ii
Cookbookを使う場合のBerksfile
はこんな感じ。
source "https://supermarket.chef.io" cookbook "timezone-ii"
社内のCookbookを使う場合は、sourceに社内のエンドポイントを指定する。
source "https://shanai.example.com/" cookbook "hogehoge" cookbook "fugafuga" cookbook "piyopiyo"
Berksfile
を作ったらberks
コマンドでcookbookをローカルに取ってくる。まるでRubyのBundlerのように。以下の例では取得先をcookbooksディレクトリにしている。
$ berks vendor cookbooks Resolving cookbook dependencies... Fetching cookbook index from https://supermarket.chef.io... Using timezone-ii (0.2.0) Vendoring timezone-ii (0.2.0) to cookbooks/timezone-ii $ tree -L 2 . ├── Berksfile ├── Berksfile.lock └── cookbooks └── timezone-ii
2. NodeのJSONファイルを定義する
次にChefを実行するために必要なNodeのJSONファイルを作成する。Nodeの設定に必要な可変値(attribute)や、どのrecipeを実行するか(run_list)などを記載する。その際、きちんと使いたいCookbookのドキュメントを読んで、使えるAttributeやrecipeを確認する。
timezone-ii
のcookbookを実行する例だと以下のようになる。
{ "name": "my_node", "tz": "Asia/Tokyo", "run_list": [ "recipe[timezone-ii]" ] }
nodes
ディレクトリを掘ってそこにJSONファイルをおく。
$ tree -L 2 . ├── Berksfile ├── Berksfile.lock ├── cookbooks │ └── timezone-ii └── nodes └── my_node.json
3. Chefを実行する
あとはChefを実行するだけ。Chefの実行はchef-solo、chef-client、knife-soloなど、いろんな方法があるが、ここではVagrantで作ったVM上で、chef-clientのlocalモードを実行する例を示す。
まず、以下のようなchefを実行するのに必要な設定ファイルclient.rb
を用意する。
cookbook_path '/vagrant/cookbooks'
ちなみに、社内環境とかProxy配下の環境で試す場合は以下のようなファイルになる。chef-zeroでproxyを使う場合はno_proxy
にlocalhostを入れることがポイント。
http_proxy 'http://proxy.example.coml:1234' no_proxy 'localhost' cookbook_path '/vagrant/cookbooks'
$ vagrant box add tkak/centos-6.6-x86_64-chef-dk $ vagrant init tkak/centos-6.6-x86_64-chef-dk $ vagrant up $ vagrant ssh [vagrant@localhost ~]$ date Sun Apr 5 04:19:24 UTC 2015 [vagrant@localhost ~]$ sudo chef-client -z -j /vagrant/nodes/my_node.json -c /vagrant/conf/client.rb Starting Chef Client, version 12.0.3 resolving cookbooks for run list: ["timezone-ii"] Synchronizing Cookbooks: - timezone-ii Compiling Cookbooks... Converging 4 resources Recipe: timezone-ii::default * yum_package[tzdata] action install (up to date) * log[Linux platform 'centos' is unknown to this recipe; using generic Linux method] action write (skipped due to not_if) Recipe: timezone-ii::linux-generic * ruby_block[confirm timezone] action run - execute the ruby block confirm timezone * file[/etc/localtime] action create - update content in file /etc/localtime from ab1ddb to 0bc4b3 (current file is binary, diff output suppressed) - restore selinux security context Running handlers: Running handlers complete Chef Client finished, 2/3 resources updated in 10.584156048 seconds [vagrant@localhost ~]$ date Sun Apr 5 13:21:12 JST 2015 [vagrant@localhost ~]$
まとめ
ChefのCookbookを書かずにJSONとBerkshelf だけでChefを実行する方法について書いた。もちろんChefをきちんと理解してCookbookが書ける方が望ましいが、Infrastructure as Codeに馴染みがない人やこれから学びたいという人は、とりあえずChefのcookbook使ってみるところからはじめるのがいいと思う。大事なのはChefを使うことではなく業務を改善することなので、まずはCookbookを使ってみて少しでも手作業をなくすことが大切だと思う。