Ansibleにてモジュールの用意されていない操作を実行する場合、OS上でコマンドを実行してくれるモジュールが用意されています。 command
や shell
がそれにあたります。
しかしながら、公式では可能な限り command
モジュールの利用を推奨しているようです。
If you want to run a command through the shell (say you are using <, >, |, etc), you actually want the shell module instead. Parsing shell metacharacters can lead to unexpected commands being executed if quoting is not done correctly so it is more secure to use the command module when possible.
どちらのモジュールにも、以下のような特徴をもっています。
creates
やremoves
パラメータを利用しない場合、または指定した条件に合致しない場合、必ず処理が実行される- コマンド実行結果ステータスが0であった時に成功、それ以外は失敗となる
- コマンド成功時のステータスは
changed
となる
creates
や removes
パラメータとは、指定したファイルの有無により、コマンド実行を制御してくれるパラメータです。逆に言うと、このパラメータで管理できない処理に関しては、必ず処理が実行される事になります。
例えば、AnsibleにてOSのロケールを変更したいとなった場合、 localectl set-locale
にあたるようなモジュールは用意されていないため、以下のようなplyabookを書くことになります。
- name: ロケールを日本語に変更 command: localectl set-locale LANG=ja_JP.utf8
まあ、これで変更してくれるのですが、上で記載した特徴の通り、このタスクはplaybook実行時に毎回実行され、changedを返してくることになります。毎回実行されても問題ないものですが、playbookの管理上、これは望ましい事ではありません。意味のないchangedを毎回返してくることも、煩わしいです。
これを回避するアイデアを記載していきます。
環境情報です。
- CentOS 7.6
- Ansible 2.7.6
システムロケールが LANG=ja_JP.utf8
の時にはロケール変更処理を、そうでない場合にはスキップして欲しい訳ですから、そういったplaybookを書いてあげることになります。
サンプルは下記です。
- name: システムロケールの確認 command: localectl status register: localectl_result check_mode: no changed_when: false - name: ロケールの変更 command: localectl set-locale LANG=ja_JP.utf8 when: "'LANG=ja_JP.utf8' not in localectl_result.stdout"
1つ目のタスクは、現在のロケール情報を取得して、変数 localectl_result
に代入している処理です。 register
とは、タスクの実行結果を指定した変数に代入してくれるディレクティブになります。また、 command
モジュールは、終了コードが0の場合にchangedステータスを返しますが、何も変更していないのにchangedステータスとなるのは変なので、 changed_when: false
として、実行結果のステータスを強制的に変更しています。この設定をすることで、okステータスを返すことになります。
2つ目のタスクで、ロケールの設定を変更しています。whenディレクティブではタスク実行の条件を指定することができ、今回は変数 localectl_result
の stdout
に、 LANG=ja_JP.utf8
の文字列がない場合のみ実行する条件となっています。
変数内の値は debug
モジュールを利用することで表示することができ、今回の場合、以下のようになっています。
playbook
- name: デバッグする debug: var: localectl_result
result
"localectl_result": { "changed": false, "cmd": [ "localectl", "status" ], "delta": "0:00:00.006054", "end": "2019-05-01 19:30:29.018230", "failed": false, "rc": 0, "start": "2019-05-01 19:30:29.012176", "stderr": "", "stderr_lines": [], "stdout": " System Locale: LANG=ja_JP.utf8\n VC Keymap: us\n X11 Layout: n/a", "stdout_lines": [ " System Locale: LANG=ja_JP.utf8", " VC Keymap: us", " X11 Layout: n/a" ] }
こうすることで、現行のロケール設定に応じて、処理を実行/スキップできるようになり、plyabook実行結果の表示も分かりやすいものになってくれます。