运行 terraform init、terraform plan 或 apply 时出现无效字符错误

Sha*_*jee 2 automation terraform devops terraform-provider-azure

我正在使用 VScode 编辑器运行 Terraform,该编辑器使用 PowerShell 作为默认 shell,当我尝试验证它或通过 VScode、外部 PowerShell 或 CMD 运行 terraform init/plan/apply 时,会出现相同的错误。

\n\n

在我添加虚拟机创建代码之前,代码运行没有任何问题。我已经将 Variables.tf、terraform.tfvars 和下面的主要 Terraform 代码组合在一起。

\n\n

terraform.tfvars

\n\n
web_server_location       = "West US 2"\nresource_prefix           = "web-server"\nweb_server_address_space  = "1.0.0.0/22"\nweb_server_address_prefix = "1.0.1.0/24"\nEnvironment               = "Test"\n
Run Code Online (Sandbox Code Playgroud)\n\n

变量.tf

\n\n
variable "web_server_location" {\n  type = string\n}\n\nvariable "resource_prefix" {\n  type = string\n}\n\nvariable "web_server_address_space" {\n  type = string\n}\n\n#variable for network range\n\nvariable "web_server_address_prefix" {\n  type = string\n}\n\n#variable for Environment\nvariable "Environment" {\n  type = string\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

terraform_example.tf

\n\n
# Configure the Azure Provider\nprovider "azurerm" {\n  # whilst the `version` attribute is optional, we recommend pinning to a given version of the Provider\n  version = "=2.0.0"\n  features {}\n}\n\n# Create a resource group\nresource "azurerm_resource_group" "example_rg" {\n  name     = "${var.resource_prefix}-RG"\n  location = var.web_server_location\n}\n\n# Create a virtual network within the resource group\nresource "azurerm_virtual_network" "example_vnet" {\n  name                = "${var.resource_prefix}-vnet"\n  resource_group_name = azurerm_resource_group.example_rg.name\n  location            = var.web_server_location\n  address_space       = [var.web_server_address_space]\n}\n\n# Create a subnet within the virtual network\nresource "azurerm_subnet" "example_subnet" {\n  name                  = "${var.resource_prefix}-subnet"\n  resource_group_name   = azurerm_resource_group.example_rg.name\n  virtual_network_name  = azurerm_virtual_network.example_vnet.name\n  address_prefix        = var.web_server_address_prefix\n}\n\n# Create a Network Interface\nresource "azurerm_network_interface" "example_nic" {\n  name                = "${var.resource_prefix}-NIC"\n  location            = azurerm_resource_group.example_rg.location\n  resource_group_name = azurerm_resource_group.example_rg.name\n\n  ip_configuration {\n    name                          = "internal"\n    subnet_id                     = azurerm_subnet.example_subnet.id\n    private_ip_address_allocation = "Dynamic"\n    public_ip_address_id          = azurerm_public_ip.example_public_ip.id\n  }  \n}\n\n# Create a Public IP \nresource "azurerm_public_ip" "example_public_ip" {\n  name = "${var.resource_prefix}-PublicIP"\n  location = azurerm_resource_group.example_rg.location\n  resource_group_name = azurerm_resource_group.example_rg.name\n  allocation_method = var.Environment == "Test" ? "Static" : "Dynamic"\n\n  tags = {\n    environment = "Test"\n  }\n}\n\n# Creating resource NSG\nresource "azurerm_network_security_group" "example_nsg" {\n  name = "${var.resource_prefix}-NSG"\n  location = azurerm_resource_group.example_rg.location\n  resource_group_name = azurerm_resource_group.example_rg.name\n\n  # Security rule can also be defined with resource azurerm_network_security_rule, here just defining it inline. \n  security_rule {\n    name       = "RDPInbound"\n    priority   = 100\n    direction  = "Inbound"\n    access     = "Allow"\n    protocol   = "Tcp"\n    source_port_range = "*"\n    destination_port_range = "3389"\n    source_address_prefix  = "*"\n    destination_address_prefix = "*"\n  }\n  tags = {\n    environment = "Test"\n  }\n}\n\n# NIC and NSG association \nresource "azurerm_network_interface_security_group_association" "example_nsg_association" {\n   network_interface_id      = azurerm_network_interface.example_nic.id\n   network_security_group_id = azurerm_network_security_group.example_nsg.id\n\n}\n\n# Creating Windows Virtual Machine\nresource "azurerm_virtual_machine" "example_windows_vm" {\n  name  = "${var.resource_prefix}-VM"\n  location =\xc2\xa0azurerm_resource_group.example_rg.location\n  resource_group_name\xc2\xa0=\xc2\xa0azurerm_resource_group.example_rg.name\n  network_interface_ids\xc2\xa0=\xc2\xa0[azurerm_network_interface.example_nic.id]\n  vm_size =\xc2\xa0"Standard_B1s"\n  delete_os_disk_on_termination = true\n\n  storage_image_reference\xc2\xa0{\n    publisher\xc2\xa0=\xc2\xa0"MicrosoftWindowsServer"\n    offer     = "WindowsServerSemiAnnual"\n    sku\xc2\xa0      =\xc2\xa0"Datacenter-Core-1709-smalldisk"\n    version   =\xc2\xa0"latest"  \n  }\n\n  storage_os_disk\xc2\xa0 {\n    name                 = "myosdisk1"\n    caching\xc2\xa0             =\xc2\xa0"ReadWrite"\n    create_option        = "FromImage"\n    storage_account_type\xc2\xa0=\xc2\xa0"Standard_LRS"\n  }\n\n  os_profile {\n    computer_name  = "hostname"\n    admin_username = "adminuser"\n    admin_password = "Password1234!"\n  }\n\n  os_profile_windows_config {\n    disable_password_authentication = false\n  }\n\n  tags = {\n    environment = "Test"\n  }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

错误:

\n\n
PS C:\\Users\\e5605266\\Documents\\MyFiles\\Devops\\Terraform> terraform init\n\nThere are some problems with the configuration, described below.\n\nThe Terraform configuration must be valid before initialization so that\nTerraform can determine which modules and providers need to be installed.\n\nError: Invalid character\n\n  on terraform_example.tf line 89, in resource "azurerm_virtual_machine" "example_windows_vm":\n  89:   location                      = azurerm_resource_group.example_rg.location\n\nThis character is not used within the language.\n\n\nError: Invalid expression\n\n  on terraform_example.tf line 89, in resource "azurerm_virtual_machine" "example_windows_vm":\n  89:   location                      = azurerm_resource_group.example_rg.location\n\nExpected the start of an expression, but found an invalid expression token.\n\n\nError: Argument or block definition required\n\n  on terraform_example.tf line 90, in resource "azurerm_virtual_machine" "example_windows_vm":\n  90:   resource_group_name           = azurerm_resource_group.example_rg.name\n\nAn argument or block definition is required here. To set an argument, use the\nequals sign "=" to introduce the argument value.\n\n\nError: Invalid character\n\n  on terraform_example.tf line 90, in resource "azurerm_virtual_machine" "example_windows_vm":\n  90:   resource_group_name           = azurerm_resource_group.example_rg.name\n\nThis character is not used within the language.\n*\n
Run Code Online (Sandbox Code Playgroud)\n

Ala*_*Dea 6

我自己在几个不同的环境中遇到过这个问题,它确实有一个通用的解决方案,但一点也不有趣:手动输入代码......

\n\n

这个资源块似乎是遇到问题的地方:

\n\n
resource "azurerm_virtual_machine" "example_windows_vm" {\n  name  = "${var.resource_prefix}-VM"\n  location =\xc2\xa0azurerm_resource_group.example_rg.location\n  resource_group_name\xc2\xa0=\xc2\xa0azurerm_resource_group.example_rg.name\n  network_interface_ids\xc2\xa0=\xc2\xa0[azurerm_network_interface.example_nic.id]\n  vm_size =\xc2\xa0"Standard_B1s"\n  delete_os_disk_on_termination = true\n\n  storage_image_reference\xc2\xa0{\n    publisher\xc2\xa0=\xc2\xa0"MicrosoftWindowsServer"\n    offer     = "WindowsServerSemiAnnual"\n    sku\xc2\xa0      =\xc2\xa0"Datacenter-Core-1709-smalldisk"\n    version   =\xc2\xa0"latest"  \n  }\n\n  storage_os_disk\xc2\xa0 {\n    name                 = "myosdisk1"\n    caching\xc2\xa0             =\xc2\xa0"ReadWrite"\n    create_option        = "FromImage"\n    storage_account_type\xc2\xa0=\xc2\xa0"Standard_LRS"\n  }\n\n  os_profile {\n    computer_name  = "hostname"\n    admin_username = "adminuser"\n    admin_password = "Password1234!"\n  }\n\n  os_profile_windows_config {\n    disable_password_authentication = false\n  }\n\n  tags = {\n    environment = "Test"\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

尝试将其按原样复制回编辑器中。我在其中看不到任何有问题的字符,具有讽刺意味的是,StackOverflow 可能已经为您提供了坚实的基础并将其过滤掉。从字面上将其复制/粘贴到现有块上可以解决这种情况。

\n\n

我在网上多次看到带有时尚双引号的 Terraform 示例(不是 ASCII 双引号,因此不起作用)。这可能就是你所看到的。

\n\n

除此之外,您需要将代码推送到 GitHub 或类似的地方,以便我自己可以看到原始字节。

\n


小智 5

偶尔这会帮助那些遇到这个错误并在谷歌上遇到它的人,我只是想我会发布我的情况以及我如何修复它。

我有一个旧的演示 Terraform 基础设施,几个月后我重新访问了它,长话短说,我两天前发出了这个命令,然后忘记了它:

terraform plan -out=plan.tf
Run Code Online (Sandbox Code Playgroud)

这将创建该计划的 zip 存档。两天后回来并运行 terraform init 时,我的终端滚动了垃圾信息并显示“该字符未在该语言中使用”。约7秒。由于 .tf 扩展名,terraform 正在查看 zip 数据并立即拉裤子。

通过将各个 tf 文件移动到临时目录并使用terraform init检查其有效性,我找到了罪魁祸首,将其删除,并且功能已恢复。

伙计们,导出计划文件时要小心!

  • 这帮了很大忙。正在导出为 plan.tf,但现在当我导出为 tf.plan 时它可以工作:)。 (2认同)