使用Terraform与Azure VM建立SSH连接

时间:2017-07-09 14:08:55

标签: linux azure terraform

我已使用Terraform在Azure上成功创建了一个VM作为资源组的一部分。下一步是在新机器中ssh并运行一些命令。为此,我创建了一个配置器作为VM资源的一部分并建立了SSH连接:

resource "azurerm_virtual_machine" "helloterraformvm" {
    name = "terraformvm"
    location = "West US"
    resource_group_name = "${azurerm_resource_group.helloterraform.name}"
    network_interface_ids = ["${azurerm_network_interface.helloterraformnic.id}"]
    vm_size = "Standard_A0"

    storage_image_reference {
        publisher = "Canonical"
        offer = "UbuntuServer"
        sku = "14.04.2-LTS"
        version = "latest"
    }


    os_profile {
        computer_name = "hostname"
        user     = "some_user"
        password = "some_password"
    }

    os_profile_linux_config {
        disable_password_authentication = false
    }

    provisioner "remote-exec" {
        inline = [
          "sudo apt-get install docker.io -y"
        ]
        connection {
          type     = "ssh"
          user     = "some_user"
          password = "some_password"
        }
    }

}

如果我运行“terraform apply”,它似乎进入无限循环尝试ssh失败,反复重复此日志:

azurerm_virtual_machine.helloterraformvm (remote-exec): Connecting to remote host via SSH...
azurerm_virtual_machine.helloterraformvm (remote-exec):   Host:
azurerm_virtual_machine.helloterraformvm (remote-exec):   User: testadmin
azurerm_virtual_machine.helloterraformvm (remote-exec):   Password: true
azurerm_virtual_machine.helloterraformvm (remote-exec):   Private key: false
azurerm_virtual_machine.helloterraformvm (remote-exec):   SSH Agent: true

我确定我做错了什么,但我不知道它是什么:(

编辑:

我已经尝试在没有配置程序的情况下设置此计算机,并且我可以使用给定的用户名/密码来SSH连接到它。但是我需要在Azure门户中查找主机名,因为我不知道如何从Terraform中检索它。可疑日志中的“Host:”行是空的,所以我想知道它是否与此有关?

更新:

我尝试过不同的事情,例如在与

的连接中指明主机名
host = "${azurerm_public_ip.helloterraformip.id}" 

host = "${azurerm_public_ip.helloterraformips.ip_address}"

如文档中所示,但没有成功。

我也尝试过使用ssh-keys而不是密码,但是同样的结果 - 无限循环的连接尝试,没有明确的错误消息,因为它没有连接。

2 个答案:

答案 0 :(得分:5)

我已成功完成这项工作。我改变了几件事:

  • 将主机名称设为connection
  • 正确配置SSH密钥 - 它们需要未加密。
  • connection元素中取出provisioner元素。

这是完整的Terraform文件,替换SSH密钥等数据:

# Configure Azure provider
provider "azurerm" {
  subscription_id = "${var.azure_subscription_id}"
  client_id       = "${var.azure_client_id}"
  client_secret   = "${var.azure_client_secret}"
  tenant_id       = "${var.azure_tenant_id}"
}

# create a resource group if it doesn't exist
resource "azurerm_resource_group" "rg" {
    name = "sometestrg"
    location = "ukwest"
}

# create virtual network
resource "azurerm_virtual_network" "vnet" {
    name = "tfvnet"
    address_space = ["10.0.0.0/16"]
    location = "ukwest"
    resource_group_name = "${azurerm_resource_group.rg.name}"
}

# create subnet
resource "azurerm_subnet" "subnet" {
    name = "tfsub"
    resource_group_name = "${azurerm_resource_group.rg.name}"
    virtual_network_name = "${azurerm_virtual_network.vnet.name}"
    address_prefix = "10.0.2.0/24"
    #network_security_group_id = "${azurerm_network_security_group.nsg.id}"
}

# create public IPs
resource "azurerm_public_ip" "ip" {
    name = "tfip"
    location = "ukwest"
    resource_group_name = "${azurerm_resource_group.rg.name}"
    public_ip_address_allocation = "dynamic"
    domain_name_label = "sometestdn"

    tags {
        environment = "staging"
    }
}

# create network interface
resource "azurerm_network_interface" "ni" {
    name = "tfni"
    location = "ukwest"
    resource_group_name = "${azurerm_resource_group.rg.name}"

    ip_configuration {
        name = "ipconfiguration"
        subnet_id = "${azurerm_subnet.subnet.id}"
        private_ip_address_allocation = "static"
        private_ip_address = "10.0.2.5"
        public_ip_address_id = "${azurerm_public_ip.ip.id}"
    }
}

# create storage account
resource "azurerm_storage_account" "storage" {
    name = "someteststorage"
    resource_group_name = "${azurerm_resource_group.rg.name}"
    location = "ukwest"
    account_type = "Standard_LRS"

    tags {
        environment = "staging"
    }
}

# create storage container
resource "azurerm_storage_container" "storagecont" {
    name = "vhd"
    resource_group_name = "${azurerm_resource_group.rg.name}"
    storage_account_name = "${azurerm_storage_account.storage.name}"
    container_access_type = "private"
    depends_on = ["azurerm_storage_account.storage"]
}



# create virtual machine
resource "azurerm_virtual_machine" "vm" {
    name = "sometestvm"
    location = "ukwest"
    resource_group_name = "${azurerm_resource_group.rg.name}"
    network_interface_ids = ["${azurerm_network_interface.ni.id}"]
    vm_size = "Standard_A0"

    storage_image_reference {
        publisher = "Canonical"
        offer = "UbuntuServer"
        sku = "16.04-LTS"
        version = "latest"
    }

    storage_os_disk {
        name = "myosdisk"
        vhd_uri = "${azurerm_storage_account.storage.primary_blob_endpoint}${azurerm_storage_container.storagecont.name}/myosdisk.vhd"
        caching = "ReadWrite"
        create_option = "FromImage"
    }

    os_profile {
        computer_name = "testhost"
        admin_username = "testuser"
        admin_password = "Password123"
    }

    os_profile_linux_config {
      disable_password_authentication = false
      ssh_keys = [{
        path     = "/home/testuser/.ssh/authorized_keys"
        key_data = "ssh-rsa xxx email@something.com"
      }]
    }

    connection {
        host = "sometestdn.ukwest.cloudapp.azure.com"
        user = "testuser"
        type = "ssh"
        private_key = "${file("~/.ssh/id_rsa_unencrypted")}"
        timeout = "1m"
        agent = true
    }

    provisioner "remote-exec" {
        inline = [
          "sudo apt-get update",
          "sudo apt-get install docker.io -y",
          "git clone https://github.com/somepublicrepo.git",
          "cd Docker-sample",
          "sudo docker build -t mywebapp .",
          "sudo docker run -d -p 5000:5000 mywebapp"
        ]
    }

    tags {
        environment = "staging"
    }
}

答案 1 :(得分:1)

根据您的说明,Azure Custom Script Extension是您的选择。

  

自定义脚本扩展在Azure上下载并执行脚本   虚拟机。此扩展对于部署后非常有用   配置,软件安装或任何其他配置/   管理任务。

删除provisioner "remote-exec"而不是以下内容:

resource "azurerm_virtual_machine_extension" "helloterraformvm" {
  name                 = "hostname"
  location             = "West US"
  resource_group_name  = "${azurerm_resource_group.helloterraformvm.name}"
  virtual_machine_name = "${azurerm_virtual_machine.helloterraformvm.name}"
  publisher            = "Microsoft.OSTCExtensions"
  type                 = "CustomScriptForLinux"
  type_handler_version = "1.2"

  settings = <<SETTINGS
    {
        "commandToExecute": "apt-get install docker.io -y"
    }
SETTINGS
}

注意:命令由root用户执行,请勿使用sudo

更多信息请参阅此链接:azurerm_virtual_machine_extension

有关可能的扩展名列表,您可以使用Azure CLI命令az vm extension image list -o table

更新:以上示例仅支持单个命令。如果需要多个命令。就像在VM上安装docker一样,你需要

apt-get update 
apt-get install docker.io -y  

将其另存为名为script.sh的文件,并将其保存到Azure存储帐户或GitHub(该文件应该是公共的)。修改如下的terraform文件:

 settings = <<SETTINGS
    {
        "fileUris": ["https://gist.githubusercontent.com/Walter-Shui/dedb53f71da126a179544c91d267cdce/raw/bb3e4d90e3291530570eca6f4ff7981fdcab695c/script.sh"],
        "commandToExecute": "sh script.sh"
    }
SETTINGS