Tech Sketch Bucket of Technical Chips by TIS Inc.

【Chef】Custom LWRPsで独自のResourceを作る方法

Pocket

3/4(火)、3/5(水)にChefエンジニア養成特別講座が開催され、参加して来ました。その中の一つにLWRPsを使って独自のResourceを定義する方法について解説があったので、Rubyのバージョン管理ツールであるrbenvのリソースを作ってみたいと思います。
なお、Chefについては過去の記事 Chef の勉強会をやってみた を参照して下さい。


Custom LWRPsとは

Chefでは定義されているResourceをrecipe内で使うことでサーバの構成管理を行います。例えば、新規にファイル作成する場合などは下記のようにfile Resourceを使ってrecipeを実装します。

既存のResourceのみでもrecipeを実装することは出来ます。しかし、既存のResourceのみではrecipeの内容が膨大になってしまったり、recipe内にRubyのロジックを書く必要が出てくる場合があるかと思います。そんな時にCustom LWRPs[※1]を使えばChefで定義されているpackage, fileなどのResource定義以外で独自にResourceを定義することが出来るので、まとまった処理やRubyのロジックを別Resourceとして定義することが出来ます。
なお、LWPRsはLightWeight Resources/Providersの略です。

LWRPsの構成要素

LWRPsはResourceとProviderの2つのコンポーネントで構成されています。

  • Resource

上記に記載したようにrecipe内で使用するResourceを定義します。Resourceは3種類のDSLを用いて実装します。

actions Resourceで使用可能なactionを定義します。定義されたactionはrecipe内で指定することが出来ます。上記のfile Resourceを用いた例では action :create 部分が該当します。
default_action recipe内でactionが指定されなかった場合に実行するデフォルトのactionを指定出来ます。
attribute recipeで指定することが出来る独自のパラメータを定義出来ます。上記のfile Resourceの例では owner, group, mode が該当します。

  • Provider

ProviderではResourceで定義したactionの処理内容を実装します。上記file Resourceの例では実際にファイルを作成する処理の内容がProvider内に定義されます。

Custom LWRPsを作ってみる

新規にResourceとProviderを定義して独自のResourceを作ってみたいと思います。

今回の例で作るLWRPs

今回はRubyのバージョン管理をする際に使用するrbenv[※2][※3]のResourceを下記内容で新しく作ってみます。
なお、今回はサンプルとして作成するので、マルチプラットフォーム対応や冪等性の考慮などは省略しています。

  • 対象OSはCentOSとします。(今回のサンプルではマルチプラットフォームは考慮しません)
  • cookbook名は rbenv で リソース名は sample とします。
  • 定義するactionは install, switch_version の2つとします。
    • install: rbenvをインストールした後にパラメータで指定されたバージョンのrubyをrbenvを使ってインストールします。
    • switch_version: 指定されたバージョンのrubyに変更します。rbenvでインストールをしていないバージョンが指定された場合は何も実行しないこととします。
  • attributeはインストールするrubyのバージョンを必須パラメータとして指定します。(rbenv install -lで取得出来るバージョン)
  • rbenv cookbookのディレクトリ構成は以下のようになります。

Resource定義

上記に記載した条件でResource定義を作成します。

1行目で使用可能なactionの一覧を定義しています。
2行目でrecipe内でaction指定がない場合にはinstallを実行するようにデフォルトactionを定義しています。
3行目でrbenvを使ってインストールするRubyのversionをString型で必須なパラメータとして定義しています。
4行目でrbenvをインストールするディレクトリを定義しています。実行時にinstall_dirを指定しなかった場合は/usr/localにrbenvをインストールするようにデフォルト値を定義しています。

今回作成するサンプルのResource定義はこれだけです。attributeではその他にもパラメータを使うことが出来ます。詳細については[※1]の公式ドキュメントを参照して下さい。

Provider定義

Resourceで定義したactionのinstallとswitch_versionの内容を実装します。処理の内容は[※3]を参考にしてrbenvをインストールするコマンドを順番に投入しています。なお、前述した通りサンプルなので、マルチプラットフォーム対応や冪等性の考慮などは省略しています。

recipe

今回新規に作成したrbenvのResourceを使うrecipeを作ります。recipe内でCustom LWRPsを使う場合にはcookbook名_Resourceファイル名をResource名として使います。今回の場合は rbenv_sample がResource名となります。

  • rubyの2.0.0-p0をインストールする場合

  • rubyの2.0.0-p451をインストールする場合

  • インストール済みのruby 2.0.0-p0に再び切り替える場合

まとめ

本記事ではChefのCustom LWRPsの使い方を簡単にまとめました。Chefのrecipeを作る際にrecipe内にRubyで複雑なロジックを書いてしまったり、1ファイルのrecipeの内容が膨大になってしまった場合などがあるかと思います。そのような場合にはCustom LWRPsを使ってRubyのロジックやまとまった処理を外だししてrecipeの見通しをよくするようなリファクタリングを実施すれば、recipeのメンテナンス性を向上させることが期待出来そうです。
Chefを使っているけど、独自のリソースを定義するのはハードルが高いと感じている方は、思っているより簡単にCustom LWRPsを実装することが出来るので、一度使ってみては如何でしょうか。


※1: LWRPsの詳細については Chefの公式ドキュメント を参照して下さい。
※2: https://github.com/sstephenson/rbenv
※3: rbenvのインストールはQiitaの記事を参考にしています。 http://qiita.com/inouet/items/478f4228dbbcd442bfe8

エンジニア採用中!私たちと一緒に働いてみませんか?