Chefで複数リソースに更新があった時だけbashを実行
はじめに
cookbookのfilesの中に大量のtomlファイルが入っていて、各tomlファイルに対してコマンドを実行したい場面に直面しました。 ファイルの更新が合った時だけ、そのコマンドを実行したかったので、その時の作業をメモします。
目的
- confファイルが更新されているかをチェック
- 更新されていればファイルを差し替えしてスクリプトを実行
作業
作業環境は、仮想マシンにChef-ServerとChef-Clientを用意し、作業(knifeを実行するマシン)はホストマシンになります。 下記、レシピになります。
recipe.rb
files = run_context.cookbook_collection["my-cookbook-name"].file_filenames files.select!{ |file| file =~ /\.toml/ } files.each do |file| # 2. 配置したtomlを使ってコマンドを実行 bash "exec-#{File.basename(file,".*")}" do action :nothing # 実行しない user "vagrant" cwd "/home/vagrant/conf" code "echo #{File.basename(file,".*")} >> /home/vagrant/exec-stamp.txt" # 処理したいコマンド end end files.each do |file| # 1. tomlを配置 cookbook_file "/home/vagrant/conf/#{File.basename(file)}" do owner "vagrant" group "vagrant" mode 0644 source File.basename file not_if { FileUtils.cmp("/home/vagrant/conf/#{File.basename(file)}", file) } # ファイルの比較 notifies :run, "bash[exec-#{File.basename(file,".*")}]" # bash[exec-hoge] の内容を実行しにいく end end
さいごに
filesの中の一覧を取得する方法を見つけるのに時間がかかってしまった。取得方法は、run_context.cookbook_collection["cookbookの名前"]で、/var/chef/以下に保存されているファイルの絶対パスが配列で返って来ます。