chef が便利すぎて泣けてきてる今日この頃なところで、「アレはどうするんだろう」「コレはどうやって実現するんだろう」
→ 公開されているレシピ使えよ( ゚д゚ )クワッ!!
という軟弱な思考に頼らず、自ら作ったレシピでどうこうしたい同輩は多いかと思われます。
皆さんの役に立つようにというよりも、もはや自分の備忘録としか思えないような話ではありますが、chef で特定の chefを「一度だけ」実行できるようにするには、どう組み合わせたら良いかなーについて、一時的に結論が出たので、ご紹介します。
後でご説明しますが、この方法にも難があるので、他に良い方法があれば教えてください。
[amazonjs asin=”B00BSPH158″ locale=”JP” tmpl=”Small” title=”入門Chef Solo – Infrastructure as Code”]
目次
templateを使ってみよう
sqlを記述した中間ファイルを使って、変更が発生した場合の再実行、一度実行された後の再実行の抑制ができそうです。
今回は PostgreSQL
で、ユーザのパスワードを変更する SQLで試してみます。
templateを準備する
まず、template ファイルを準備しましょう。
-cookbooks/pgsql/templates/default/pg_chpasswd.sql.erb ALTER USER <%= @pg_user %> WITH PASSWORD '<%= @pg_password %>';
一旦こんな感じで。好みに応じて、Encrypted
などつけてたもうれ。
recipeを準備する
次に、これにあわせて recipe
を書いてみましょう。
まず、sql を実行するための execute
パートを作りましょう
-cookbooks/pgsql/recipes/default.rb execute "pgsql-chpasswd" do command "su - postgres -c '/usr/bin/psql -U postgres < /tmp/pg_chpasswd.sql'" action :nothing end
command は root
で実行されるはずですが、PostgreSQL
の socket 接続の場合、デフォルトでは Peer
接続になっているため、Linux のユーザと、PostgreSQLのユーザが同一でないと、socket通信できないようになっています。
pg_hba.conf
を適当に変更すれば良いのですが、su - postgres
すれば特に問題がないので、そのままで実行できるようなコマンドを準備しました。
ここでのポイントは action :nothing
として、まだじっこうさせないことですね( ´∀`)bグッ!
-cookbooks/pgsql/recipes/default.rb template "pg_chpasswd.sql" do path "/tmp/pg_chpasswd.sql" source "pg_chpasswd.sql.erb" user "postgres" group "postgres" mode 0600 variables ({ :pg_user => node[:postgresql][:user], :pg_password => node[:postgresql][:password] }) notifies :run, 'execute[pgsql-chpasswd]', :immediately end
[amazonjs asin="4798123358" locale="JP" title="PostgreSQL徹底入門 第3版"]
次に、template
のパートです。
ここでは、/tmp/
に中間ファイルを配置するようにしてます。=> path "/tmp/pg_chpasswd.sql"
今回は PostgreSQL
で利用するので、user(owner)/group は postgres
を使っています。
variables
に、今回使用する pg_user
と pg_password
の元ネタを配備しています。
最後に notifies
で execute
させるという流れです。
対応した template との差異がなければ、実行されないということになりますね。
attributeどうしよう
対象となる変数をどうするかですが、初期値は attributes
へ、このの定義は role
や node
を使います。
今回は attribute
と node
で定義しています。
-cookbooks/pgsql/attributes/default.rb default['postgresql']['user'] = "" default['postgresql']['password'] = ""
/pgsql.json { "postgresql": { "user" : "zabbix", "password" : "zabbix" }, "run_list":[ : ] }
見ただけで分かるように、user
= "zabbix" , password
= "password" という素人定義です。
これにより、sql の中間ファイルの更新状態を見て、chef 側では、一度だけ実行される、と言うことになります。
めでたいヽ(´ー`)ノ
課題がないわけじゃない
個人的には、もうコレで十分なのですが、2つほど気がついた点があります。時と場合によっては、致命的です。
- /tmp/ 配下のファイルが消されたら、また実行される
- 中間ファイルに残っている情報は見られるかも知れない
1./tmp/ 配下のファイルが消されたら、また実行される
まんまですね。
とある rebootタイミングや cronなどで、/tmp/ 配下は clearされるように設定されていた場合、中間ファイルが削除されます。
その後に、同じレシピを実行した場合、やらなくても良い SQLが流れることになります。
2.中間ファイルに残っている情報は見られるかも知れない
今回特にそうですが、めっちゃ password が入ってバレます。
md5sum したものを入れておけば良いじゃんみたいなのはありますが、時と場合によっては SQL文すら見られたくないと言うときなどもあるかと思われます。
そんな時、いくらアクセス制御をしたところで、どうにもならない場合もあるかも知れません。ないかも知れませんが。
少なくとも、脅威が1つ増えることによって、リスクと対策は増えると言うことです。気をつけましょう。
応用編
すでに想像ついてる方がほとんどでしょうか、中間ファイルを実行させるようにすれば、コマンドを実行するようにもできるでしょう。
また、消されることをうまく使って、何度も実行することもできるかも知れません。元々の使い方ではないでしょうが('A`)
ま、template
にはこんな使い方もあるんよ( ゚д゚ )クワッ!!
て感じで、どうぞ。
[amazonjs asin="4434181475" locale="JP" title="シェフ vol 100―一流のシェフたち"]