Ansible - 条件判定

今回は、条件判定を使って処理を行うサーバ、行わないサーバの判別を追加していきます。
前回のブログでsite.ymlにこっそり追加されていた、「gather_facts: yes」の設定で対象サーバの情報が取得されます。

[user01@ansible-ctl01 ~]$ cat ansible/site.yml
---
# chrony setting playbook
- name: Apply chrony settings
  hosts: all
  gather_facts: yes
  become: true

  roles:
    - chrony

Playbookを作成しなくても以下のコマンドで取得することが可能です。取得される情報が多いので一部抜粋して見てみます。

[user01@ansible-ctl01 ansible]$ ansible all -i hosts.ini -m setup --vault-password-file=~/.vault_pass.txt
ansible-client01 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.220.10"
        ],
~ 省略 ~
        "ansible_distribution": "AlmaLinux",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/redhat-release",
        "ansible_distribution_file_variety": "RedHat",
        "ansible_distribution_major_version": "9",
        "ansible_distribution_release": "Sage Margay",
        "ansible_distribution_version": "9.6",
~ 省略 ~
        "ansible_nodename": "ansible-client01",
        "ansible_os_family": "RedHat",
        "ansible_pkg_mgr": "dnf",
~ 省略 ~

※vaultパスワードをオプションで渡していますが、gather_factsでは通常は不要です。しかし、推奨ディレクトリ構造の中にvaultで暗号化しているファイルが含まれている場合、使用していなくても復号化が必要になるため、vaultパスワードを渡す必要があります。

IPアドレスやOS情報、その他様々な情報が取得されています。

前回までに作成したansible環境で、gather_factsで取得される情報を使用してサーバの判別を行えることを確認していきます。Almalinuxサーバが既に一台あるので、Ubuntuサーバをインベントリに追加してOSの種別による条件判定を行います。

サーバの追加とインベントリファイルの修正

インベントリにUbuntuサーバを追加します。Ubuntuサーバはユーザの作成や公開鍵の配置、そしてfingerprintの登録も実施済みの状態です。

[user01@ansible-ctl01 ~]$ cat ansible/hosts.ini
[alma]
ansible-client01 ansible_host=10.0.220.10 ansible_user=user01 ansible_ssh_private_key_file=~/.ssh/ansible_ssh_key
[ubuntu]
ansible-client01 ansible_host=10.0.220.11 ansible_user=user01 ansible_ssh_private_key_file=~/.ssh/ansible_ssh_key

[ ]書きの部分はグループ名になります。
ついでに、同じプロジェクト内で使用される同じ変数は「group_vars」にまとめることができるので、インベントリファイル内の「ansible_user」、「ansible_private_key_file」の変数を「group_vars/all/vars.yml」に記載し、インベントリファイル「hosts.ini」からは削除することにします。
前回のブログで「group_vars」の下に「all」ディレクトリを作成し、すべてのホストに適用される変数を記載していましたが、ホストをグループに分けても「all」ディレクトリ内の変数はすべてのホストが対象になります。

[user01@ansible-ctl01 ~]$ cat ansible/group_vars/all/vars.yml
---
ansible_user: user01
ansible_ssh_private_key_file: ~/.ssh/ansible_ssh_key

[user01@ansible-ctl01 ~]$ cat ansible/hosts.ini
[alma]
ansible-client01 ansible_host=10.0.220.10
[ubuntu]
ansible-client02 ansible_host=10.0.220.11

条件判定の追加

続いて、chronyの設定処理を呼び出す前段のファイル「roles/chrony/tasks/main.yml」に条件判定を追加します。

[user01@ansible-ctl01 ~]$ cat ansible/roles/chrony/tasks/main.yml
---
- name: Define OS condition variable
  set_fact:
    is_redhat: "{{ ansible_os_family == 'RedHat' and ansible_distribution_major_version in ['8', '9'] }}"

- name: setting chrony task
  import_tasks: chrony_setting.yml
  when: is_redhat

「set_fact:」は動的に変数を設定するモジュールです。先頭に追加した、「set_fact:」で、gather_factsで収集した情報を参照して、"RedHat"系OS、且つ、バージョンが8か9の場合は「is_redhat」にtrueが入ります。
「name: setting chrony task」のブロックに追加した「when:」でis_redhatの値を判定し、trueならtaskが実行されます。

Ubuntuサーバのgather_factsの結果を見てみると、「ansible_os_family」は"Debian"となっているので、処理がスキップされるはずです。

[user01@ansible-ctl01 ~]$ ansible all -i ansible/hosts.ini -l ansible-client02 -m setup --vault-password-file=~/.vault_pass.txt
~省略~
        "ansible_nodename": "ansible-client02",
        "ansible_os_family": "Debian",
~省略~

実行

実行して確認してみると、想定通りUbuntuサーバである「ansible-client02」は処理がスキップされました。

[user01@ansible-ctl01 ~]$ ansible-playbook -i ansible/hosts.ini ansible/site.yml --vault-password-file=~/.vault_pass.txt

PLAY [Apply chrony settings] ****************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [ansible-client01]
ok: [ansible-client02]

TASK [chrony : Define OS condition variable] ************************************************************************************************
ok: [ansible-client01]
ok: [ansible-client02]

TASK [chrony : replace chrony.conf] *********************************************************************************************************
skipping: [ansible-client02]
ok: [ansible-client01]

PLAY RECAP **********************************************************************************************************************************
ansible-client01           : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-client02           : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

まとめ

ansibleでの条件判定による処理対象サーバの選別を行ってみました。今回の例では処理をスキップするだけでしたが、Ubuntuサーバに対してはchrony設定ではなく、UbuntuのデフォルトNTPクライアントであるtimesyncdの設定を変更する処理を追加すると、一回のansible-playbook実行でOSが異なる複数のサーバに対して同時に処理を行うことができるようになります。

参考

Ansible community documentation

お問い合わせ

弊社では様々なサービスを取り扱っております。
詳細はサービス一覧からご覧ください。

お気軽にお問い合わせください。応対時間 9:30-17:30 [ 土・日・祝日除く ]

お問い合わせ