gpt4 book ai didi

linux - 错误: host for provisioner cannot be empty

转载 作者:行者123 更新时间:2023-12-02 08:18:11 53 4
gpt4 key购买 nike

我正在处理 main.tf 文件,用于在 azure 中创建具有远程执行功能的虚拟机,并且我还想在此文件中创建并下载 SSH key .pem 文件以访问 Linux VM。

主要。 tf 文件

# Configure the Microsoft Azure Provider
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
}
}
provider "azurerm" {
features {}
subscription_id = var.subscription_id
client_id = var.client_id
client_secret = var.client_secret
tenant_id = var.tenant_id

}
# Create a resource group if it doesn't exist
resource "azurerm_resource_group" "myterraformgroup" {
name = var.resource_group
location = var.resource_group_location

tags = {
environment = "Terraform Demo"
}
}
# Create virtual network
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"
}
}

# Create subnet
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"]
}

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

tags = {
environment = "Terraform Demo"
}
}

# Create Network Security Group and rule
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"
}
}

# Create network interface
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"
}
}

# Connect the security group to the network interface
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
}

# Generate random text for a unique storage account name
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
}

# Create storage account for boot diagnostics
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"
}
}
# Create (and display) an SSH key
resource "tls_private_key" "example_ssh" {
algorithm = "RSA"
rsa_bits = 2048
}
output "tls_private_key" {
value = tls_private_key.example_ssh.private_key_pem
sensitive = true
}

# Create virtual machine
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"
}
}
resource "null_resource" "execute" {
connection {
type = "ssh"
agent = false
user = "azureuser"
host = azurerm_public_ip.myterraformpublicip.ip_address
private_key = tls_private_key.example_ssh.private_key_pem
}
provisioner "file" {
source = "./config"
destination = "~/"
}
provisioner "remote-exec" {
inline = [
"chmod 755 ~/scripts/*",
"sudo sh ~/scripts/foreman_prerequisite_config.sh",
]
}
depends_on = [azurerm_linux_virtual_machine.myterraformvm]
}

使用命令 terraform apply时遇到以下错误

[0m[1mnull_resource.execute: Provisioning with 'file'...[0m[0m
[31m╷[0m[0m
[31m│[0m [0m[1m[31mError: [0m[0m[1mfile provisioner error[0m
[31m│[0m [0m
[31m│[0m [0m[0m with null_resource.execute,
[31m│[0m [0m on main.tf line 184, in resource "null_resource" "execute":
[31m│[0m [0m 184: provisioner "file" [4m{[0m[0m
[31m│[0m [0m
[31m│[0m [0mhost for provisioner cannot be empty

请帮我解决这个问题。提前致谢!

最佳答案

根据Azure提供商文档[1],当公共(public)IP分配类型为动态时,您应该使用数据源来获取IP地址:

data "azurerm_public_ip" "myterraformpublicip" {
name = azurerm_public_ip.myterraformpublicip.name
resource_group_name = azurerm_linux_virtual_machine.myterraformvm.resource_group_name
}

然后,在 null_resourcehost 参数中,您应该设置以下内容:

host = data.azurerm_public_ip.myterraformpublicip.ip_address

但是,这可能无法解决您遇到的问题,因为此版本的 Linux VM 的 Azure 提供程序似乎存在问题 [2]:

In this release there's a known issue where the public_ip_address and public_ip_addresses fields may not be fully populated for Dynamic Public IP's.

问题的第二部分与生成 SSH key 有关,该 key 稍后可用于访问虚拟机。在您的问题中,您有以下代码:

resource "tls_private_key" "example_ssh" {
algorithm = "RSA"
rsa_bits = 4096
}

output "tls_private_key" {
value = tls_private_key.example_ssh.private_key_pem
sensitive = true
}

根据您在评论 [3] 中链接的答案,不需要输出。这可用于在同一目录中创建私钥:

resource "tls_private_key" "example_ssh" {
algorithm = "RSA"
rsa_bits = 4096
}

resource "local_file" "private_key_file" {
content = tls_private_key.example_ssh.private_key_pem
filename = "${path.root}/private-key.pem"
}

然后,在 null_resource 中,您应该添加以下内容:

resource "null_resource" "execute" {
connection {
type = "ssh"
agent = false
user = "azureuser"
host = data.azurerm_public_ip.myterraformpublicip.ip_address
private_key = "${path.root}/private-key.pem"
}

provisioner "file" {
source = "./config"
destination = "~/"
}

provisioner "remote-exec" {
inline = [
"chmod 755 ~/scripts/*",
"sudo sh ~/scripts/foreman_prerequisite_config.sh",
]
}
}
depends_on = [azurerm_linux_virtual_machine.myterraformvm]
}

请注意,您可能不应该在生产环境中使用 tls_private_key 资源 [4]:

The private key generated by this resource will be stored unencrypted in your Terraform state file. Use of this resource for production deployments is not recommended. Instead, generate a private key file outside of Terraform and distribute it securely to the system where Terraform will be run.

<小时/>

[1] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/public_ip#example-usage-retrieve-the-dynamic-public-ip-of-a-new-vm

[2] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine#:~:text=In%20this%20release%20there%27s%20a%20known%20issue%20where%20the%20public_ip_address%20and%20public_ip_addresses%20fields%20may%20not%20be%20fully%20populated%20for%20Dynamic%20Public%20IP%27s .

[3] https://stackoverflow.com/a/67379867/8343484

[4] https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key

关于linux - 错误: host for provisioner cannot be empty,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71292185/

53 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com