はじめに
2020/04/14 に開催された Ansible もくもく会にメンターとして参加させていただきました。
サーバー編、ネットワーク編とあるうちのネットワーク編を主に見ていました。
実際に自分自身もハンズオンで試してみると、Ansible Tower のパートで、ネットワーク機器への認証が通らないエラーに出会いました。
この記事では、発生したエラーから分かったこと、切り分け、対処方法についてまとめます。
- 動作確認環境
- Ansible Tower 3.6.3
- Ansible 2.9.5
結論
Ansible Tower の以下の2箇所に秘密鍵が指定されている場合、(1) が優先される、ということが分かりました。
以下、発生したエラーや、切り分けた手順です。
発生したエラー
ネットワーク編の Exercise 6で、「Backup network configurations」と言う名前のジョブテンプレートを作って、実行したときに以下のエラーが発生しました。(XX
は一応伏せ字です)
[Errno 13] Permission denied: '/home/studentXX/.ssh/aws-private.pem'
環境としては、Cisco IOS、Arista EOS、Juniper Junos からなる仮想ネットワーク機器4台がありましたが、4台とも上記のエラーでした。
Playbook、厳密にはロールではこの部分です。(IOSの場合)
切り分け
秘密鍵ファイルのパーミッションを調べてみると所有ユーザー、グループは studentXX
で 400
でした。
[studentXX@ansible ~]$ ls -al /home/studentXX/.ssh/aws-private.pem -r--------. 1 studentXX studentXX 1674 Apr 13 12:28 /home/studentXX/.ssh/aws-private.pem
Ansible Tower としては、awx
ユーザーか何かで読み取りに行くのでしょう。とにかく Tower には権限はありません。
そもそも、なぜこの秘密鍵を参照しに行こうとしてるのか、Tower 側を調べてみると、インベントリーの変数に設定されていました。
ここで、秘密鍵のパーミンションを変更するのも何だかおかしな気がしたため、引き続き Tower 側の設定を見直しました。(予め作成されていたので探る必要がある)
実行したジョブテンプレートで利用しているクレデンシャルを確認すると、ここに秘密鍵データが(暗号化されて)格納されていました。
クレデンシャルまわりの機能は Tower 独自の機能です。せっかくクレデンシャルを利用しているのだから、こちらを使うのが筋だろうと考えました。
対処
しかし、前述のように、インベントリ変数に設定されている ansible_ssh_private_key_file
変数の値が優先されています。
そこで、この変数を無効化しました。
動作確認
動作確認のため、再度ジョブテンプレートを実行しました。
今度は無事に認証も通り、目的であるコンフィグのバックアップもできました。
[studentXX@ansible ~]$ ls -la /backup/2020-04-14-09-59/ total 24 drwxr-xr-x. 2 root root 54 Apr 14 10:00 . drwxr-xr-x. 21 root root 4096 Apr 14 14:12 .. -rw-r--r--. 1 root root 5291 Apr 14 10:00 rtr1 # 各バックアップコンフィグファイル -rw-r--r--. 1 root root 1926 Apr 14 10:00 rtr2 -rw-r--r--. 1 root root 1734 Apr 14 10:00 rtr3 -rw-r--r--. 1 root root 1367 Apr 14 10:00 rtr4
想定される原因
もくもく会の環境の構築処理の詳細はあまり分かっていないのですが、awx-manage
でインベントリをインポートしたときに、うっかり入ってしまったのではと予想しています。ちがっていたらすみません。
- CLI パートで利用したインベントリファイル
~/lab_inventory/hosts
[all:vars] ansible_ssh_private_key_file=/home/studentXX/.ssh/aws-private.pem ..(略)...
ユーザー名もインベントリ内の変数の値が優先される
インベントリ内の各グループ変数としてユーザー名が定義されていました。
これもないほうが良いと思いました。ユーザー名はクレデンシャルでも定義されているためです。
試しに、グループ変数に定義されたユーザー名を、意図的に間違えるとジョブが正常に実行できなくなりました。
このことから、ユーザー名もクレデンシャルの値よりインベントリ内の変数を優先する、ということが言えます。
おわりに
Ansible は変数を定義できる場所が多岐にわたります。更に Ansible Tower の場合、変数が持つ役割を Tower 独自の機能で担っている場合もあります。被ってる部分については少し注意が必要に思います。
コンテンツは随時改良されていくと思いますので、また参加したいと思います。
もくもく会を運営していただいているみなさん、コンテンツのメンテナンスや翻訳していただいているみなさん、ありがとうございます!