Terraform 参数必须是地图或对象,得到“字符串”
Posted
技术标签:
【中文标题】Terraform 参数必须是地图或对象,得到“字符串”【英文标题】:Terraform arguments must be maps or objects, got "string" 【发布时间】:2021-05-07 03:45:10 【问题描述】:预期行为
我正在尝试遍历 var.vm_settings 但似乎没有合作。 该错误没有意义,因为输入变量所需的类型是“字符串”
实际行为
抛出错误(见错误输出)
错误输出
Error: Error in function call
on ..\main.tf line 4, in locals:
4: vm_settings = zipmap(keys(var.vm_settings), [for vm_setting in values(var.vm_settings) : merge(var.vm_defaults, vm_setting)])
|----------------
| var.vm_defaults is object with 12 attributes
Call to function "merge" failed: arguments must be maps or objects, got
"string".
Terraform(和 AzureRM 提供程序)版本
受影响的资源
azurerm_v2.25.0
terraform v0.13.0
Terraform 配置文件
Main.tf
locals
vm_settings = zipmap(keys(var.vm_settings), [for vm_setting in values(var.vm_settings) : merge(var.vm_defaults, vm_setting)])
resource "azurerm_linux_virtual_machine" "oracle_db"
for_each = local.vm_settings
name = each.key
resource_group_name = var.resource_group_name
location = var.location
size = each.value.size
admin_username = each.value.admin_username
admin_password = local.admin_password
disable_password_authentication = each.value.disable_password_authentication
priority = each.value.priority
eviction_policy = each.value.eviction_policy
zone = each.value.zone
network_interface_ids = [azurerm_network_interface.nic.id, ]
admin_ssh_key
username = each.value.admin_ssh_key.username
public_key = each.value.admin_ssh_key.public_key
identity
type = each.value.identity.type
os_disk
caching = each.value.os_disk.caching
storage_account_type = each.value.os_disk.storage_account_type
source_image_reference
publisher = each.value.source_image_reference.publisher
offer = each.value.source_image_reference.offer
sku = each.value.source_image_reference.sku
version = each.value.source_image_reference.version
boot_diagnostics
storage_account_uri = each.value.boot_diagnostics.storage_account_uri
Variables.tf
variable "vm_settings"
description = "Map of vm's to create (keys are vm names). Allowed values are the same as for vm_defaults."
type = any
default =
variable "vm_defaults"
type = object(
name = string
size = string
admin_username = string
admin_password = string
disable_password_authentication = string
priority = string
eviction_policy = string
identity = object(
type = string
)
admin_ssh_key = object(
username = string
public_key = string
)
os_disk = object(
name = string
caching = string
storage_account_type = string
)
source_image_reference = object(
publisher = string
offer = string
sku = string
version = string
)
boot_diagnostics = object(
storage_account_uri = string
)
)
default =
name = null
size = null
admin_username = null
admin_password = ""
disable_password_authentication = null
priority = null
eviction_policy = null
identity =
type = null
admin_ssh_key =
username = ""
public_key = null
os_disk =
name = null
caching = null
storage_account_type = null
# Image used to create the virtual machines.
source_image_reference =
publisher = ""
offer = ""
sku = ""
version = ""
boot_diagnostics =
storage_account_uri = ""
description = <<EOT
virtual machine default settings (only applied to virtual machine settings managed within this module)
vm_settings =
size = (Required) The SKU which should be used for this Virtual Machine, such as Standard_F2.
admin_username = (Required) The username of the local administrator used for the Virtual Machine. Changing this forces a new resource to be created.ring
admin_password = (Optional) The Password which should be used for the local-administrator on this Virtual Machine. Changing this forces a new resource to be created.
disable_password_authentication = (Optional) Should Password Authentication be disabled on this Virtual Machine? Defaults to true. Changing this forces a new resource to be created.
# Spot VM to save money
priority = (Optional) Specifies the priority of this Virtual Machine. Possible values are Regular and Spot. Defaults to Regular. Changing this forces a new resource to be created.
eviction_policy = (Optional) Specifies what should happen when the Virtual Machine is evicted for price reasons when using a Spot instance. At this time the only supported value is Deallocate. Changing this forces a new resource to be created. This can only be configured when priority is set to Spot.
# type of Managed Identity which should be assigned to the Linux Virtual Machine
identity =
type = (Required) The type of Managed Identity which should be assigned to the Linux Virtual Machine. Possible values are SystemAssigned, UserAssigned and SystemAssigned, UserAssigned.
# SSH key
admin_ssh_key =
username = (Required) The Public Key which should be used for authentication, which needs to be at least 2048-bit and in ssh-rsa format. Changing this forces a new resource to be created.
public_key = (Required) The Username for which this Public SSH Key should be configured. Changing this forces a new resource to be created.
# Internal OS disk
os_disk =
name = (Required) The Type of Caching which should be used for the Internal OS Disk. Possible values are None, ReadOnly and ReadWrite.
caching = (Required) The Type of Caching which should be used for the Internal OS Disk. Possible values are None, ReadOnly and ReadWrite.
storage_account_type = (Required) The Type of Storage Account which should back this the Internal OS Disk. Possible values are Standard_LRS, StandardSSD_LRS and Premium_LRS. Changing this forces a new resource to be created.
# Image used to create the virtual machines.
source_image_reference =
publisher = (Optional) Specifies the publisher of the image used to create the virtual machines.
offer = (Optional) Specifies the offer of the image used to create the virtual machines.
sku = (Optional) Specifies the SKU of the image used to create the virtual machines.
version = (Optional) Specifies the version of the image used to create the virtual machines.
boot_diagnostics =
storage_account_uri = (Optional) The Primary/Secondary Endpoint for the Azure Storage Account which should be used to store Boot Diagnostics, including Console Output and Screenshots from the Hypervisor. Passing a null value will utilize a Managed Storage Account to store Boot Diagnostics.
EOT
【问题讨论】:
【参考方案1】:通常如果你有一个默认地图并且你想将它与用户提供的地图结合起来,以下就足够了:
merge(var.vm_defaults, var.vm_settings)
以上将使用来自var.vm_settings
的值,而其他所有内容将来自var.vm_defaults
。
所以你的local.vm_settings
将是:
locals
vm_settings = merge(var.vm_defaults, var.vm_settings)
【讨论】:
以上是关于Terraform 参数必须是地图或对象,得到“字符串”的主要内容,如果未能解决你的问题,请参考以下文章
Terraform:“inputMap”参数的值无效:lookup() 需要地图作为第一个参数