【问题标题】:Key Issues with AWS, Ansible, and TerraformAWS、Ansible 和 Terraform 的关键问题
【发布时间】:2019-04-08 04:25:23
【问题描述】:

我正在编写一个程序,它使用 Terraform 在 Amazon EC2 上创建一个 VM 实例,然后在该实例上运行一个 Ansible 脚本以进行进一步的配置。该程序执行以下操作:

  1. 生成 RSA 公钥/私钥对
  2. 通过python的subprocess模块,在准备好的json文件上运行terraform apply,传入生成的公钥等信息。
  3. 从该调用的输出中捕获主机名
  4. 使用subprocess 运行针对该主机的 Ansible playbook,并提供生成的私钥。

但是,Ansible 脚本无法连接到主机。错误消息暗示关键问题应归咎于:

ec2-user@ec2-XX-XXX-XX-XXX.compute-1.amazonaws.com: Permission denied (publickey).

但在仔细检查了用于生成实例的公钥和用于连接的私钥之后,我确认它们确实匹配。我感觉问题出在编码上,但我可以帮助找出问题所在。

我可以确认 VM 已成功创建 - 我可以在 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}",
       ...
     }
   }
 }

idpublic_key 在命令行中作为变量传入。 aws_key_pair 不是。


terraform applysubprocess 参数如下所示:

['terraform', 'apply', '-auto-approve', '-var', 'public_key=ssh-rsa AAAA...', '-var', 'user_id=...', '-var', 'access_key=...', '-var', 'secret_key=...']

ansible-playbooksubprocess 参数看起来像这样(我使用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', ...]

其中涉及的很多代码(大部分 terraform 的东西)都是由我的队友编写的,所以我不完全知道它是如何工作的。如果还有什么我需要提供的,我会尽力找到它

【问题讨论】:

  • 如果您尝试使用生成的密钥通过 SSH 连接到实例会发生什么?您要以什么用户身份通过​​ SSH 连接到实例?您的基础 AMI 是什么,例如。 Ubuntu/Amazon Linux 等?
  • 基础 AMI 是 Amazon Linux。我以ec2-user 身份登录,但随后将ansible 设置为become=true,以便它以root 身份运行所有内容。尝试使用与 ansible 脚本相同的临时文件手动 ssh 会产生相同的错误消息。
  • 检查变量public_key的内容一次。确保没有任何多余的空格,因为其他所有内容似乎都正确。
  • 不,根据terraform apply的输出,公钥中只有一个空格。私钥可能在末尾有一个额外的换行符,在 -----END PRIVATE KEY----- 行之后,但这会导致问题吗?
  • 您的 Python 代码不是一个完整的示例,因此很难看出您在这里可能做错了什么。出于好奇,您是否有理由像这样动态生成 SSH 密钥?您是否有理由不直接使用 Terraform 执行所有这些操作来生成像 this answer 中的 SSH 密钥并将 Ansible 作为 local-exec 配置器运行?或者甚至只是将其作为一个 shell 脚本来执行,而不是不断地在 Python 中执行任何有用的操作?

标签: python amazon-ec2 ansible terraform


【解决方案1】:

(OP)

原来问题一开始就错了。我使用了错误的用户帐户——虽然我曾期望 EC2 能够创建 amazon-linux 虚拟机,但我事先手动测试系统时他们就是这样做的,但我的队友实际上将它们设置为创建 ubuntu 虚拟机。所以我使用的用户名 ec2-user 是问题的原因 - 将其更改为 ubuntu 并且它工作(我的意思是我得到了一个不同的错误,但更容易调试)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-26
    • 2019-11-27
    • 2017-08-03
    • 1970-01-01
    • 2021-10-05
    • 2020-09-30
    • 2018-02-09
    • 1970-01-01
    相关资源
    最近更新 更多