Я использую Packer для создания образов VirtualBox, а средство обеспечения Ansible - для настройки образов. На этапе построения создается временный пользователь ( ssh_username
и ssh_password
). Поставщик Ansible работает под этим временным пользователем. Я, конечно, хотите избавиться от этого пользователя после того, как он настроит более безопасного пользователя с открытым ключом. Поэтому я добавил второй шаг подготовки Ansible, который подключается как защищенный пользователь и удаляет незащищенного пользователя. По крайней мере, таков был план. Однако Ansible через упаковщик не может фактически подключиться к виртуальной машине с помощью этого метода.
Вот соответствующая часть файла packer.json:
"provisioners": [
{
"type": "ansible",
"playbook_file": "playbooks/image/image.yml",
"groups": [
"{{user `ansible_group`}}"
],
"user": "vagrant",
"extra_arguments": [
"--vault-password-file", "scripts/get-vault-password.sh",
"-e", "global_configuration_user={{user `configuration_user`}}",
"-e", "global_deployment_user={{user `deployment_user`}}",
"-e", "ansible_ssh_pass=vagrant",
"-vvvvv"
]
},
{
"type": "ansible",
"playbook_file": "playbooks/image/removeVagrant.yml",
"groups": [
"{{user `ansible_group`}}"
],
"user": "{{user `configuration_user`}}",
"extra_arguments": [
"--vault-password-file", "scripts/get-vault-password.sh",
"-e", "global_configuration_user={{user `configuration_user`}}",
"-e", "global_deployment_user={{user `deployment_user`}}",
"-e", "ansible_ssh_private_key_file=~/.ssh/id_{{user `configuration_user`}}_rsa",
"-vvvvv"
]
}
],
Первый шаг инициализации работает без проблем. Это второй сбой с отказом в разрешении. Ansible пытается выполнить следующую команду SSH:
ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=37947 -o 'IdentityFile="/home/redacted/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=redacted -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ControlPath=/home/redacted/.ansible/cp/ansible-ssh-%h-%p-%r 127.0.0.1 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo ~/.ansible/tmp/ansible-tmp-1491233126.24-276699777493633 `" && echo ansible-tmp-1491233126.24-276699777493633="` echo ~/.ansible/tmp/ansible-tmp-1491233126.24-276699777493633 `" ) && sleep 0'"'"''
Соответствующая часть вывода отладки SSH:
debug1: SSH2_MSG_NEWKEYS received
debug2: key: /home/redacted/.ssh/id_rsa, explicit, agent
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug3: send packet: type 5
debug3: receive packet: type 6
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug3: send packet: type 50
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey
debug3: start over, passed a different list publickey
debug3: preferred gssapi-with-mic,gssapi-keyex,hostbased,publickey
debug3: authmethod_lookup publickey
debug3: remaining preferred: ,gssapi-keyex,hostbased,publickey
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/redacted/.ssh/id_rsa
debug3: send_pubkey_test
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey
debug1: Offering RSA public key: key2
debug3: send_pubkey_test
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
Затем он продолжает пробовать оставшиеся ключи в моем каталоге .ssh
, которые все терпят неудачу, конечно. Первый, запрошенный, уже не сработал.
Я запустил Packer с -on-error = abort
, чтобы он оставил виртуальную машину включенной. Я попробовал использовать SSHing с той же командой и получил сообщение об ошибке в соединении. Я обнаружил, что причина этого в том, что он пытается подключиться к порту прокси-сервера SSH, который настраивает Пакер. Поэтому я использую фактический перенаправленный порт, который настроен на виртуальной машине Virtualbox, и соединение SSH успешно. Таким образом, похоже, что проблема заключается в прокси-сервере SSH. Однако я не уверен, как заставить его вести себя.
Я также пробовал использовать параметр ssh_authorized_key_file
( https://www.packer.io/docs/provisioners/ansible.html ) в моей конфигурации Packer для инициатора Ansible. В этом случае я получил сообщение об ошибке Packer о том, что ему не удалось проанализировать авторизованный ключ (исходный код находится здесь: https: // github. com / bhcleek / packer-provisioner-ansible / blob / master / provisioner / ansible / provisioner.go ). Он не сказал мне, в чем проблема. В документации Go для библиотеки SSH сказано, что это стандартный формат ключевого файла SSH. Или это моя лучшая интерпретация ( https://godoc.org/golang.org/x/crypto/ssh#ParseAuthorizedKey ).
У меня возникла эта проблема, и я не смог заставить SSH-прокси Packer работать успешно.
Чтобы упаковщик не создавал временный ключ, вам необходимо чтобы либо запечь «ключ инициализации» в AMI, либо он будет существовать в AWS заранее.
Если вы следуете варианту 1 - вам необходимо предоставить оба параметра ssh_private_key_file
в конфигурацию сборщика, как а также установить для ssh_agent_auth
значение true - например, так:
"ssh_username": "ubuntu",
"ssh_private_key_file": "../provision",
"ssh_agent_auth": true,
Если вы последуете варианту 2 - предоставьте построителю параметр ssh_keypair_name
.
В обоих случаях вам понадобится предоставить пользователя провайдеру Ansible, но указанная пара ключей должна использоваться вместо временной, генерируемой упаковщиком.
NB : когда я удалил пользователя из коробки с помощью инициатора Ansible, он вызвал сбой ansible. Я подозреваю, что это связано с тем, что невозможно установить доступное соединение с целевой машиной без прохождения через прокси, и невозможно указать пользователя прокси в провайдере. Мне нужно было выполнить «Удалить пользователя и выключить машину» за один асинхронный вызов.