PackerのAnsible Provisioner利用時につまづいたところのメモ
PackerがリモートホストへのAnsible実行に対応しましたね!リリースノート。これまでもAnsible LocalというProvisionerはありましたが、構成管理の対象になるホストにAnsibleがインストールされてしまう問題がありました。今回追加されたAnsible Provisionerでは、そのような問題はありません。
この記事はAnsible ProvisionerでAMIを作成しようとした時につまづいたところのメモです。基本的な使い方を知りたい場合は、こちらの記事が参考になると思います。
次の環境で試しました。
- Ansible 2.0.0.2
- Packer 0.9.0
- ベースにするAMI Ubuntu 14.04
SSHに失敗する1
最初は、次のようなSSHエラーでつまづきました。
amazon-ebs: PLAY *************************************************************************** amazon-ebs: amazon-ebs: TASK [setup] ******************************************************************* amazon-ebs: fatal: [default]: 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} amazon-ebs: amazon-ebs: PLAY RECAP ********************************************************************* amazon-ebs: default : ok=0 changed=0 unreachable=1 failed=0
-vvvv
オプションを付けろとのことです。
Ansible Provisionerに次のパラメータを渡します。
"extra_arguments" : "-vvvv"
結果は次のようになりました。ディレクトリ名は一部書き換えてます。
amazon-ebs: PLAY *************************************************************************** amazon-ebs: amazon-ebs: TASK [setup] ******************************************************************* amazon-ebs: <127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: packer-ansible amazon-ebs: <127.0.0.1> SSH: EXEC ssh -C -vvv -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=57406 -o 'IdentityFile="/var/folders/9_/qdkghd2x2q5bw2hxyv1f0n7h0000gn/T/ansible-key551882343"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=packer-ansible -o ConnectTimeout=10 -o 'ControlPath=/Users/yagami/src/XXX/$HOME/.ansible/cp/ansible-ssh-%h-%p-%r' -tt 127.0.0.1 '( umask 22 && mkdir -p "$( echo $HOME/.ansible/tmp/ansible-tmp-1456648870.02-189603518951689 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1456648870.02-189603518951689 )" )' amazon-ebs: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "ERROR! SSH encountered an unknown error. The output was:\nOpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011\ndebug1: Reading configuration data /Users/yagami/.ssh/config\r\ndebug1: Reading configuration data /etc/ssh_config\r\ndebug1: /etc/ssh_config line 20: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\nControlPath too long\r\n", "unreachable": true} amazon-ebs: amazon-ebs: PLAY RECAP ********************************************************************* amazon-ebs: default : ok=0 changed=0 unreachable=1 failed=0
ControlPath too long
と言われてます。Ansible provisionerはSSH接続を共有して実行を高速化しているようです。このとき、接続の共有につかうUnixドメインソケットのパス名に108文字の上限があり、その上限に引っかかっているようです。
この問題はAnsibleのドキュメントにも書かれていて、control_path
設定を変更すればいいようです。Ansible Provisionerに次のパラメータを渡します。
"ansible_env_vars": [ "ANSIBLE_HOST_KEY_CHECKING=False", "ANSIBLE_CONTROL_PATH=%(directory)s/%%h-%%r" ]
ANSIBLE_HOST_KEY_CHECKING=False
はansible_env_vars
のデフォルト値なので、一緒に付けておきます。
amazon-ebs: PLAY *************************************************************************** amazon-ebs: amazon-ebs: TASK [setup] ******************************************************************* amazon-ebs: <127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: packer-ansible amazon-ebs: <127.0.0.1> SSH: EXEC ssh -C -vvv -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=58075 -o 'IdentityFile="/var/folders/9_/qdkg hd2x2q5bw2hxyv1f0n7h0000gn/T/ansible-key173226644"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o Passwor dAuthentication=no -o User=packer-ansible -o ConnectTimeout=10 -o ControlPath=/Users/yagami/.ansible/cp/ansible-ssh-%h-%p-%r -tt 127.0.0.1 '( umask 22 && mkdir -p "$( echo $H OME/.ansible/tmp/ansible-tmp-1456650315.25-37408588369242 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1456650315.25-37408588369242 )" )' amazon-ebs: SSH proxy: accepted connection
無事にSSH接続できたようです。
SSHに失敗する2
こちらの失敗をする人はあまりいないと思うのですが、一度つまづくと問題を見つけるのがなかなか大変な気がするので、残しておきます。
Ansibleはタスクを実行するとき、SFTPでモジュールを転送します。その転送がなぜか失敗する問題がありました。
次のようなエラーです。
amazon-ebs: PLAY *************************************************************************** amazon-ebs: amazon-ebs: TASK [setup] ******************************************************************* amazon-ebs: <127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: packer-ansible amazon-ebs: <127.0.0.1> SSH: EXEC ssh -C -vvv -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=58241 -o 'IdentityFile="/var/folders/9_/qdkghd2x2q5bw2hxyv1f0n7h0000gn/T/ansible-key726237014"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=packer-ansible -o ConnectTimeout=10 -o ControlPath=/Users/yagami/.ansible/cp/ansible-ssh-%h-%p-%r -tt 127.0.0.1 '( umask 22 && mkdir -p "$( echo $HOME/.ansible/tmp/ansible-tmp-1456650679.34-272153885545980 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1456650679.34-272153885545980 )" )' amazon-ebs: SSH proxy: accepted connection ==> amazon-ebs: authentication attempt from 127.0.0.1:58242 to 127.0.0.1:58241 as packer-ansible using none ==> amazon-ebs: authentication attempt from 127.0.0.1:58242 to 127.0.0.1:58241 as packer-ansible using publickey amazon-ebs: <127.0.0.1> PUT /var/folders/9_/qdkghd2x2q5bw2hxyv1f0n7h0000gn/T/tmp3kAuoj TO /home/ubuntu/.ansible/tmp/ansible-tmp-1456650679.34-272153885545980/setup amazon-ebs: <127.0.0.1> SSH: EXEC sftp -b - -C -vvv -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=58241 -o 'IdentityFile="/var/folders/9_/qdkghd2x2q5bw2hxyv1f0n7h0000gn/T/ansible-key726237014"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=packer-ansible -o ConnectTimeout=10 -o ControlPath=/Users/yagami/.ansible/cp/ansible-ssh-%h-%p-%r '[127.0.0.1]' ==> amazon-ebs: starting sftp subsystem amazon-ebs: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "ERROR! SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh", "unreachable": true} amazon-ebs: amazon-ebs: PLAY RECAP ********************************************************************* amazon-ebs: default : ok=0 changed=0 unreachable=1 failed=0
あまり参考にならないエラーメッセージですね。。
かなりハマった末に、Packerに渡すjsonファイルを一行ずつ消してみる、という方法を試したところ、amazon-ebs builderに渡している次のパラメータが問題になっていました。
"ssh_pty": true
以前、Shell Provisionerを使っていたAmazon Linuxを使っていた時の名残のコードです。この行を消すと、問題なく動きました。。。
まとめ
Ansible Provisionerを使った時につまづいたところのメモでした。お役に立てば幸いです。間違い等ありましたらコメントお願いします。