てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] インベントリ変数で指定した秘密鍵のパスはクレデンシャルの秘密鍵データより優先される

はじめに

2020/04/14 に開催された Ansible もくもく会にメンターとして参加させていただきました。

サーバー編、ネットワーク編とあるうちのネットワーク編を主に見ていました。

実際に自分自身もハンズオンで試してみると、Ansible Tower のパートで、ネットワーク機器への認証が通らないエラーに出会いました。

この記事では、発生したエラーから分かったこと、切り分け、対処方法についてまとめます。

  • 動作確認環境
    • Ansible Tower 3.6.3
    • Ansible 2.9.5

結論

Ansible Tower の以下の2箇所に秘密鍵が指定されている場合、(1) が優先される、ということが分かりました。

  • (1) インベントリ変数に設定されている ansible_ssh_private_key_file 変数
  • (2) クレデンシャルの「SSH 秘密鍵」に格納した秘密鍵データ

f:id:akira6592:20200415103428p:plain
インベントリ変数の秘密鍵のパスが優先される

以下、発生したエラーや、切り分けた手順です。

発生したエラー

ネットワーク編の Exercise 6で、「Backup network configurations」と言う名前のジョブテンプレートを作って、実行したときに以下のエラーが発生しました。(XXは一応伏せ字です)

[Errno 13] Permission denied: '/home/studentXX/.ssh/aws-private.pem'

f:id:akira6592:20200415101042p:plain
鍵のパーミッションエラー

環境としては、Cisco IOS、Arista EOS、Juniper Junos からなる仮想ネットワーク機器4台がありましたが、4台とも上記のエラーでした。

Playbook、厳密にはロールではこの部分です。(IOSの場合)

github.com

切り分け

秘密鍵ファイルのパーミッションを調べてみると所有ユーザー、グループは studentXX400 でした。

[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 側を調べてみると、インベントリーの変数に設定されていました。

f:id:akira6592:20200415101137p:plain
インベントリ変数として秘密鍵のパスが指定されていた

ここで、秘密鍵のパーミンションを変更するのも何だかおかしな気がしたため、引き続き Tower 側の設定を見直しました。(予め作成されていたので探る必要がある)

実行したジョブテンプレートで利用しているクレデンシャルを確認すると、ここに秘密鍵データが(暗号化されて)格納されていました。

f:id:akira6592:20200415101226p:plain
クレデンシャルの秘密鍵データが設定されていた

クレデンシャルまわりの機能は Tower 独自の機能です。せっかくクレデンシャルを利用しているのだから、こちらを使うのが筋だろうと考えました。

対処

しかし、前述のように、インベントリ変数に設定されている ansible_ssh_private_key_file 変数の値が優先されています。

そこで、この変数を無効化しました。

f:id:akira6592:20200415101317p:plain
秘密鍵のパスの変数定義を削除した

動作確認

動作確認のため、再度ジョブテンプレートを実行しました。

f:id:akira6592:20200415101354p:plain
再実行(成功)

今度は無事に認証も通り、目的であるコンフィグのバックアップもできました。

[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

..(略)...

ユーザー名もインベントリ内の変数の値が優先される

インベントリ内の各グループ変数としてユーザー名が定義されていました。

f:id:akira6592:20200415123842p:plain
グループ変数に定義されたユーザー名

これもないほうが良いと思いました。ユーザー名はクレデンシャルでも定義されているためです。

試しに、グループ変数に定義されたユーザー名を、意図的に間違えるとジョブが正常に実行できなくなりました。

このことから、ユーザー名もクレデンシャルの値よりインベントリ内の変数を優先する、ということが言えます。

おわりに

Ansible は変数を定義できる場所が多岐にわたります。更に Ansible Tower の場合、変数が持つ役割を Tower 独自の機能で担っている場合もあります。被ってる部分については少し注意が必要に思います。

コンテンツは随時改良されていくと思いますので、また参加したいと思います。

もくもく会を運営していただいているみなさん、コンテンツのメンテナンスや翻訳していただいているみなさん、ありがとうございます!