Terraform Azure虚拟机SSH密钥

3

我是 Terraform 的新手,希望能得到一些帮助。我已经成功创建了一个虚拟机,并且可以手动 SSH 进入它,没有任何问题。但是,我正在与团队一起开展项目,他们无法在不使 Terraform 删除所有资源并重新创建它们的情况下更改 Tf 文件。我认为这是因为他们拥有不同于我的 SSH 密钥。

admin_ssh_key {
   username = "azureroot"
   public_key = file("~/.ssh/id_rsa.pub")}

因为我的ssh密钥与我的团队成员不同,这会破坏虚拟机并使用执行terraform的人的密钥重新创建它。有没有办法解决这个问题?由于密钥不同,这已经导致多个虚拟机被销毁。


有几种方法可以解决这个问题。如果你们两个都在使用同一个用户,你可以将两个公钥合并在一起。这不是一个好主意,但是可行的。 另一个方法是通过 cloud-init,你可以添加用户和密钥,但是需要告诉 Azure waagent,并且在快照实例时可能会因为旧的用户数据而出现问题。我不明白为什么两个团队都在创建相同的资源。 - harshavmb
团队没有创建相同的资源。例如,如果我是第一个执行terraform apply的人,则我的密钥将与VM相关联。但是后来,我的队友需要修改入站/出站规则,并进行terraform plan,即使我们没有对其进行任何更改,它也会删除vm并重新启动一个新的。当我查看输出时,这是因为terraform检测到不同的密钥(因为我的密钥与我的团队不同)。 - python-noob
好的。在这种情况下,将两个键组合在一起。public_key -(必填)用于身份验证的公钥,必须至少为2048位并且采用ssh-rsa格式。更改此内容会强制创建新资源。 请参阅:https://www.terraform.io/docs/providers/azurerm/r/linux_virtual_machine.html - harshavmb
有关这个问题,是否有任何更新?它解决了你的问题吗? - Charles Xu
是的,你下面的回答有帮助!谢谢大家的参与。 - python-noob
如果这对你有用,请接受它作为答案,以帮助寻找此解决方案的其他社区成员,谢谢 :-) - Charles Xu
7个回答

2

2

问题出在虚拟机的配置上。看起来您使用了资源 azurerm_linux_virtual_machine 并将SSH密钥设置为:

admin_username      = "azureroot"
admin_ssh_key {
   username = "azureroot"
   public_key = file("~/.ssh/id_rsa.pub")
}

对于公钥,您可以使用函数file()从路径~/.ssh/id_rsa.pub在当前计算机上加载公钥。因此,当您在不同的计算机上时,可能是您的同事的计算机,那么公钥应该与您的不同。这就产生了问题。
我有两个建议给您。一个是使用静态公钥,例如:
admin_username      = "azureroot"
admin_ssh_key {
   username = "azureroot"
   public_key = "xxxxxxxxx"
}

无论在哪里执行Terraform代码,公钥都不会引起问题。您可以根据需要更改事物,例如NSG规则。


2
也许这会帮助那些和我遇到相同问题的人。
您可以使用Terraform配置语言生成新的私钥和公钥。以下是一个示例:
resource "tls_private_key" "example_ssh" {
    algorithm = "RSA"
    rsa_bits = 4096
}

resource "azurerm_linux_virtual_machine" "myterraformvm" {
    computer_name = "myvm"
    admin_username = "azureuser"
    disable_password_authentication = true

    admin_ssh_key {
        username = "azureuser"
        public_key = tls_private_key.example_ssh.public_key_openssh #The magic here
    }

    tags = {
        environment = "Terraform Demo"
    }
}

1

1

虽然对于持续访问,您应该拥有单独的用户/帐户,但在规划期间,您必须指定一个单一用户,作为VM管理员。
为了克服您和团队成员之间的不同秘密哈希,您可以生成一个新密钥,用于规划,与团队共享私钥,并将公钥存储在Azure KeyVault中。
然后,在构建Terraform VM时,从KeyVault提取公钥并使用它。

# Get existing Key Vault
data "azurerm_key_vault" "kv" {
  name                = "kv-dev-mgmt"
  resource_group_name = "rg-master"
}
# Get existing Key
data "azurerm_key_vault_key" "ssh_key" {
  name         = "dev-mgmt-ssh-key"
  key_vault_id = data.azurerm_key_vault.kv.id
} 

# Create a VM
resource "azurerm_linux_virtual_machine" "main" {
  name                            = .....
  resource_group_name             = .....
  location                        = .....
  size                            = .....
  admin_username                  = "adminuser"
  admin_ssh_key {
    username = "adminuser"
    public_key = data.azurerm_key_vault_key.ssh_key.public_key_openssh
  }
  disable_password_authentication = true

请参考https://isbyr.com/how-to-use-an-ssh-key-stored-in-azure-key-vault-while-building-azure-linux-vms-using-terraform/,了解逐步说明。

0

您可以将每个人的公钥添加到用于创建根SSH密钥的同一文件中。这是务实的方法,但不应作为标准推广。 为了最佳实践,您应该将每个用户作为单独的实体添加,以便我们的配置管理系统可以创建他们的用户和公钥,然后他们可以作为自己的用户登录并根据需要提升权限。


这不会起作用,请参见 https://github.com/hashicorp/terraform-provider-azurerm/issues/652 - Shawn Cicoria

0
解决这个问题的一种方法是在Terraform中使用azurerm_ssh_public_key数据源来访问在Terraform之外创建的SSH公钥。以下是代码的示例:
data "azurerm_ssh_public_key" "SshPublicKey" {
  name                = "ssh_key_name"
  resource_group_name = "rg_name"
}

azurerm_linux_virtual_machine资源内部:
admin_ssh_key {
    username   = "adminuser"
    public_key = data.azurerm_ssh_public_key.SshPublicKey.public_key
  }

如果您和您的团队成员在上述数据块中引用相同的SSH密钥,您的问题应该会得到解决。
请注意,不建议使用tls_private_key资源来创建SSH密钥,因为此资源生成的私钥将以未加密的形式存储在您的Terraform状态文件中。相反,建议在Terraform之外生成一个私钥文件,并使用上述数据源在您的Terraform配置文件中访问它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接