サーバがだいたい CentOS 5/6 でsshの設定においてSFTPがオフになっていると、ansibleを使おうとしたときにいきなりファイル転送ができなくてハマる。
まず第一に、RHEL6およびそれ以前において OpenSSH が ControlPersist オプションをサポートしていないため、ansibleは paramiko というライブラリを使おうとする。
When using Enterprise Linux 6 operating systems as the control machine (Red Hat Enterprise Linux and derivatives such as CentOS), however, the version of OpenSSH may be too old to support ControlPersist. On these operating systems, Ansible will fallback into using a high-quality Python implementation of OpenSSH called ‘paramiko’.
Getting Started — Ansible Documentation
ところでansibleを使うとき、sshdの設定でSFTPが無効になっているとこんなエラーが出る。
FAILED => failed to open a SFTP connection (Channel closed.)
これは調べると以下のような設定をしろという情報がさくさく見付かる。*1
[ssh_connection] scp_if_ssh=True
のだが、これを作業用ディレクトリ ansible.cfg に書いても状況が変わらない。なぜだー、と思ったら、この paramiko はファイルの転送に必ずSFTPを使おうとするらしい。scp_if_sshを書いても見てくれない。
ということで通信に ssh を使うよう強制する必要がある。このとき先程の ControlPersist オプションが問題になる(ansibleがデフォルトでセットしている)ので、これを明示的に無効にしてやる必要がある。これは ssh_args に空の代入を行うことで実施する。
[defaults] transport=ssh [ssh_connection] ssh_args= scp_if_ssh=True
同等の設定を環境変数だけでやるには ANSIBLE_TRANSPORT=ssh ANSIBLE_SSH_ARGS="" ANSIBLE_SCP_IF_SSH=true を指定する。また ANSIBLE_TRANSPORT=ssh の指定は ansible -c ssh でも代用できる。
paramiko については @r_rudi さんに教えていただきました。ありがとうございます。
@tagomoris なにも指定しないと、paramikoというsshのpython実装が使われます。そして、どうもparamikoを使う場合は必ずsftpを使うようです。なので、opensshを使うように明示的に指定するといける、ということみたいです。
2014-03-18 13:27:34 via web to @tagomoris
かいけつ!