ansibleを使って、プレイブックを適用した際に不思議な現象が起こってハマったのでメモ
何が起きたか
ansible-playbook -i インベントリA プレイブックA --diff
を実行した際に、指定していないプレイブックBが適用される現象が発生!!
発生した環境
- 異なるNWのA、Bという環境が2つあり、それぞれインベントリA/B、プレイブックA/Bがある
- インベントリAはプレイブックA、インベントリBはプレイブックBに対応する構成
- 環境ごとに1台踏み台があり各サーバには踏み台経由(多段SSH)でアクセス(詳細後述)
多段SSH構成
A/B環境には同じホスト名(例. app01)のサーバが稼働していて、環境ごとのssh踏み台サーバ
経由でログインするような構成となっていて、
例えば、
A環境のapp01サーバにログインするには ssh a-app01
B環境のapp01サーバにログインするには ssh b-app01
となる。
↓ssh_config抜粋
# A環境用ProxyCommand設定
Host a-* !a-bastion
ProxyCommand ssh -W "$(<<<"%h" awk -F- '{print $NF}')":%p a-bastion
Host a-bastion
HostName xx.xx.xx.xx
# B環境用ProxyCommand設定
Host b-* !b-bastion
ProxyCommand ssh -W "$(<<<"%h" awk -F- '{print $NF}')":%p b-bastion
Host b-bastion
HostName yy.yy.yy.yy
設定内容
ansible.cfgに以下の設定がありました。
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=1500s
control_path = %(directory)s/as-%%h-%%r
通常はこの設定により、ansible適用対象へのssh接続用のソケットファイルを作成して
使い回すことができ、タスク実行の度に接続する必要がなくなり、実行速度があがります。
(pipeliningと合わせて使うのが定石ですね。参考)
原因
ansible-playbookを実行中に作成されるファイルが以下の通り。
$ ls -1 ~/.ansible/cp/
as-xx.xx.xx.xx-centos
as-app01-centos
as-xx.xx.xx.xx-centos
は踏み台サーバ(a-bastion)、
as-app01-centos
はa-app01サーバに接続するためのソケットファイルです。
見てわかる通り、a-app01、b-app01にansibleを実行する際に作成されるソケットファイルが
同じ名前(as-app01-centos)になってしまっています。
つまり、ControlPersistで指定した時間内に、連続して異なる環境にansibleを実行すると
同名のソケットファイルが使われてしまい、別のプレイブックが適用されてしまいます。
今回の事象は、多段SSH構成で異なる環境の同じホスト名に対して接続する形になっていると
発生します。
通常は、control_pathでソケットファイル名がユニークになるように指定しますが、control_path
(sshオプションのControlPath)に使えるのは h, r以外にもp, l, Cなども指定できますが、
どれを使っても、ホスト名、ポート、ユーザ名が同じ場合はユニークにすることができませんでした。。 参考
回避策
ControlPersistを無効してソケットファイルが作成されないようにすれば一応解決しますが、
そうするとansible実行時間がかなり遅くなるので、無効化はしたくない、ですよね。
ということで、下記のようにして回避しました。
各インベントリファイルの[all:vars]に、
env_id=hogehoge # ←環境固有の文字列
ansible_ssh_extra_args='-o ControlPath=~/.ansible/cp/{{env_id}}-%h-%r'
を追記して、ソケットファイル名をユニークにしました!!