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 [ 土・日・祝日除く ]
お問い合わせ