humangas's blog

自分の振り返りを適当に書いてます。書きっぷりはそん時の気分によって変わります。

入門Chef Solo:16-その他Resource

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

ここで取り扱うのはPackage、Service以外のResourceである。
※Windows関連Resourceについての記述は割愛されている。
※ この時点の解説で全体の8〜9割のやりたいことが満たせるはず。

cron

crontabコマンドを取り扱うResource
userを指定した場合、crontab -u [user]という形で実行される

action
:create
:delete

※chefでcronリソースを扱うメリット

冪等性が担保され、オペレーションで発生するcrontab -eで発生したオペミスやcrontab -rでcronを消してしまう事故が防げる。

[OPSCODE]cron

deploy

gitやsubversionなどのSCMからのデプロイが出来るResource

[OPSCODE]deploy
参考:chefのdeployリソースを使ってみる

file

対象ノード上のファイルの追加、削除、touch、権限の設定などが可能なResource

※ contentオプションを使用して任意の文字列を対象ファイルに書き込むことも可能
※ directory Resourceの場合はディレクトリを取り扱える。file Resourceとほぼ同様

action
:create
:create_if_missing
:delete
:touch

OPSCODE: file

http_request

指定したURLにhttpリクエストを飛ばせるResource

action
:get
:put
:post
:delete
:head
:options

OPSCODE: http_request

ifconfig

NICの設定変更、調整に使用できるResource

action
:add
:delete
:enable
:disable

OPSCODE: ifconfig

link

シンボリックリンク、ハードリンクを取り扱えるResource

action
:create
:delete

OPSCODE: link

mount

ファイルシステムの管理を出来るResource
fstabを調整してくれる

action
:mount
:umount
:remount
:enable
:disable

OPSCODE: mount

route

ルーティングテーブルの状態を管理できるResource

action
:add
:delete

OPSCODE: route

ruby_block

任意のrubyコードを読み込むためのResource
※ruby_blockは他のクックブック内のものと同じ名前にするとnot_ifやonly_ifの条件が同じ名前の違う定義のを見てしまうため注意が必要

action
:create

OPSCODE: ruby_block

入門Chef Solo:15-任意のシェルスクリプトを実行したい - Execute, Script

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

やりたいことがほかのResourceを使ってもなかなか実現できない場合にExecuteやScriptリソースを使う。

  • ExecuteやScriptは任意のコマンドやスクリプトを実行できる
  • ほとんど抽象化されておらず、冪等性も自分で担保する
  • Execute, Scriptともに任意のコマンドを実行するResource
  • bash, perl, rubyなど指定したインタプリタを使う場合はScriptを使う

Script(bash)

実行ユーザー

デフォルトではrootユーザー(正確にはchef soloを実行したユーザー)の権限で動く。

cwd

スクリプト実行時のcurrent working directoryを指定。

code

セットしたスクリプトを実行する。
ヒアドキュメントを用いて、レシピの中にシェルのコードを書ける。

creates

冪等性を保証するために使用するので重要。
createsは、このリソースで結果的に作成されるファイルを指定し、既にそのファイルが存在する場合にはコマンドを実行しない。

not_if, only_if

詳細な条件分岐を記述できる。

  • not_if: 指定した条件が真でないならコマンドを実行する。
  • only_if: 指定した条件が真のときのみコマンドを実行する。

条件として与えられた値によって、条件判定の仕様が異なる。

  • 文字列が与えられたとき:インタプリタ(例:bash)で実行してその終了ステータスを判定
  • Rubyのブロックが与えれたとき:与えられたコードブロックをrubyで解釈して真偽値で判定

処理の実行に使われるユーザーやディレクトリ、環境変数を指定できる。
例)

not_if <<-EOC, :user => 'vagrant', :environment => {'HOME' => '/home/vagrant'}
    ...
EOC

not_ifonly_ifはどのResourceでも記述できるが、よく使うのはScript Resource

EC2のマイクロインスタンスにスワップファイルを作る例

EC2のマイクロインスタンスは、インスタンス起動直後にはスワップ領域が設定されていない。そのためスワップを使うにはスワップイメージを作ってスワップを有効化する。

コード:よく使いそうだからコピペできるように書いときます

bash 'create swapfile' do
    code <<-EOC
        dd if=/dev/zero of=/swap.img bs=1M count=2048 &&
        chmod 600 /swap.img
        mkswap /swap.img
    EOC
    only_if { not node[:ec2].nil? and node[:ec2][:instance_type] == 't1.micro' }
    creates "/swap.img"
end

mount '/dev/null' do # swap file entry for fstab
    action :enable # cannot mount; only add to fstab
    device '/swap.img'
    fstype 'swap'
    only_if { not node[:ec2].nil? and node[:ec2][:instance_type] == 't1.micro' }
end

bash 'activate swap' do
    code 'swapon -ae'
    only_if "test `cat /proc/swaps | wc -l` -eq 1"
end

参考: 『EC2にSWAP領域を作成』suz-lab

入門Chef Solo:14-gitレポジトリからファイルを取ってくる - Git

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

Package Resourceを使うほかにgithubからファイルを取ってきて利用する場合にGit Resouceを使う。

Git

サンプルコード:gitからファイルを取得して設置

git "/home/vagrant/.oh-my-zsh" do
    repository "git://github.com/robbyrussell/oh-my-zsh.git"
    reference "master"
    action :checkout
    user "fiorung"
    group "xenoblade"
end

/home/vagrant/.oh-my-zsh ディレクトリに、リモートのgitレポジトリから取得してきたファイルが置かれる

action

  • :checkout 実際にチェックアウトしてファイルを取得するのは初回のみ
  • :sync 毎回必要に応じてレポジトリを更新したい場合

gitでとってきてインストールする

gitでファイルを取得して、取得した中に含まれるインストールスクリプトをキックする。インストールスクリプトの実行にbash Resourceを使用できる。

入門Chef Solo:13-ユーザーを作成したい - User, Gorup

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

  • ユーザーの管理:User Resource
  • グループの管理:Group Resource

User

サンプルコード(ユーザー作成)

user "fiorung" do
    comment "fiorung"
    home "/home/fiorung"
    shell "/bin/bash"
    password nil
    supports :manage_home => true
end

↑本文には書いてないがaction :createがデフォルト値

action

  • :create
  • :remove
  • :modify ユーザーが存在しないとエラー
  • :manage ユーザーが存在しなくてもエラーにならない

supports

  • supports :manage_home => true
  • → ユーザーを新規作成したときにホームディレクトリを一緒に作る
  • supports :non_unique => ture
  • → 新規ユーザーを作成したときにノンユニークIDが振られても構わない

Group

サンプルコード(グループ作成)

group "xenoblade" do
    gid 999
    members ['fiorung', 'dunban']
    action :create
end

サンプルコード(グループにユーザーを追加)

group "xenoblade" do
    action :modify
    members [ 'shulk' ]
    append true
end

入門Chef Solo:12-ファイルやディレクトリを扱いたい - Cookbook File, Directory

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

Cookbook File

Cookbook Fileを使用して、クックブックに同梱したファイルを転送し任意のパスへ配置できる。
標準リソースのFileリソースはファイルを一から作成する場合のResourceで、利用頻度は低い。

Templateとの使い分け

  • Template: 変数を使う場合
  • Cookbook File: 静的なファイルを扱う場合

サンプルコード

cookbook_file "/tmp/supervisor-3.0a12-2.el6.noarch.rpm" do
    mode 00644
end

転送元:files/default/supervisor-3.0a12-2.el6.noarch.rpm

オプション

下記のようなオプションがある(一部)

  • mode
  • owner
  • group
  • path
  • source
  • checksum

checksum

SHA-256のチェックサム

チェックサム生成のコマンド

$ shasum -a 256 <filename>

Directory

ディレクトリ操作を行う。
TemplateやCookbook Fileで扱うファイルを転送先となるディレクトリは、明示的に作成しておく必要がある。そこでDirectory Resourceを使用する。

ディレクトリ作成のサンプルコード

directory '/etc/td-agent/' do
    owner   'td-agent'
    group   'td-agent'
    mode    '0755'
    action  :create
end

action

アクションは:createもしくは:delete

パッケージをファイルからインストール

  • yumを使わずにrpmパッケージをインストールするときに、Cookbook FileとPackageを組み合わせてインストールのレシピを作ることができる
  • rpmをファイルでインストールする場合、そのrpmが依存するパッケージをChefが解決する
  • Redhat系ならyumレポジトリから取ってきてインストールしてくれる

入門Chef Solo:11-テンプレートから設定ファイルを配置したい - Template

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

Template

テンプレートを使ったレシピの例:

template "nginx.conf" do
 path "/etc/nginx/nginx.conf"
 source "nginx.conf.erb"
 owner "root"
 group "root"
 mode 0644
end

使用されるテンプレート

templates/default/nginx.conf.erb

  • defaultのものを使う場合はsourceを省略してもよい
  • templateにフルパスを指定する場合はpathを省略してもよい

テンプレート内ではAttributeが使える

テンプレートに記述する変数

  • JSONファイルで指定
  • Ohaiで取得

JSONファイルで指定

JSONファイル

{
 "nginx": {
 "port" : 80
 },
 "run_list":[
 "nginx"
 ]
}

テンプレートには次のようにキーと文字列を指定して記述する。

<%= node['nginx']['port'] %>

Ohaiで取得

Ohaiで取得する場合は、テンプレートには次のようにシンボルを指定して記述する。

<%= node[:platform] %>

テンプレートはまるっと既存のをもってくるところから始める

Chefのレシピを書き始めた段階では、設定ファイル系のテンプレートは既存のものあるいはパッケージを入れたときのデフォルトのものをそのままコピーして使い始めるのが定石。その後、各種設定を煮詰めながら徐々に配布しやすい形態に変えていく。

入門Chef Solo:10-サービスを起動したい - Service と Notification

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

  • Package Resourceはインストールのみで、サービスの起動やOS起動時の登録は行われない
  • サービスの状態はService Resourceで記述する
  • Notification(通知)とServiceのResourceを組み合わせると、設定ファイルを更新したらreloadやrestartすることを実現できる

Service

action

RedHat系では/etc/init.d 以下のスクリプトが実行される。

:enable

OSブート時のサービス有効

:start

サービス起動(レシピ実行時)

supports

serviceで使用できるオプションの指定

restart => trueを指定しない場合、stop + start で代用される。 サービスによっては、stop + start のほかにもrestartで処理することがあるので、restartをサポートしているサービスではなるべくrestartを有効にする。

Notification と Service の組み合わせ

nginx.confが更新された場合にnginxサービスをreloadする例)

service "nginx" do
    supports :status => true, :restart => true, :reload => true
    action [ :enable, :start ]
end

template "nginx.conf" do
    path "/etc/nginx/nginx.conf"
    source "nginx.conf.erb"
    owner "root"
    group "root"
    mode 0644
    notifies :reload, 'service[nginx]'
end
  • notifiesは第一引数にアクション、第二引数にresource_type[resource_name]を記述する
  • resource_typeservicetemplateなどResourceの種類
  • resource_nameは自分でレシピ内に指定したResourceの名前
  • notifiesで指定できる通知先はserviceに限らないが、serviceがよく使われる

Notification のタイミング

デフォルトではNotificationの実行は遅延して行われる。いったんキューに入れられて、Chef全体の実行の限りなく終盤でキューから出されるので、通知を送る側はあまり順番を気にしなくてよい。キューに入れずに即時実行する場合はnotifiesの第三引数に:immediatelyを指定するが利用場面は少ない。

Subscribe - Notification の逆方向の通知

  • SubscribeはResourceに何かアクションをさせたいときに使う
  • Subscribeで実現できる動作はNotificationと全く同じで、通知の向きのみが異なる
  • Notification と Subscribe は記述するときに可読性の高い方を選択する

入門Chef Solo:09-パッケージをインストールする - Package

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

Package Resourceが最もよく使うResource

本章では使い方の例を見ていく

Package

インストール

package "nginx" do
    action :install
end

複数インストール

%w{gcc make nginx mysql}.each do |pkg|
    package pkg do
        action :install
    end
end

バージョン指定

package "perl" do
    action :install
    version "5.10.1"
end

action

  • install
  • upgrade
  • remove

指定したファイルからインストール

package "tar" do
    action :install
    source "/tmp/tar-1.16.1-1.rpm"
    provider Chef::Provider::Package::Rpm
end

gem_package

Package Resourceのサブリソースのgem_packageを使うとrubygemsのgemを扱うことができる

gem_package "rake" do
    action :install
end

gemのインストールパスを指定する

gem_package 'fluent-plugin-extract_query_params' do
    gem_binary "/usr/lib64/fluent/ruby/bin/fluent-gem"
    version '0.0.2'
    action :upgrade
end

入門Chef Solo:08-代表的なレシピのサンプルが見たい - td-agentのレシピを読む

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

目的:レシピを記述するためにResourceの詳細を見ていく前に、overviewする。

サンプルに使用するtd-agent:

td-agentのレシピを見てみよう

レシピでやっていること:

  • td-agentグループを作る
  • td-agentユーザーを作る
  • /etc/td-agent/ ディレクトリを作る
  • td-agent配布用のサイトをaptソースもしくはyumリポジトリに追加する
  • td-agentの設定ファイルをテンプレートから作成して設置する
  • td-agentパッケージをインストールする
  • td-agentサービスを有効にする

ポイント

一般的なRPMやdebパッケージは、ユーザー作成そのほかを実行してくれる。このレシピは「シンタックスの参考」としてレビューする。

グループを作る、ユーザーを作る、ディレクトリを作る

ポイント

Chefのレシピは上から順に逐次実行されていくので、先に定義した処理は既に実行されている前提でレシピを書いていく。

パッケージの配布サイトを登録する

レシピで対応させるプラットフォームごとに、パッケージの取得先をcaseを使って分岐する。
Resouceとしてapt_repositoryyum_repositoryが用意されているので、プラットフォームによって使い分ける。

AttributeとOhai

Ohaiを使ってAttributeに設定された値を取り出す。
Chefで使用する場合はnode[:platform]などと書いて取得する。

テンプレートから設定ファイルを作る

3章の入門Chef Solo:03-nginxをChef Soloで立ち上げたいを参照する。

パッケージtd-agentをインストール

Package Resourceを使ってインストールする。該当プラットフォームのパッケージシステムを自動的に調べて実行してくれる。aptかyum。
actioninstallではなくupgradeを指定すると、レシピ実行時に最新版にアップデートされる。

サービスを起動する

:enableはOS起動時のサービスとして登録
:startはすぐにサービスを起動

subscribes :restart, resources(:template => "/etc/td-agent/td-agent.conf")はテンプレートファイルが更新されていたら:restartアクションを実行する記述。

オフィシャルドキュメントを参照しよう

公式のResourceのドキュメント
About Resources and Providers - Chef Docs

なんで"Resource"?

レシピに書くのは、それを実行した結果のリソースの状態であるから。
「Chefはサーバーの状態を管理し収束させるためのフレームワークである」

Chefの思想

What Is Chef?

入門Chef Solo:07-サードパーティのChefクックブックを使いたい

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

Opsccode Community

ココにサードパーティChefクックブックが集積されている。knifeコマンドを使って公開されているクックブックを簡単にインポートできる。

事前の設定

Opscode Communityにユーザー登録する

Opscode CommunityのサイトからSign Upを行う

秘密鍵を取得する

ユーザー設定画面から"Get a new private key"を選択して秘密鍵をダウンロードする。

  • ダウンロードした秘密鍵の保存場所(例):~/.chef/[username].pem
  • パーミッション:600

knifeの設定

~/.chef/knife.rb

client_key
'/Users/[username]/.chef/[username].pem'
cookbook_path [ './cookbooks' ]

例:yumのEPELをyumクックブックで有効にする

OpsCode Communityのクックブックはknifeコマンドで取得する。

前提:

  • Chefレポジトリがgitで管理されていること
  • ワーキングディレクトリがクリーンな状態(コミットしていない変更がない状態)であること

Chefレポジトリの準備

$ cd chef-repo
$ git init
$ git add .
$ git commit -m `blah blah`

knifeでyumクックブックを取得する

次のコマンドでcookbooksディレクトリ以下にyumクックブックをダウンロードし、git addからgit commitまで自動実行する。

$ knife cookbook site vendor yum

クックブックを実行する

JSONファイルのrun_listに"yum::epel"を設定してChef Soloを実行する。

JSONファイル:

{
    "run_list":[
        "yum::epel"
    ]
}

実行結果の確認

$ vagrant ssh
$ yum repolist
...
epel Extra Packages for Enterprise Linux
8,425

自分で書くかサードパーティのものを使うか

  • ポリシー次第
  • 理想的な動作が保証されているわけではない
  • 十分に利用できるレベルにある
  • 汎用性をあげるためにしっかりと書かれているものが多い
  • 利用範囲を限定して自分で書いた方がわかりやすい
  • 筆者はサードパーティをほとんど使っていない

考察:

  • プライベートや開発でちょっと使いたいときはサードパーティも楽でよさそう
  • エンタープライズの仕事をするときは自分で書いた方がよさそう
  • 自分で書くときに参考のために読むのはよさそう