Packer + Ansible Provisioner実行時にbuilderへ接続エラーとなる場合の対処


Packer+Ansible(remote)の子ネタです。

概要

事象

packerでAnsible Provisioner を使用すると、builderに接続する際以下のようなエラーが発生する。

      [...]
==> amazon-ebs: Executing Ansible: ansible-playbook /Users/j-un/path/to/ansible-playbook/hoge.yml -i /var/folders/sk/hd789tls3hs_5zzqyxyqqw4d6_1mx1/T/packer-provisioner-ansible930583846 --private-key /var/folders/sk/hd789tls3hs_5zzqyxyqqw4d6_1mx1/T/ansible-key627107363
    amazon-ebs:
    amazon-ebs: PLAY [all] *********************************************************************
    amazon-ebs:
    amazon-ebs: TASK [setup] *******************************************************************
    amazon-ebs: SSH proxy: accepted connection
==> amazon-ebs: authentication attempt from 127.0.0.1:49925 to 127.0.0.1:49924 as ec2-user using none
==> amazon-ebs: authentication attempt from 127.0.0.1:49925 to 127.0.0.1:49924 as ec2-user using publickey
==> amazon-ebs: starting sftp subsystem
    amazon-ebs: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh", "unreachable": true}
    amazon-ebs:         to retry, use: --limit @/Users/j-un/path/to/ansible-playbook/hoge.retry
    amazon-ebs:
    amazon-ebs: PLAY RECAP *********************************************************************
    amazon-ebs: default                    : ok=0    changed=0    unreachable=1    failed=0
      [...]

再現環境

  • 各種バージョン情報

    • 実行環境:osx 10.11.6
    • 元イメージ:Amazon Linux AMI 2016.03.3
    • Packer 0.10.1
    • Ansible 2.1.1.0
  • Packerのテンプレートファイル抜粋

config.json
{
      [...]
  "builders": [{
    "type": "amazon-ebs",
    "source_ami": "ami-374db956",  # Amazon Linux AMI 2016.03.3
      [...]
  }],
  "provisioners" : [{
    "type" : "ansible",
    "user" : "ec2-user",
    "playbook_file" : "path/to/ansible-playbook/hoge.yml"
  }]
}

原因

sftp-serverコマンドのパスが違うことが原因だった。
下記ドキュメントに記載の通り、Ansible Provisionerはsftpを使用するとのこと("to transfer files"って具体的に何を?という点を実はまだ確認してない)。

https://www.packer.io/docs/provisioners/ansible.html#sftp_command

このパラメータのデフォルト値は /usr/lib/sftp-server -e ということだが、source_amiに指定したAmazon Linuxイメージの場合、このパスにsftp-serverコマンドが存在していないためエラーとなっていた。

対策

sftp_commandパラメータに、正しいsftp-serverのパスを設定する。

config.json
  "provisioners" : [{
    "type" : "ansible",
    "user" : "ec2-user",
    "sftp_command" : "/usr/libexec/openssh/sftp-server -e",
    "playbook_file" : "path/to/ansible-playbook/hoge.yml"
  }]

opensshは導入済みとして、基本的にはsshd_configにSubsystemとして指定されているsftp-serverコマンドを設定すればよい。

example
$ grep sftp /etc/ssh/sshd_config
Subsystem sftp  /usr/libexec/openssh/sftp-server

これに限らずsftpで待ち受け開始してくれるコマンドであれば何でもいいんじゃないかと思う。

補足

少し細かい調査記録

  • 冒頭に抜粋したログ出力だけでは何が起こっているか分からないので、デバッグログを出力してみる。packerコマンド実行時、以下のようにシェル変数を指定すると詳細なログが出力されるようになる。
$ PACKER_LOG=1 packer build -var-file=credential.json config.json

※参考: https://www.packer.io/docs/other/debugging.html

  • すると以下のような出力が得られる。
    remote command exited with '127': /usr/lib/sftp-server -e
    'exited with 127' ということで、コマンドがないらしい。
2016/08/26 13:04:59 ui: ==> amazon-ebs: starting sftp subsystem
==> amazon-ebs: starting sftp subsystem
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 opening new ssh session
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 starting remote command: /usr/lib/sftp-server -e
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 remote command exited with '127': /usr/lib/sftp-server -e
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 [INFO] RPC endpoint: Communicator ended with: 127
2016/08/26 13:04:59 [INFO] 54 bytes written for 'stderr'
2016/08/26 13:04:59 [INFO] 0 bytes written for 'stdout'
2016/08/26 13:04:59 [INFO] RPC client: Communicator ended with: 127
2016/08/26 13:04:59 [INFO] RPC endpoint: Communicator ended with: 127
2016/08/26 13:04:59 [INFO] 9 bytes written for 'stdin'
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 [INFO] 0 bytes written for 'stdout'
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 [INFO] 54 bytes written for 'stderr'
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 [INFO] RPC client: Communicator ended with: 127
2016/08/26 13:04:59 packer: 2016/08/26 13:04:59 [INFO] 9 bytes written for 'stdin'
2016/08/26 13:04:59 ui:     amazon-ebs: fatal: [default]: UNREACHABLE! => {"changed": false, "msg": "SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh", "unreachable": true}
  • そのため、正しいパスを確認してsftp_commandパラメータに設定してあげたら無事に動いた。