はじめに

私は http://qiita.com/nekogeruge_987/items/836a75960e0ad1f00b67 のコメントに以下のように書いた。

ansible all -i 10.0.2.190,10.0.2.191,10.0.2.192,10.0.2.193 -m ping -c paramiko -kと実行してみましたが、インベントリファイルなし、SSH鍵の用意なし、.ssh/known_hostsに未登録の状態で実行に成功しました。

これはつまり、何の用意もなくAnsibleをインストールするだけで、ansibleコマンドを実行して他のコンピュータを操作することができる、ということである。

Ansibleを使うのにインベントリファイルを作るだのSSH鍵を作るだの、ついでにプレイブックを作るだのが微妙な心理的障壁になる、というのは理解できる感覚である。
ところが、上記コマンドのように実行することでこれを取り払うことができる。

以下ではこれでなぜ実行できるのかを解説するが、理屈が不要なら読まずに上記コマンドをホスト名と実行するモジュールの部分だけ変えて実戦投入すると良い。

私の書く文章としてはこちらでlocalhostのみ、としていたことが他コンピュータにも可能だった、というものになる。この旧文章はansibleコマンド1回で具体的にどんなことができるのか、を知るには参考になるかと思う。

各引数の説明

-iオプション

-iオプションはインベントリファイルを指定するオプションとして知られている。
しかし同じコメントに以下のように書いた。

-iの値にカンマを含む場合、カンマを区切り文字にしたリストをホスト名を列挙したインベントリとして扱うようです。

-iオプションには何を指定するとどのようになるのかをソースから確認してみる。主に見るのは libansibleinventory__init__.py である。バージョンは1.8.2のものを見ている。

まず-iオプションに指定した値として、カンマ(,)が入っているかどうかが判定の基準となる。
カンマが入っているとカンマを区切り文字として分割し、それぞれをallグループに所属するホスト名として扱うようになる。
分割した後、前後の空白文字は除去される。除去された後何も残らなければそれはホスト名扱いされず無視される。
したがって、操作対象のホストが1つだけの場合はそのホスト名の前か後ろにカンマを付ければよい。

なお、分割されたそれぞれの文字列の中に1つだけコロン(:)を含む場合はコロン以前をホスト名、以降をポート番号として扱う。
2つ以上コロンを含む場合はIPv6のアドレスとみなしホスト名扱いとなる。
IPv6でかつポート番号を指定する場合はアドレス部分を[]で囲む必要がある。

本題とは関係ないが、-iオプションの値としてカンマが入っていない場合パスを指定することになる。このパスは存在していなければならない。パスの種類によって以下のように処理が変化する。

  • 所有者、グループ、その他ユーザのいずれかに実行権限が与えられたファイル
    実行され、標準出力に出力されたJSONによってインベントリを形成する。(Dynamic Inventory)

  • それ以外のファイル
    通常のインベントリファイルとして処理される。

  • ディレクトリ
    ディレクトリ内の各ファイル/ディレクトリについて、ファイル名/ディレクトリ名が脚注1のものを除き、それぞれに「実行権限が与えられたファイル」か「それ以外のファイル」か「ディレクトリ」かの処理を行う。

-cオプションと-kオプション

-c paramiko -kの部分について。

-cオプションは対象のコンピュータへの接続方法を指定するオプションである。
-cオプションの指定がない場合、デフォルト設定では-c smartとなる。
そして-c smartの場合、接続相手のSSHサーバでOpenSSHのControlPersist機能が利用できる場合は-c sshとして扱い、ControlPersist機能が利用できなければ-c paramikoとして扱う。

ControlPersist機能が利用できない接続相手として代表的だったのが、6.5までのRHEL 6(およびCentOS 6などのRHEL派生)だが、6.6のOpenSSHにはControlPersist機能がバックポートされており、それ以降のOpenSSHを使用すれば-c smart-c sshとなる。
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/6.6_Technical_Notes/openssh.html

一方、-kオプションはSSHパスワードの入力を実行後に行うようにするためのオプションである。この文章の趣旨としてSSH鍵の準備もしたくないので必要になる。
-c sshである場合、-kオプションと共に使用するとsshpassを通して実行されることになるが、sshpassは~/.ssh/known_hostsに登録されている相手にしか接続できない。
これはAnsible関係なく~/.ssh/known_hostsに登録されていない相手にsshpass -p <password> ssh <user>@<hostname>を実行すればSSHログインできないのでわかる。

-c paramikoの場合は、-kオプションと共に使用してもsshpassは使用しないし、~/.ssh/known_hostsに未登録でも登録するかを聞いてくる(ただし、~/.ssh/known_hostsが存在しないと登録に失敗するようで、ansibleコマンド実行には成功しても次回実行時に再度聞いてくる)。

そのため、SSH鍵を用意しない、~/.ssh/known_hostsにも未登録の状態でAnsibleの実行を成功させるためには-c paramiko -kと指定する必要がある。

all

インベントリの中からどのホストを対象にするか、である。
-iオプションで説明した通り、カンマ区切りで-iオプションに指定したホストはallグループに所属する。
したがってここに指定するのはallとなる。

もしプレイブックを作るのなら、hostsにはall以外に各ホストなどを指定することもありえるだろう。



  1. 隠しファイル(”.”で始まるファイル)、”~”,”.orig”,”.bak”,”.ini”,”.retry”,”.pyc”,”.pyo”のいずれかで終わるファイル、”host_vars”,”group_vars”,”vars_plugins”という名前のファイル。いずれもディレクトリでも同様 

TOP