Advent Calenderの時期で、私もAnsible 2 Advent Calender 2019にエントリしていますが、空気を読まずに通常投稿!!
先日の記事にも書きましたが、我が家の検証用のFortigateが2台構成になりました。
最終的にHAを組むつもりなので、各々のバージョンを合わせるために、Ansibleでファームアップを試みてみましたので、それを記録しておきます。
Ansible関連の実践記事一覧はこちら。
目的
AnsibleによるFortigateのファームアップにおけるPlaybookに必要なパラメータを明らかにするため
※モジュールのリファレンスが<your_own_value>
ばかりで困るんです…
環境
※途中の過程でFortios5.6でも試しかけましたが、fortios_factsすら通らなかったので断念。
やっぱり5.6系(fw02)だとfactsでもだめか… pic.twitter.com/GTEH2AWevC
— tatematsu_san (@tk4_jj) 2019年12月8日
fortios_system_firmware_upgradeの手法毎の結果
source: usbの場合
事前準備として、ファームアップ用のファイル(.outファイル)をUSBメモリに入れ、本体に接続します。
その後、以下のようなPlaybookで、問題なくファームアップが実施できました。
最後にdebug仕込んでますが、Reboot入ってしまうのでエラーになります。(うろ覚えなので、確認後修正するかもしれません。)
ただ、処理はちゃんと実行されていて、Reboot後には新しいファームで起動してきます。
--- - hosts: fortigate gather_facts: false vars: vdom: "root" tasks: - name: Perform firmware upgrade with firmware file on USB. fortios_system_firmware_upgrade: vdom: "{{ vdom }}" system_firmware: filename: "FGT_60D-v6-build0303-FORTINET.out" #USBメモリ上のファイル名を入れる format_partition: "yes" source: "usb" register: fortios_system_firmware_upgrade_result - name: Debug debug: var: fortios_system_firmware_upgrade_result
source: fortiguardの場合
事前準備として、ファームアップ用のファイル名が必要になります。
この「ファイル名」が曲者でして。「オンラインなのにファイル名…?」となりました。バージョンの指定とかならわかるんですが。
- USBでやったときの結果と同じファイル名でやってみる→NG ( "FGT_60D-v6-build0303-FORTINET.out" )
- ターゲットにしているバージョンを入れてみる→NG ( "v6.0.8" )
■NG時の出力(Playbookの実行結果のstateとしてはokになります)
"results": { "error": "download_failed", "status": "error" },
頭を悩ませていたんですが、fortios_factsに「system_firmware_select」というfactがあったことを思い出しまして、以下のPlaybookを実行。
■fortios_facts実行用のPlaybook
--- - hosts: fortigate gather_facts: false tasks: - name: Get Facts. fortios_facts: gather_subset: - fact: 'system_firmware_select' register: getfact_result - name: Debug debug: var: getfact_result
その結果、以下のようなJSON形式の情報が戻ってきました。
■fortios_factsの出力結果
"results": { "available": [ { "branch-point": 303, "build": 303, "id": "06000000FIMG0009900008", "major": 6, "minor": 0, "name": "FortiOS", "notes": "http://docs.fortinet.com/d/fortios-6.0.8-release-notes/download", "patch": 8, "release-type": "GA", "source": "fortiguard", "version": "v6.0.8" }, { "branch-point": 302, "build": 302, "id": "06000000FIMG0009900007", "major": 6, "minor": 0, "name": "FortiOS", "notes": "http://docs.fortinet.com/d/fortios-6.0.7-release-notes/download", "patch": 7, "release-type": "GA", "source": "fortiguard", "version": "v6.0.7" }, (中略) ], "current": { "branch-point": 231, "build": 231, "id": "current", "major": 6, "minor": 0, "name": "FortiOS", "notes": "http://docs.fortinet.com/d/fortios-6.0.4-release-notes/download", "patch": 4, "platform-id": "FGT60D", "release-type": "GA", "source": "current", "version": "v6.0.4" }
この中のどれかか…とあたりを付け、ファイル名になりそうな「id」という情報を試しに入れてみました。
結果、Playbookの実行が即download_Failed などにはならず、待ち状態→Timeoutっぽい形でfailedになりました。
■作成したPlaybook
--- - hosts: fortigate gather_facts: false vars: vdom: "root" tasks: - name: Perform firmware upgrade with firmware on fortiguard. fortios_system_firmware_upgrade: vdom: "{{ vdom }}" system_firmware: filename: "06000000FIMG0009900008" #v6.0.8の場合の「ID」の値を記載 format_partition: "yes" source: "fortiguard" register: fortios_system_firmware_upgrade_result - name: Debug debug: var: fortios_system_firmware_upgrade_result
しばらく放置すると、コンソール画面に変化が現れ、ファームアップのシーケンスに入ってくれて、その後自動で再起動→ファームアップが完了しました!!
というわけで、【source: fortiguardを利用する場合のfilenameにはfortios_factsで取得できる対象ファームウェアの「id」を入れればいい】ということがわかりました。
これも最後にdebug仕込んでますが、ファームウェアのダウンロード中の段階でTimeoutを迎えてエラーになります。ただ、処理はちゃんと実行されていて、Reboot後には新しいファームで起動してきます。
試しにPlaybook実行時に--timeout=6000
とオプションを入れてみましたが変わりませんでした。
httpapiのtimeout値をいじればもしかしたら戻りが取れるのかもしれません。また調べてみようと思います。
ダウングレードの場合
試しに、6.0.8->6.0.7を同じやり方で試してみたんですが、ダウングレードは始まりませんでした。
ファームウェア関連は、WebUIで見ると、こんな画面になります。(System -> Firmware )
上手く行かない理由は、この部分の「Confirm version downgrade」に当たる部分がモジュール上存在しないからかな、と予想してます。
(WebUIでやる場合には、問題なくダウングレードも実施可能です)
source: uploadの場合(未達成)
おそらく、Ansibleを使う時点でUSBはないな、と思ってます。そうすると、本命はfortiguardか、このupload。
なんですが。
モジュール側で処理してくれればいいのにと思いながら、ちょっと試してみましたが、上手く行かず。
■作成したPlaybook(失敗してます)
--- - hosts: fortigate gather_facts: false vars: vdom: "root" tasks: - name: Perform firmware upgrade with firmware file Upload File. fortios_system_firmware_upgrade: vdom: "{{ vdom }}" system_firmware: file_content: lookup('file', '/home/ansible/ansible-playbook/fortigate/F60Dv608_base64') filename: "FGT_60D-v6-build0303-FORTINET.out" format_partition: "yes" source: "upload" register: fortios_system_firmware_upgrade_result - name: Debug debug: var: fortios_system_firmware_upgrade_result
外部でbase64化したものをlookupで読ませたんですが、失敗してます。
これは余裕がある時にもう少し別の方法を試してみます。
まとめ
最後の「upload」はまだ未完了ですが、FortigateのファームアップもAnsibleで実行できることが確認できました。
uploadのものも、fortiguardほどはわからなくはないと思いますので、また折を見てやってみます。
●残課題
- uploadでのbase64での実践
- fortiguard/uploadで発生するtimeoutを伸ばして、処理結果を取得する方法