运行Terraform初始化,terraform计划或应用时出现无效字符错误

时间:2020-04-25 11:49:00

标签: automation terraform devops terraform-provider-azure

我正在使用VScode编辑器运行Terraform,该编辑器使用PowerShell作为默认Shell,并在尝试对其进行验证或通过VScode,外部PowerShell或CMD运行terraform init / plan / apply时遇到相同的错误。

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

terraform.tfvars

web_server_location       = "West US 2"
resource_prefix           = "web-server"
web_server_address_space  = "1.0.0.0/22"
web_server_address_prefix = "1.0.1.0/24"
Environment               = "Test"

variables.tf

variable "web_server_location" {
  type = string
}

variable "resource_prefix" {
  type = string
}

variable "web_server_address_space" {
  type = string
}

#variable for network range

variable "web_server_address_prefix" {
  type = string
}

#variable for Environment
variable "Environment" {
  type = string
}

terraform_example.tf

# Configure the Azure Provider
provider "azurerm" {
  # whilst the `version` attribute is optional, we recommend pinning to a given version of the Provider
  version = "=2.0.0"
  features {}
}

# Create a resource group
resource "azurerm_resource_group" "example_rg" {
  name     = "${var.resource_prefix}-RG"
  location = var.web_server_location
}

# Create a virtual network within the resource group
resource "azurerm_virtual_network" "example_vnet" {
  name                = "${var.resource_prefix}-vnet"
  resource_group_name = azurerm_resource_group.example_rg.name
  location            = var.web_server_location
  address_space       = [var.web_server_address_space]
}

# Create a subnet within the virtual network
resource "azurerm_subnet" "example_subnet" {
  name                  = "${var.resource_prefix}-subnet"
  resource_group_name   = azurerm_resource_group.example_rg.name
  virtual_network_name  = azurerm_virtual_network.example_vnet.name
  address_prefix        = var.web_server_address_prefix
}

# Create a Network Interface
resource "azurerm_network_interface" "example_nic" {
  name                = "${var.resource_prefix}-NIC"
  location            = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.example_subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.example_public_ip.id
  }  
}

# Create a Public IP 
resource "azurerm_public_ip" "example_public_ip" {
  name = "${var.resource_prefix}-PublicIP"
  location = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  allocation_method = var.Environment == "Test" ? "Static" : "Dynamic"

  tags = {
    environment = "Test"
  }
}

# Creating resource NSG
resource "azurerm_network_security_group" "example_nsg" {
  name = "${var.resource_prefix}-NSG"
  location = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name

  # Security rule can also be defined with resource azurerm_network_security_rule, here just defining it inline. 
  security_rule {
    name       = "RDPInbound"
    priority   = 100
    direction  = "Inbound"
    access     = "Allow"
    protocol   = "Tcp"
    source_port_range = "*"
    destination_port_range = "3389"
    source_address_prefix  = "*"
    destination_address_prefix = "*"
  }
  tags = {
    environment = "Test"
  }
}

# NIC and NSG association 
resource "azurerm_network_interface_security_group_association" "example_nsg_association" {
   network_interface_id      = azurerm_network_interface.example_nic.id
   network_security_group_id = azurerm_network_security_group.example_nsg.id

}

# Creating Windows Virtual Machine
resource "azurerm_virtual_machine" "example_windows_vm" {
  name  = "${var.resource_prefix}-VM"
  location = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  network_interface_ids = [azurerm_network_interface.example_nic.id]
  vm_size = "Standard_B1s"
  delete_os_disk_on_termination = true

  storage_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServerSemiAnnual"
    sku       = "Datacenter-Core-1709-smalldisk"
    version   = "latest"  
  }

  storage_os_disk  {
    name                 = "myosdisk1"
    caching              = "ReadWrite"
    create_option        = "FromImage"
    storage_account_type = "Standard_LRS"
  }

  os_profile {
    computer_name  = "hostname"
    admin_username = "adminuser"
    admin_password = "Password1234!"
  }

  os_profile_windows_config {
    disable_password_authentication = false
  }

  tags = {
    environment = "Test"
  }
}

错误:

PS C:\Users\e5605266\Documents\MyFiles\Devops\Terraform> terraform init

There are some problems with the configuration, described below.

The Terraform configuration must be valid before initialization so that
Terraform can determine which modules and providers need to be installed.

Error: Invalid character

  on terraform_example.tf line 89, in resource "azurerm_virtual_machine" "example_windows_vm":
  89:   location                      = azurerm_resource_group.example_rg.location

This character is not used within the language.


Error: Invalid expression

  on terraform_example.tf line 89, in resource "azurerm_virtual_machine" "example_windows_vm":
  89:   location                      = azurerm_resource_group.example_rg.location

Expected the start of an expression, but found an invalid expression token.


Error: Argument or block definition required

  on terraform_example.tf line 90, in resource "azurerm_virtual_machine" "example_windows_vm":
  90:   resource_group_name           = azurerm_resource_group.example_rg.name

An argument or block definition is required here. To set an argument, use the
equals sign "=" to introduce the argument value.


Error: Invalid character

  on terraform_example.tf line 90, in resource "azurerm_virtual_machine" "example_windows_vm":
  90:   resource_group_name           = azurerm_resource_group.example_rg.name

This character is not used within the language.
*

2 个答案:

答案 0 :(得分:2)

我自己在几个不同的上下文中都遇到了这个问题,它确实有一个通用的解决方案,一点都不有趣:手动输入代码...

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

resource "azurerm_virtual_machine" "example_windows_vm" {
  name  = "${var.resource_prefix}-VM"
  location = azurerm_resource_group.example_rg.location
  resource_group_name = azurerm_resource_group.example_rg.name
  network_interface_ids = [azurerm_network_interface.example_nic.id]
  vm_size = "Standard_B1s"
  delete_os_disk_on_termination = true

  storage_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServerSemiAnnual"
    sku       = "Datacenter-Core-1709-smalldisk"
    version   = "latest"  
  }

  storage_os_disk  {
    name                 = "myosdisk1"
    caching              = "ReadWrite"
    create_option        = "FromImage"
    storage_account_type = "Standard_LRS"
  }

  os_profile {
    computer_name  = "hostname"
    admin_username = "adminuser"
    admin_password = "Password1234!"
  }

  os_profile_windows_config {
    disable_password_authentication = false
  }

  tags = {
    environment = "Test"
  }
}

尝试按原样复制回编辑器。我看不到任何有问题的字符,具有讽刺意味的是,StackOverflow可能使您变得可靠并过滤掉了它们。从字面上复制/粘贴到现有块上可能会纠正这种情况。

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

除此之外,您还需要将代码推送到GitHub或类似网站,以便我自己查看原始字节。

答案 1 :(得分:1)

在偶然的情况下,这可以帮助遇到此错误并在 Google 上遇到它的人,我只是想我会发布我的情况以及我如何解决它。

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

terraform plan -out=plan.tf

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

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

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