ChefはRubyでできている

 ChefはRubyでできている

ながのRubyの会#1向け発表 2017/12/2

9cbe7ff6cb7a183264754bb5e76d84d9?s=128

Kazuya Taniguchi

December 02, 2017
Tweet

Transcript

  1. 2.

    自己紹介  谷口 和哉  長野市在住  自他ともに認める非プログラマ  RubyはSilver認定(を持ってるだけ)

     開発は管理しかさせてもらえない  元々インフラ系→セキュリティ系を経て、結局何でも屋さんに落ち着いた  @tmtmsさんの前の席に座ってます  最近はPython勉強中(しろめ)  趣味:Ingress
  2. 3.
  3. 5.

    Chefの記述はRubyの内部DSL  Ruby言語を「ベースにした」記述ができる  リテラル、配列変数、ハッシュ、正規表現、基本的な制御構文(if、case)  特に%w(空白ベースの配列)は大変お世話になる(複数リソースに対して処 理をする時など) %w{ aaaa

    bbbb cccc }.each do |pkg| package pkg do action :install end end  ただし100%ではない(むしろ使えないものの方が多い)  詳細は「Chef Style Guide」を参照 https://docs.chef.io/ruby.html
  4. 6.

    素のRubyを記述するなら  ruby_blockというリソースがあり、その中であれば自由にRubyで記述で きる ruby_block “リソース名” do block do (Rubyのコードをそのまま書ける)

    end action :run end  ただしbashリソースと同じ扱いで、その中の冪等性は担保されないので、 そこは自分でなんとかすること  私はつい、bashリソースに走ってしまう(スマン!)
  5. 7.

    Puppetってありますよね  Chefと同様Rubyで記述されたツール  こっちは外部DSLなので、内部の構文はRubyっぽくない  (おなじみngnixのインストール) package { “ngnix”:

    ensure => “installed” } 先ほどの例(複数のパッケージをインストールする)をPuppetで実施する なら、 package { ensure => “installed” } $pkg = [ aaaa bbbb cccc ] package { $pkg } となる。
  6. 8.

    よく使うリソースTOP5 1. cookbook_file / template 2. directory 3. package 4.

    bash / execute 5. service 過去、作成したrecipeからざっくり抽出 上位5つでrecipe全体の8割をカバー
  7. 9.

    cookbook_file  Cookbookにあるファイルをサーバに転送する  設定ファイルの配置、インストーラの転送等に大 活躍  配備するファイルの内容を動的に調整するなら template cookbook_file

    “/etc/hosts” do owner ‘root’ group ‘root’ mode ‘0755’ action :create not_if { File.exist?(“/etc/hosts”) } end 所有者とモードの設定は必ずして おく 「無い場合だけ作成」という create_if_missingというのもあ るが、あまり使わない 例では/etc/hostsが既にあったら 実施しない(not_if制御)としている が「状態を管理」するならば本来は 毎回上書きで良いはず(そうしないと 意図した状態に収束しない) Cookbookのfiles/default/hosts が自動的に選ばれる
  8. 10.

    template  収束の段階で設定ファイルに動的な値を埋め込みたい  RubyのERBによるテンプレートを使う  例: hosts → hosts.erb(cookbookのtemplates/にあるファイルを優先的に、

    拡張子.erbを抜いて検索してくれる)  置き換えたいところを<%= @(変数) %>とする  templateリソースで、変数化した部分をattributeに結びつける template “/etc/hosts” do owner ‘root’ group ‘root’ mode ‘0755’ variables( :localip => node[‘server’][‘ipaddress’] ) end  attributeとは ( ゚д゚ )クワッ!! 127.0.0.1 localhost.localdomain <%= @localip %> hoge.fuga.com hosts.erbの例
  9. 11.

    attribute(templateの続き)  Recipeが使用する変数等の値を、Recipe外から取得する仕組み  Recipeの汎用化には必須  node[‘aaa’][‘bbb’]の形式で指定  Ohai(Chefが使用しているOS/HW情報取得ツール)もこのI/F 

    初期値はCookbookのattributes/default.rbに記載しておける default[‘server’][‘ipaddress’] = ‘192.168.1.1’  適用するサーバ単位で、個別情報を設定することができる “server”: { “ipaddress: “192.168.100.100” } Template hosts.erb Node 情報 hosts 個別node default 指定があれば なければ
  10. 12.

    service  サービス(/etc/init.dに設定されているもの)の状態を定義する  enable / disable → chkconfigやsystemctl上のOn /

    Off  start / stop → サービス自体の動作 service “ntpd” do supports :restart => true, :status => false action [ :enable, :start ] end  Recipeをまたぐと、serviceリソースを認識できない場合があるので、service の定義と、notifies等で行うrestartアクションは同じrecipe内がベター  大抵が「enable, start」だが、逆に動いていては困るサービスを止めるため にも使う そのサービス(rcスクリプト)が使える命 令を定義できる
  11. 13.

    package  定番過ぎるので、Tips的な例を…  Packageリソース自体は複数の◦◦_packageの親玉的存在  OSによって、実体がrpm_packageだったりapt_packageだったり  直接◦◦_packageを指定することも可 

    Rubygemsのパッケージを入れる「gem_package」は、そのままだとOSに 入っているRubyのGemを操作するが、「Chef自体」に包含されているRubyの Gemを操作する場合は、「chef_gem」を使用する  例: Workstationのknifeにknife-soloを追加する  外部リポジトリではなく、ローカルにあるファイルからインストールしたい場 合は、「source」を指定する。その場合、cookbook_fileリソースであらかじめ コピーすることを忘れずに  大抵が、action:installだが、入っていると衝突するため外しておきたいパッ ケージをaction: uninstallで外すのにも使う  例: OSに最初から入っているmysql-server
  12. 14.

    directory  配備の下準備として、意外に使うことが多い  数えてみたら上位に来た directory “/var/local/hoge” do owner ‘root’

    group ‘root’ mode ‘0755’ recursive true action :create end  再帰的に作成する場合は、recursive trueを指定する  同じRecipeの中で作成→使用(中にファイルを入れるとか)をするのは(順序性の問題で) 基本避ける  なんとなくよろしくやってくれる感じではあるのですが…  どうしても必要であれば、別のrecipeにする(run_listには順序性があるため)
  13. 15.

    bash / execute  なんでもできる。ヤバい  よく知られている通り、冪等性が担保されないので、何度実行しても同じ結果になるよう、 recipe作成者が配慮しないといけない  手っ取り早いのは、not_if制約

     not_if “コマンド実行” → trueの場合、実行しない(grep等で使用)  not_if { File.exists?(ファイルのPath) } → ファイルがあったら実行しない  not_if { Dir.exist?(ディレクトリのPath) } → Dirがあったら実行しない  逆の「only_if」というのもある(個人的にはあまり使わない)  Shellの本文に、recipe内のRuby変数を入れ込めるので便利 dir = “/tmp/testdir” bash “hogehoge” do user ‘root’ cwd ‘/tmp’ code <<-EOS mkdir #{dir} EOS end bashリソースの外部にある変数を参 照
  14. 16.

    ところで、Itamaeってあり(ry  Rubyとほぼ同じ構文で記述できる互換ツール  国内開発(CookPadのエンジニアの方が開発した)  Rubyとの違いは・・・  エージェントレスである 

    使えるリソースが限定されてる  directory / execute / file / gem_package / git / group / http_request / link / local_ruby_block / package / remote_directory / remote_file / service / template / user  本家ChefにあるWindows系のリソースは いさぎよくカット  ぶっちゃけ ほぼ網羅してるといえる  ただし同じリソースでもChefとは微妙に挙動が異なったりする  あまりあれこれ求めない場合は有力な選択肢  個人的には「Chefとの微妙な差異」を追いかけるのが大変なので、もっぱら普通 のChefを使っている