首页 > 解决方案 > 无法连接到 Azure Linux 虚拟机

问题描述

我按照以下指南使用 Terraform 设置 Linux 虚拟机:

https://docs.microsoft.com/en-us/azure/developer/terraform/create-linux-virtual-machine-with-infrastructure

一切都在 Azure 中成功创建。我无法通过 ssh 进入虚拟机的最后一步。我在 Windows powershell 中使用以下命令:

ssh azureuser@public_ip_here

它给了我以下错误:

azureuser@52.186.144.190: Permission denied (publickey).

我尝试通过下载 RDP 文件并将其导入 RDP 来使用 Azure 门户中的 RDP 文件,但出现以下错误:

也不适用于 RDP

我尝试过的事情:

  1. 如上使用普通的 ssh 命令
  2. 尝试将私钥放在 .pem 文件中并为其分配受限权限。然后使用 ssh -i 命令传递此密钥。这也不起作用
  3. 使用从 Azure 门户下载的 RDP 文件(错误如下所示)
  4. 在 Azure 门户中运行虚拟机的测试连接功能,显示连接成功,但我仍然无法访问 VM。

我想知道我是否必须以某种方式配置 Azure 门户以允许自己能够在 VM 中进行 ssh。

我的 main.tf 代码是:

provider "azurerm" {
    # The "feature" block is required for AzureRM provider 2.x. 
    # If you're using version 1.x, the "features" block is not allowed.
    version = "~>2.0"
    features {}
}

resource "azurerm_resource_group" "myterraformgroup" {
    name     = "myResourceGroup"
    location = "eastus"

    tags = {
        environment = "Terraform Demo"
    }
}

resource "azurerm_virtual_network" "myterraformnetwork" {
    name                = "myVnet"
    address_space       = ["10.0.0.0/16"]
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name

    tags = {
        environment = "Terraform Demo"
    }
}

resource "azurerm_subnet" "myterraformsubnet" {
    name                 = "mySubnet"
    resource_group_name  = azurerm_resource_group.myterraformgroup.name
    virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
    address_prefixes       = ["10.0.1.0/24"]
}

resource "azurerm_public_ip" "myterraformpublicip" {
    name                         = "myPublicIP"
    location                     = "eastus"
    resource_group_name          = azurerm_resource_group.myterraformgroup.name
    allocation_method            = "Dynamic"

    tags = {
        environment = "Terraform Demo"
    }
}

resource "azurerm_network_security_group" "myterraformnsg" {
    name                = "myNetworkSecurityGroup"
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name

    security_rule {
        name                       = "SSH"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "22"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
    }

    tags = {
        environment = "Terraform Demo"
    }
}

resource "azurerm_network_interface" "myterraformnic" {
    name                      = "myNIC"
    location                  = "eastus"
    resource_group_name       = azurerm_resource_group.myterraformgroup.name

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = azurerm_subnet.myterraformsubnet.id
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = azurerm_public_ip.myterraformpublicip.id
    }

    tags = {
        environment = "Terraform Demo"
    }
}

resource "azurerm_network_interface_security_group_association" "example" {
    network_interface_id      = azurerm_network_interface.myterraformnic.id
    network_security_group_id = azurerm_network_security_group.myterraformnsg.id
}

resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.myterraformgroup.name
    }

    byte_length = 8
}

resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = azurerm_resource_group.myterraformgroup.name
    location                    = "eastus"
    account_tier                = "Standard"
    account_replication_type    = "LRS"

    tags = {
        environment = "Terraform Demo"
    }
}

resource "tls_private_key" "example_ssh" {
  algorithm = "RSA"
  rsa_bits = 4096
}
output "tls_private_key" { value = tls_private_key.example_ssh.private_key_pem }

resource "azurerm_linux_virtual_machine" "myterraformvm" {
    name                  = "myVM"
    location              = "eastus"
    resource_group_name   = azurerm_resource_group.myterraformgroup.name
    network_interface_ids = [azurerm_network_interface.myterraformnic.id]
    size                  = "Standard_DS1_v2"

    os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        storage_account_type = "Premium_LRS"
    }

    source_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "18.04-LTS"
        version   = "latest"
    }

    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
    }

    boot_diagnostics {
        storage_account_uri = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
    }

    tags = {
        environment = "Terraform Demo"
    }
}

任何帮助/指针将不胜感激!

标签: azurevirtual-machineazure-virtual-machine

解决方案


经过我的验证,您可以将输出的私人 pem 密钥保存到key.pem主目录中命名的文件中。例如,C:\Users\username\在 Windows 10 或/home/username/Linux 中。

在此处输入图像描述

然后,您可以通过 shell 中的命令访问 Azure VM。

ssh -i "C:\Users\username\key.pem"  azureuser@23.x.x.x

结果

在此处输入图像描述

此外,由tls_private_key生成的私钥将不加密地存储在您的 Terraform 状态文件中。建议在 Terraform 之外生成一个私钥文件,并将其安全地分发到将运行 Terraform 的系统。

您可以在 Windows 10 的 PowerShell 中使用ssh-keygen在客户端计算机上创建密钥对。密钥对保存在目录C:\Users\username\.ssh中。

例如,您可以使用 Terraform 函数文件将公钥发送到 Azure VM:

admin_ssh_key {
    username       = "azureuser"
    public_key     = file("C:\\Users\\someusername\\.ssh\\id_rsa.pub")     
    #tls_private_key.example_ssh.public_key_openssh
}

推荐阅读