AnsiblePlaybookで条件文を使用する方法
Ansibleでは、タスクが実行される前に評価される条件を定義できます。 条件が満たされない場合、タスクはスキップされます。 これは、whenキーワードを使用して実行されます。このキーワードは、通常、変数またはファクトに基づく式を受け入れます。
次の例では、create_user_fileとuserの2つの変数を定義しています。 create_user_fileがtrueと評価されると、user変数で定義されたユーザーのホームディレクトリに新しいファイルが作成されます。
ansible-practiceディレクトリにplaybook-04.ymlという名前の新しいファイルを作成します。
nano ~/ansible-practice/playbook-04.yml
次に、新しいプレイブックファイルに次の行を追加します。
〜/ ansible-practice / playbook-04.yml
---
- hosts: all
vars:
- create_user_file: yes
- user: sammy
tasks:
- name: create file for user
file:
path: /home/{{ user }}/myfile
state: touch
when: create_user_file
内容の編集が完了したら、ファイルを保存して閉じます。
インベントリファイルからサーバー上でこのプレイブックを実行するには、このシリーズの他のプレイブックを実行するときに以前に使用したのと同じ接続引数を使用してansible-playbookを実行します。 ここでも、inventoryという名前のインベントリファイルとsammyユーザーを使用してリモートサーバーに接続します。
ansible-playbook -i inventory playbook-04.yml -u sammy
条件が満たされると、再生出力にchangedステータスが表示されます。
Output... TASK [create file for user] ***************************************************************************** changed: [203.0.113.10] ...
create_user_fileの値をnoに変更すると、条件はfalseに評価されます。 この場合、再生出力にskippingステータスが表示され、タスクが実行されなかったことを示します。
Output... TASK [create file for user] ***************************************************************************** skipping: [203.0.113.10] ...
Ansibleプレイブックのコンテキストでの条件の一般的な使用法は、registerと組み合わせることです。これは、新しい変数を作成し、コマンドから取得した出力に割り当てるキーワードです。 このように、任意の外部コマンドを使用して、タスクの実行を評価できます。
注意すべき重要な点の1つは、デフォルトでは、条件の評価に使用しているコマンドが失敗した場合、Ansibleが再生を中断することです。 そのため、ignore_errorsディレクティブをyesに設定して、そのタスクに含める必要があります。これにより、Ansibleは次のタスクに進み、プレイを続行します。
次の例では、ファイルがまだ存在しない場合にのみ、ユーザーのホームディレクトリに新しいファイルを作成します。これは、lsコマンドでテストします。 ただし、ファイルが存在する場合は、debugモジュールを使用してメッセージを表示します。
ansible-practiceディレクトリにplaybook-05.ymlという名前の新しいファイルを作成します。
nano ~/ansible-practice/playbook-05.yml
次に、次のコンテンツを新しいプレイブックファイルに追加します。
〜/ ansible-practice / playbook-05.yml
---
- hosts: all
vars:
- user: sammy
tasks:
- name: Check if file already exists
command: ls /home/{{ user }}/myfile
register: file_exists
ignore_errors: yes
- name: create file for user
file:
path: /home/{{ user }}/myfile
state: touch
when: file_exists is failed
- name: show message if file exists
debug:
msg: The user file already exists.
when: file_exists is succeeded
完了したら、ファイルを保存して閉じます。
次に、前の例と同じ接続引数を使用してansible-playbookを実行します。 ここでは、inventoryという名前のインベントリファイルとsammyという名前のユーザーを使用していますが、それに応じてこれらの値を変更する必要があります。
ansible-playbook -i inventory playbook-05.yml -u sammy
このプレイブックを初めて実行するとき、ファイルがそのパスに存在しないため、コマンドは失敗します。 次に、ファイルを作成するタスクが実行され、最後のタスクはスキップされます。
...
[secondary_label Output]
TASK [Check if file already exists] *********************************************************************
fatal: [203.0.113.10]: FAILED! => {"changed": true, "cmd": ["ls", "/home/sammy/myfile"], "delta": "0:00:00.004258", "end": "2020-10-22 13:10:12.680074", "msg": "non-zero return code", "rc": 2, "start": "2020-10-22 13:10:12.675816", "stderr": "ls: cannot access '/home/sammy/myfile': No such file or directory", "stderr_lines": ["ls: cannot access '/home/sammy/myfile': No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoring
TASK [create file for user] *****************************************************************************
changed: [203.0.113.10]
TASK [show message if file exists] **********************************************************************
skipping: [203.0.113.10]
...
出力から、create file for userタスクがサーバーに変更を加えたことがわかります。これは、ファイルが作成されたことを意味します。 ここで、プレイブックを再度実行すると、別の結果が得られます。
ansible-playbook -i inventory playbook-05.yml -u sammy
Output...
TASK [Check if file already exists] *********************************************************************
changed: [203.0.113.10]
TASK [create file for user] *****************************************************************************
skipping: [203.0.113.10]
TASK [show message if file exists] **********************************************************************
ok: [203.0.113.10] => {
"msg": "The user file already exists."
}
...
Ansibleプレイブックでの条件の使用について詳しく知りたい場合は、公式ドキュメントを参照してください。