SSH
Ansible
AnsibleDay 13

踏み台経由でAnsibleを実行する


はじめに

こちらはAnsible Advent Calender 2018 13日目の記事です。

この記事では、Ansibleの実行対象が踏み台サーバの向こう側に存在する場合の、Ansibleの実行方法について記載します。


Ansibleの仕組みのおさらい

AnsibleではSSHで対象サーバに入り、Pythonのスクリプトを実行することでサーバの状態を管理します。

そこで踏み台サーバ経由でAnsibleを実行するには多段SSHの仕組みを使います。


実行環境

以下の図のような環境を想定します。

ansible-bastion.002.jpg

上記のサーバに対し予め、


  • Ansible実行サーバ -> 踏み台サーバの公開鍵認証でのSSH設定

  • 踏み台サーバ -> 実行対象サーバへの公開鍵認証でのSSH設定

を設定し、Ansible実行サーバの秘密鍵(id_rsa)と踏み台サーバの秘密鍵(id_rsa.bastion)をAnsible実行サーバにもたせておきます。

また、踏み台サーバの設定ができるかを確認するため、事前にcontroller -> targetに直接通信できないことを確認しておきます。

vagrant@controller:~$ cat host_list

bastion
target

vagrant@controller:~$ ansible -m shell -a "uname -n" -i host_list target
target | UNREACHABLE! => {
"changed": false,
"msg": "ERROR! SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue",
"unreachable": true
}


多段SSHの設定

Ansibleで多段SSHを行うには、大きく以下の2パターンがあるためそれぞれ設定の仕方を記載します。


  • OSレベルでの設定

  • Ansibleでの設定


OSレベルの設定

OSのSSHのconfig (~/.ssh/config, /etc/ssh/configなど)に多段SSHの設定を入れておくことで、Ansibleがその設定を読み込んで多段SSHを実行できます。

しかし、OSのSSH設定を変更すると、Ansible以外のプログラムにも影響を与える点に注意してください。

実際の設定例としては以下のようになります。

vagrant@controller:~/.ssh$ cat config

Host bastion
User vagrant
IdentityFile ~/.ssh/id_rsa

Host target
User vagrant
IdentityFile ~/.ssh/id_rsa.bastion
ProxyCommand ssh -W %h:%p bastion

この状態で実行し、通信が通ることを確認します。

vagrant@controller:~$ ansible -m shell -a "uname -n" -i host_list target

target | SUCCESS | rc=0 >>
target


Ansibleで設定

上記で説明した通り、OSレベルで設定すると、他のSSHを使うプログラムにも影響を与えてしまいます。

Ansibleの実行のみ多段SSHをしたいのであれば、こちらで設定した方が良いかもしれません。

ansible.cfg の動作を確認するために上記で設定した ~/.ssh/config は消して繋がらない状態にしておきます。

vagrant@controller:~$ ansible -m shell -a "uname -n" -i host_list target

target | UNREACHABLE! => {
"changed": false,
"msg": "ERROR! SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue",
"unreachable": true
}

では ansible.cfg に設定してみます。

内容としては、基本的に ~/.ssh/config で設定したものを ansible.cfg に書くだけです。上記と同様の設定を ansible.cfg に記載すると以下のようになります。

[ssh_connection]

ssh_args = -o ProxyCommand="ssh -i ~/.ssh/id_rsa bastion -W %h:%p" -i ~/.ssh/id_rsa.bastion

また、これと同様の設定を環境変数(ANSIBLE_SSH_ARGS)で設定しておくこともできます。

vagrant@controller:~$ export ANSIBLE_SSH_ARGS='-o ProxyCommand="ssh -i ~/.ssh/id_rsa bastion -W %h:%p" -i ~/.ssh/id_rsa.bastion'

上記の設定をした状態で実行すると、以下のように繋がることが確認できます。

vagrant@controller:~$ ansible -m shell -a "uname -n" -i host_list target

target | SUCCESS | rc=0 >>
target

ちなみに ansible.cfg の設定は、以下のような優先順位で読み込まれます。


  • ANSIBLE_CONFIG (環境変数)

  • ansible.cfg (カレントディレクトリ)

  • ~/ansible.cfg (ホームディレクトリ)

  • /etc/ansible/ansible.cfg

例えば、Playbookによって設定を変えたい、というような場合だとPlaybookごとに ansible.cfg をもたせて設定しておくと良いです。


おわりに

Ansible Advent Calender 12日目 の記事を見て、自分もOSSにコントリビュートしてみたいなぁ、とぼんやり思いました。来年は「Ansibleのモジュール作ってコントリビュートしてみた」という記事がかけるように頑張りたい…


参考記事