Я пишу программу, которая использует Terraform для создания экземпляра виртуальной машины на Amazon EC2, а затем запускает сценарий Ansible в экземпляре для дальнейшей настройки. Программа выполняет следующие действия:
- Создание пары открытого и секретного ключей RSA
- С помощью модуля
subprocess
python запустите terraform apply
для подготовленного файла json, передав сгенерированный открытый ключ и другую информацию.
- Захватить имя хоста из выходных данных этого вызова
- Используйте
subprocess
для запуска книги воспроизведения Ansible, ориентированной на этот хост, и с учетом сгенерированного закрытого ключа.
Однако сценарию Ansible не удается подключиться к хосту. Сообщение об ошибке подразумевает, что виноваты ключевые проблемы:
ec2-user@ec2-XX-XXX-XX-XXX.compute-1.amazonaws.com: Permission denied (publickey).
но после двойной проверки открытого ключа, использованного для создания экземпляра, и закрытого ключа, используемого для подключения, я подтвердил, что они совпадают. У меня такое чувство, что проблема в кодировке, но я мог бы помочь выяснить, где.
Я могу подтвердить, что виртуальные машины созданы успешно - я вижу их в консоли EC2.
Следующий метод - это генерирование пары ключей:
def generate_ssh_key():
key = rsa.generate_private_key(
backend=crypto_default_backend(),
public_exponent=65537,
key_size=2048)
private_key = key.private_bytes(
crypto_serialization.Encoding.PEM,
crypto_serialization.PrivateFormat.PKCS8,
crypto_serialization.NoEncryption())
public_key = key.public_key().public_bytes(
crypto_serialization.Encoding.OpenSSH,
crypto_serialization.PublicFormat.OpenSSH)
return str(public_key, "utf-8"), str(private_key, "utf-8")
Соответствующие строки в моем файле aws.tf.json
:
"resource": {
"aws_key_pair": {
"generated_key": {
"key_name": "aws-key-${var.id}",
"public_key": "${var.public_key}"
}
}
},
"resource": {
"aws_instance": {
"vm": {
...
"key_name": "${aws_key_pair.generated_key.key_name}",
...
}
}
}
где id
и public_key
были переданы как переменные в командной строке. aws_key_pair
не было.
Аргументы subprocess
для terraform apply
выглядят так:
['terraform', 'apply', '-auto-approve', '-var', 'public_key=ssh-rsa AAAA...', '-var', 'user_id=...', '-var', 'access_key=...', '-var', 'secret_key=...']
И аргументы subprocess
для ansible-playbook
выглядят так (я использую tempfile
для печати закрытого ключа. Я пытался записать его в tempfile в режиме w
и режиме wb
, и ни один не работал):
['ansible-playbook', '--private-key=/path/to/tempfile.pem', '-i', 'ec2-XX-XXX-XX-XX.compute-1.amazonaws.com,', '-e', 'hostname=ec2-XX-XXX-XX-XX.compute-1.amazonaws.com', '-e', ...]
Большая часть кода, задействованного в этом (большая часть терраформ), была написана моими товарищами по команде, поэтому я не совсем понимаю, как все это работает. Если мне нужно что-то еще предоставить, я постараюсь найти это