てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] F5 BIG-IP への接続確認には ping モジュールではなく bigip_* を利用するしかないのではという話

はじめに

先日開催された Ansibleもくもく会 (サーバ編 & NW編)2019.11では、ネットワーク編の環境として F5 BIG-IP の環境を割り当ていただきました。

書いていく Playbook は、こんな感じものでした(引用元)。

---
- name: GRAB F5 FACTS
  hosts: f5
  connection: local
  gather_facts: no


  tasks:

    - name: COLLECT BIG-IP FACTS
      bigip_device_facts:
        gather_subset:
         - system-info
        server: "{{private_ip}}"
        user: "{{ansible_user}}"
        password: "{{ansible_ssh_pass}}"
        server_port: 8443
        validate_certs: no
      register: device_facts

先だって、参加者から「ansible all -m ping を実行すると、f5のみ失敗するが、どのように確認すればよいか」という旨の質問がありました。

  • 発生するエラー
f5 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Authentication or permission failure. In some cases, you may have been able to authenticate and did not have permissions on the target directory. Consider changing the remote tmp path in ansible.cfg to a path rooted in \"/tmp\". Failed command was: ( umask 77 && mkdir -p \"` echo ~/.ansible/tmp/ansible-tmp-1573597787.31-66002750839439 `\" && echo ansible-tmp-1573597787.31-66002750839439=\"` echo ~/.ansible/tmp/ansible-tmp-1573597787.31-66002750839439 `\" ), exited with result 1", 
    "unreachable": true
}

メンターとして参加させていただきましたが、当日は私としては答えがなかったのですが、考えた結果、bigip_* モジュールを利用するしかないのでは、となりましたので、その考えをまとめます。

  • 環境
    • Ansible 2.8.5

ping モジュールとネットワーク機器

Ansible における ping モジュールは ICMP による 疎通確認ではなく、Ansible が利用する接続方式(デフォルト SSH)での接続確認です。

そのため、もし Ansible から BIG-IP に HTTP API で接続して利用するのであれば、接続確認としても HTTP を利用するのが良いと考えています。そのため、そもそも ping モジュールは不向きなのではと思いました。

となるともう、bigip_* モジュールを利用して接続確認するしかないのでは、というのが私の考えです。

なお、公式ドキュメントの「Network Debug and Troubleshooting Guide」では切り分けための接続確認として、ping モジュールではなく、eos_command モジュール(ここでは Arista EOS向けの解説)を利用して、? コマンドを実行する方法を掲載しています。この方法は network_cli コネクションプラグインに対応している OS (IOS、EOS、Junos など)向けであって、BIG-IP モジュールでは利用できません

ansible コマンドと bigip モジュールを利用した接続確認

ここでは インベントリファイル hosts 内のグループ lb 内に BIG-IP ホスト f5 を定義しているものとしてます。

  • 接続確認コマンド(長い)
ansible -i hosts lb -m bigip_device_facts -a "gather_subset=system-info server=BIGPのアドレス user=ユーザー名 password=パスワード server_port=8443 validate_certs=no" -c local

やっていることは以下のとおりです。

  • bigip_device_facts モジュールを利用
    • 接続確認なので、設定変更しない当たり障りないモジュールを指定
    • 接続方式はデフォルトの restcli ではなく)
      • 利用したい接続方式に合わせる
    • gather_subset オプションで、戻り値が少ない system-info を指定
    • BIG-IP への接続ポートを 8443 に指定
    • 補足: Ansilbe 2.9 では bigip_device_info に名前変更されてます
  • -c local でコネクションプラグインに local を指定

これで、local コネクションプラグインを利用しつつ、BIG−IP に HTTP API で接続することになります。

以下の通り、fact が返ってこれば、接続成功です、

f5 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": true, 
    "system_info": {
        "base_mac_address": "0a:7f:96:21:a0:75", 
        "chassis_serial": "84a12dec-93f2-65f5-4eaf0ae97801", 
        "hardware_information": [
            {
                "model": "Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz", 
                "name": "cpus", 
                "type": "base-board", 
                "versions": [
                    {
                        "name": "cpu stepping", 
                        "version": "1"
                    }, 
                    {
                        "name": "cpu sockets", 
                        "version": "1"
                    }, 
                    {
                        "name": "cpu MHz", 
                        "version": "2300.021"
                    }, 
                    {
                        "name": "cores", 
                        "version": "2  (physical:2)"
                    }, 
                    {
                        "name": "cache size", 
                        "version": "46080 KB"
                    }
                ]
            }
        ], 
        "marketing_name": "BIG-IP Virtual Edition", 
        "package_edition": "Point Release 7", 
        "package_version": "Build 0.0.1 - Tue May 15 15:26:30 PDT 2018", 
        "platform": "Z100", 
        "product_build": "0.0.1", 
        "product_build_date": "Tue May 15 15:26:30 PDT 2018", 
        "product_built": 180515152630, 
        "product_changelist": 2557198, 
        "product_code": "BIG-IP", 
        "product_jobid": 1012030, 
        "product_version": "13.1.0.7", 
        "time": {
            "day": 12, 
            "hour": 22, 
            "minute": 53, 
            "month": 11, 
            "second": 19, 
            "year": 2019
        }, 
        "uptime": 67290.0
    }
}

コマンドが長いですね。接続情報系のオプションを provider にまとめたり、変数化したりカスタマイズの余地はあるかとお思います。

もうPlaybook 書いたほうが良くないですか!? という思いが芽生えます。