更新时间:2022-02-10 GMT+08:00

输入变量

输入变量可以理解为模块的参数,通过关键字 "variable" 进行声明。通过定义输入变量,我们可以无需变更模块的源代码就能灵活修改配置。输入变量的值可以使用默认值,CLI 选项,环境变量等方式来设置。

定义输入变量

按照约定,输入变量通常在名为 variables.tf 的文件中定义。输入变量通过关键字 "variable" 进行声明

variable "iamge_id" {
  type        = string
  description = "image id of Ubuntu 1804"
}

variable "availability_zone_name" {
  type    = string
  default = "cn-north-1a"
}
variable 关键字后的标签是输入变量的名称,该名称在同一模块中的所有变量之间必须唯一。变量的名称可以是除保留关键字以外的任何有效的标识符。保留关键字包括:
source    version    providers    count    for_each    lifecycle    depends_on    locals

variable块中主要包括如下参数:

  • type:指定变量的类型,默认为 string。
  • description :指定变量的描述信息,用于描述变量的用途。
  • default:指定变量的默认值,存在默认值的变量可视为可选变量。
  • validation块:指定变量的自定义验证规则。

如果未明确指定变量类型,则默认为 string。建议开发者显式指定变量类型,这样可以方便地提醒用户如何使用该模块,并允许Terraform在使用错误的类型后返回有用的错误信息。Terraform 输入变量支持的类型有:

  • 基本类型:string,number,bool
  • 复合类型:list(<TYPE>),set(<TYPE>),map(<TYPE>)

复合类型的变量定义如下:

variable "availability_zone_names" {
  type    = list(string)
  default = ["cn-north-1a"]
}

variable "docker_ports" {
  type = list(object({
    internal = number
    external = number
    protocol = string
  }))
  default = [{
    internal = 8300
    external = 8300
    protocol = "tcp"
  }]
}

自定义验证规则

我们可以使用 validation嵌套块为输入变量指定自定义验证规则,该特性在 Terraform 0.13.0之后的版本支持,例如:

variable "iam_user_password" {
    type        = string
    description = "The password for iam user to log in."

    validation {
      condition     = length(var.iam_user_password)>=8
      error_message = "The password is too short."
    }
}

其中,condition 参数是一个布尔表达式,我们可以使用 can 函数来检测表达式是否会产生错误,例如:

variable "iam_user_name" {
    type        = string
    description = "This name is used for iam user to log in."

    validation {
      # regex(...) 如果匹配失败将返回错误
      condition     = can(regex("([a-zA-Z])", var.iam_user_name))
      error_message = "Incorrect user name. Please check whether it contains upper and lower case letters."
    }
}

如果condition 的结果为false,Terraform 将产生一条错误消息,其内容为 error_message 所定义的字符串。error_message 应该至少是一个完整的句子,以大写字母开头,以 "." 或者 "?" 结尾。

引用输入变量

输入变量可以通过 var.<变量名称> 的形式访问,且只能在声明该变量的模块内访问:

# variables.tf
variable "vpc_cidr" {
  type        = string
  description = "the CIDR of VPC"
}

# main.tf
resource "huaweicloud_vpc" "vpc_example" {
    name = "my_vpc"
    cidr = var.vpc_cidr
}

设置变量

通过如下方式可以设置输入变量:

  • 通过命令行中 -var 选项指定
  • 通过变量定义文件 (.tfvars),在命令行中指定或自动加载
  • 设置环境变量

在 "terraform plan" 和 "terraform apply" 命令行中,通过 -var 选项可以指定变量。其中,-var 选项可以多次使用,例如:

terraform apply -var='vpc_name=my_vpc'
terraform apply -var='vpc_name=my_vpc' -var='vpc_cidr=192.168.0.0/16'
terraform apply -var='availability_zone_names=["cn-north-1a", "cn-north-1c"]'

注意:变量名称和等号之间不能有空格。

变量定义 (.tfvars) 文件

如果配置中使用了很多变量,建议使用变量定义文件来设置这些变量,然后通过 -var-file 选项指定该文件:

terraform apply -var-file="testing.tfvars"

变量定义文件的扩展名为 ".tfvars",变量定义文件的语法与配置文件的语法相同,但仅用于指定变量名称:

vpc_name = "my_vpc"
vpc_cidr = "192.168.0.0/16"
availability_zone_names = [
    "cn-north-1a",
    "cn-north-1c",
]

Terraform 还会自动加载特殊命名的变量定义文件:

  • 文件名为 terraform.tfvars 或 terraform.tfvars.json 的文件
  • 文件名称以 .auto.tfvars 或 .auto.tfvars.json 结尾的文件

对于以 .json 结尾的文件,需要使用 JSON对象表示:

{
    "vpc_name": "my_vpc"
    "availability_zone_names": ["cn-north-1a", "cn-north-1c"]
}

环境变量

我们可以通过设置以 "TF_VAR_" 为前缀的环境变量来指定置输入变量。这对以自动化的方式运行或连续运行使用相同变量的 Terraform 命令很有帮助。

$ export TF_VAR_vpc_name=my_vpc
$ export TF_VAR_availability_zone_names='["cn-narth-1a", "cn-north-1c"]'
$ terraform plan
...

变量定义优先级

我们可以自由组合使用上述设置变量的方式。对于复合类型的变量,为了提高可读性并避免转义带来的问题,建议使用变量定义文件来设置。如果我们为同一个变量分配了多个值,Terraform 将使用最后一个值进行覆盖。Terraform 根据以下顺序加载变量 (根据顺序,后面的源优于前面的源):

  1. 环境变量
  2. terraform.tfvars 或 terraform.tfvars.json 文件
  3. *.auto.tfvars 或 *.auto.tfvars.json 文件
  4. 命令行中的 -var 和 -var-file 选项

注:不能在单个源中为同一个变量分配多个值。

有关变量的更多信息,请参见Terraform的 输入变量文档。