Ansibleのcommand moduleに要注意!

わたなべです。
いろいろな社内準備でわたわたしております!
(詳しくは7月1日のプレスリリースをご覧ください)

さて先日、Ansibleで挙動に悩まされたことがありました。
結果的には初歩的なものでしたが、
個人的にまたやらかしそうなので、備忘録として残しておきます😓

やりたかったこと

- name: "create-csv"
  command: "node index.js > hash_client.csv"
  args:
    chdir: "/opt/create-csv/"

上記のようなcommand moduleを用意し、csvを生成するレシピを作りました。

しかし、csvが生成されません。

しかも出力されるべき中身が、
なぜかAnsibleのログ出力に紛れ込んでいるではありませんか。

Ansibleのレシピを試行錯誤する際、デバッグレベルを上げたり下げたりしますが(-v ~ -vvvv)、
今回に関しては原因がわかりませんでした。
どうもレシピは正常に動いているようです。

原因はcommand moduleの仕様でした

いろいろ調査していると、どうもリダイレクトが効いていないということがわかりました。
なぜ効いていないのかわからなかったのですが、ふと公式ドキュメントを見ると、
かなり目立つように書いてありました…

It will not be processed through the shell, so variables like $HOME and operations like "<", ">", "|", ";" and "&" will not work (use the shell module if you need these features).

このmoduleはShellを介して処理されないので、$HOME変数や”<“、”>”、”|”、”;”、”&”は動作しません。(これらの機能が必要な場合は、shell moduleを使用してください)。

まさにこのままですね。最初から公式ドキュメントを読むべきでした。

いつもは環境変数やPATHのありなしで挙動が変わらないように、
command moduleを使用していました。
しかし、今回のようなリダイレクトを使いたい場合は、shell moduleが良いようです。

公式ドキュメントにも、どうしてもshell moduleを使わなくてはいけない場合を除き、
なるだけcommand moduleを使うようにと書いてあります。
(そもそも冪等性を担保できないような処理をAnsibleに入れるなという話はありますが…)

ということで、今回はこのようになりました。

- name: "create-csv"
  shell: "node index.js > hash_client.csv"
  args:
    chdir: "/opt/create-csv/"

まとめ

  • Ansibleのcommand moduleは、Shellを介して処理されない
  • command moduleは$HOME変数や”<“、”>”、”|”、”;”、”&”が動作しない
  • 上記機能が必要な場合は、shell moduleを代わりに使用する
  • どうしてもshell moduleを使わなくてはいけない場合を除き、なるだけcommand moduleを使うようにする