Ansible 踏み台経由のサーバ接続

たまに接続制限されたサーバの構築が必要になって、いわゆる踏み台サーバ経由で作業を行なうわけですが、そういう時にAnsibleでも操作を簡単にできるようにするためのやり方をおさらいしてみます。

前置き

踏み台サーバ名: step-srv
実際に操作したいサーバ名: target-srv

Ansible実行環境
macOS: 10.11.6
ansible: 2.2.0.0

Ansible で踏み台サーバにつなげる

まずは、踏み台サーバにつなげる準備から。

SSHの設定やAnsibleの設定を調整していくのですが、システム側の設定ファイルをいじらない形にします。
各所にばらつくよりも、Playbookを書く場所に各種設定ファイルがひとまとめになっていた方が色々と都合良いので。

ssh_config その1

step-srv用のSSHの設定を書きます。書き方は、~/.ssh/configと同じ。

ひとまず、下記のように記載。

ServerAliveInterval 10

Host step-srv
  HostName XXX.XXX.XXX.XXX
  User root
  Port 4022
  IdentityFile ~/.ssh/step-srv.pem

パラメータは、各自の環境に合わせて調整をしてください。
ここでは、上記のようなパラメータでstep-srvにSSH接続できるようにします。

では、この設定をAnsibleから利用できるようにしましょう。

ansible.cfg

Ansibleは、コマンド実行時のカレントディレクトリにansible.cfgというファイルがあると、設定をそちらから読み込んでくれます。
こちらのファイルに、SSH接続関連の設定として下記の内容を記載します。

[ssh_connection]
control_path = %(directory)s/%%h-%%r
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -F ssh_config

control_pathは、SSH設定のControlPathと等価です。
これは、Ansibleのように同じサーバに何度もSSH接続・コマンド実行を行なう場合に効率化を図る機能で利用されます。
設定内容については、ドキュメントにあるものを参考にしたものです。

ssh_argsは、sshコマンド実行時の引数の指定になります。
こちらはドキュメントに記載のデフォルトに加えて-F ssh_configとすることで、先に記載したssh_configの中身をAnsibleから利用できるようにしています。

まずは、こちらで踏み台であるstep-srvに接続できることを確認します。

確認

Inventoryファイルとして、下記hostsファイルも準備します。

step-srv

では、実行してみましょう。

$ ansible step-srv -i hosts -m ping
step-srv | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
$

無事に、ssh_configで定義したホスト名step-srvに対してAnsibleが実行可能となりました。

実際に操作したいサーバにつなげる

次に、本当のターゲットとなるtarget-srvを操作する準備を進めます。

ssh_config その2

ServerAliveInterval 10

Host step-srv
  HostName XXX.XXX.XXX.XXX
  User root
  Port 4022
  IdentityFile ~/.ssh/step-srv.pem

Host target-srv
  HostName 10.3.0.88
  User root
  IdentityFile ~/.ssh/target-srv.pem
  ProxyCommand ssh -F ssh_config -W %h:%p step-srv

9-13行目のハイライトされている箇所が今回の追加分、ターゲットサーバの情報になります。
ここでは、特に13行目のProxyCommandに注目してください。
ansible.cfgで書いたのと同じですが、-F ssh_configがありますね。

つまり、自分自身であるssh_configを読み込む必要があります。
これを行なうことで、その後ろの踏み台サーバstep-srvの定義を有効にすることが可能となります。

確認

hostsファイルを下記のように編集しましょう。

step-srv
target-srv

編集できたら、target-srvに接続できるか実際にAnsibleを実行してみましょう。

$ ansible target-srv -i hosts -m ping
target-srv | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
$

無事に、ssh_configで定義したホスト名target-srvに対してAnsibleが実行可能となりました。

まとめ

ssh_config その2で記載したProxyCommandで-F ssh_configが無い記事が検索でヒットしてハマったことがあるので、ほぼ自分のために作った記事でした。

tacck
  • tacck
  • 北の大地の普通のソフトウェアエンジニア。
    インフラ・バックエンド・フロントエンドと、色々やります。

    初心者・若手向けのメンターも希望あればお受けします。

    勉強会運営中
    * ゆるWeb勉強会@札幌
    * スマートスピーカーで遊ぼう会@札幌