变量的类型
有两种类型的变量:
- 输入变量(变量)
- 本地值(本地)
输入变量(变量)
大多数 Terraform 项目以一种或多种方式使用变量。变量非常常见,并且有充分的理由。可以在整个项目(或模块)中访问变量(如果您要构建由一个或多个模块构成的项目)。
本地值(本地)
还有一种称为局部变量(即“局部变量”)的变量,这是整个项目无法访问的,但仅限于单个 Terraform 文件的上下文。这意味着,如果在特定 Terraform 文件中定义了本地变量,则它仅可用于该文件中的代码(但不能用于其他 Terraform 文件中的代码)。
获取变量
获取变量的内容
要使用变量,请在变量名称开头加上 var.
。例如,以下 VCN 资源块中使用的 var.tenancy_ocid
:
resource oci_core_vcn tf_101 {
cidr_block = "192.168.1.0/24"
compartment_id = var.tenancy_ocid
display_name = "tf-101"
dns_label = "tf101"
}
这看起来很熟悉。它从体验 Terraform 教程中借用!这是引用(读取和使用)tenancy_ocid
变量的方式。
获取本地内容
要使用本地变量,只需在本地变量名称前面加上 local
下面是一个示例:
resource oci_core_vcn tf_101 {
cidr_block = local.cidr
compartment_id = var.tenancy_ocid
display_name = "tf-101"
dns_label = "tf101"
}
上面的示例将 cidr_block
属性设置为 cidr
本地属性中的任何属性。
设置变量值
可通过多种方法设置变量的值。设置变量的值(从最高优先级到最低优先级列出)时,Terraform 使用以下优先级顺序:
- CLI 参数(-var 和 -var-file CLI 参数)
- *.auto.tfvars
- terraform.tfvars
- 环境变量
设置本地值(本地)
本地值与常规变量略有不同(在本节的其余部分中我们将介绍)。本地(也称为“本地值”)是在 Terraform 代码本身中设置的。由于本地设置在 Terraform 代码中,因此可以以编程方式对其进行计算,从而授予使用 Terraform 函数、引用其他变量、本地和资源的功能。
下面是如何定义本地人的示例:
locals {
comp_id = len(var.compartment_id) > 0 ? var.compartment_id : "abcd.1234"
}
以上示例是虚构的(甚至不是定义本地语言的最有效方法),但您可以了解如何设置 comp_id
本地(变量)。本地是在多个 locals
块中定义的,但引用时是单数 (local.comp_id
)。
通过命令行界面
Terraform 支持许多命令行参数,其中一个是 -var
参数,允许您在运行 Terraform 时设置变量的值。下面是使用命令行设置 compartment_id
变量的示例。
$ terraform plan -var 'compartment_id=abcd.1234'
或者,您也可以使用以下格式。
$ terraform plan -var="compartment_id=abcd.1234"
可以使用此技术设置一个或多个变量。此方法有点乏味,因为它在运行 Terraform 时会导致一个非常长的命令,特别是如果设置了大量变量。每次想要运行 Terraform 时都需要使用此功能!
变量文件
以 .tfvars
结尾的文件可用于设置变量的值。您可以使用 -var-file
参数告诉 Terraform 在运行时读取哪些文件,也可以让它自动加载文件(基于其文件名)。
如果工作目录中存在 terraform.tfvars
文件,Terraform 将读取该文件并设置在那里提供的变量值。下面是一个示例 terraform.tfvars
文件:
compartment_id = "<your_compartment_OCID_here>"
region = "us-phoenix-1"
cidr = "172.16.0.0/20"
这些是设置变量值(请注意,没有使用 var.
前缀)。Terraform 隐式使用 terraform.tfvars
文件设置变量值。
将静态读取 terraform.tfvars
文件,这意味着不会进行计算。Terraform 不引用其他变量、资源或其他 Terraform 函数。它仅读取静态值。
terraform.tfvars
文件通常可用于设置特定于环境的设置。它通常不会提交到 git 资源库(至少与 Terraform 代码一起使用),因为其值可能确定环境的特性。
*.auto.tfvars
您可以在 .auto.tfvars
中指定任意数量的文件,Terraform 很乐意读取这些文件并相应地设置变量值。这允许您在不同文件之间设置不同的变量定义。例如,将变量定义设置为跟随(这只是一个示例,绝不是唯一的方法):
network.auto.tfvars
storage.auto.tfvars
compute.auto.tfvars
这样对变量赋值进行分组可以使人员更好地在变量之间导航,尤其是在存在大量变量时。
通过环境变量
Terraform 足够智能,能够在运行时查看环境变量。如果有任何变量以 TF_VAR_
开头(完整的环境变量为:TF_VAR_<variable_name>
),则 Terraform 会将该值分配给给定的变量。
下面是如何在 MacOS/Linux 系统上设置 compartment_id
变量的示例:
export TF_VAR_compartment_id=<your_compartment_OCID_here>
此环境变量在 Windows 上可能设置如下:
setx TF_VAR_compartment_id <your_compartment_OCID_here>
通过用户交互式提示
如果未给变量赋值,Terraform 将通过请求用户在运行时提供变量。如果不知道要使用的值,Terraform 将无法继续。
这是令人烦恼的,可能很乏味(特别是如果有很多未定义的变量),但有时这种方法可能具有完美的意义。在需要用户输入值(例如确认提示)的情况下,这可能是一个很好的解决方案。
定义变量
要定义变量是否存在,只需在 Terraform 代码中的任意位置提供以下内容:
variable "compartment_id" {}
通常的做法是在单个文件中放置变量定义:variables.tf
。这样可以更轻松地管理变量定义(将变量定义放在一个位置)。
除了变量名称之外,还可以为变量设置多个不同的属性,包括(但不限于):
- 类型(type)(稍后将讨论某些常见类型)
- 说明(description)最好让人们知道该变量的使用方式)
- 默认(default)
- 敏感(sensitive)
默认值
default
属性需要了解,因为其行为是多用途的。注意没有 required
属性。如果变量不具有默认值,Terraform 将要求设置变量值。这意味着 default
不仅允许您提供默认值,而且还可以使变量“可选”(排序)。这真是物有所值的副作用。每个定义的变量必须具有一个值。赋予默认值(即使为空,例如 ""
或 null
的值)使 Terraform 不会“调试”运算符,这会给出不需要的印象。这就是你如何看待它的问题。
某些变量最好留空(因此,如果运行 Terraform 的用户未将其设置为特定值,则非常明显)。通常,设置“sane defaults”非常好,以便对变量使用合理的默认值,从而最大程度地减少必须提供的输入量。为变量赋予默认值时,除非已覆盖(显式设置了值),否则将使用默认值。
要定义默认值,请将 default
属性添加到变量定义中。
variable "compartment_id" {
default = "abcd.1234"
}
在上面的示例中,除非显式提供了值,否则 compartment_id
变量将使用默认值 "abcd.1234"。
敏感变量
如果将变量的敏感属性设置为 true
,则 Terraform 会尝试将向用户显示的值降至最低。这不能保证用户无法访问或无法在屏幕上显示。有关详细信息,请参阅 Terraform 文档。
下面是一个示例:
variable "api_token" {
sensitive = true
}
在上面的示例中,通过为 api_token
变量将 sensitive
属性设置为 true,将 api_token
变量的可见性最小化。
变量类型
字符串
到目前为止使用的变量是字符串值。字符串值由双引号 ("") 括起来。
compartment_id="<your_compartment_OCID_here>"
下面是在 variables.tf
中定义的:
variable tenancy_id {
type = string
}
字符串是常见的,但绝不是唯一可以使用的类型。
数字
数字是不用引号括起来的数字值。
number_of_computes=10
下面是在 variables.tf
中定义的:
variable "number_of_computes" {
type = number
}
布尔值
与许多其他语言一样,Terraform 支持 true
和 false
布尔值。下面是正在设置的布尔变量示例。
create_computes = true
在上面的示例中,create_computes
变量设置为 true
。这对于许多事情可能非常有用,包括指定所需行为(如本示例,如果将值设置为 false
,则可能无法创建计算)。
下面是在 variables.tf
中定义的:
variable "create_computes" {
type = bool
}
列表
有时需要列表。Terraform 列表与许多其他语言的数组类似。Terraform 列表是一个指定类型的有序值列表(可以是字符串值、数字值等)。下面是字符串列表的示例。
compute_names = [ "web1", "web2", "app1", "app2", "db1", "db2" ]
下面是在 variables.tf
中定义的。
variable "compute_names" {
type = list(string)
}
要引用列表元素,请使用项的索引。Terraform 为零索引,因此第一项是索引 0
,第二项是索引 1
,依此类推。查看如何引用 db1
值(从上面的列表示例,即元素 5
、索引 4
):
var.compute_names[4] # this equals "db1"
Map
需要键 - 值关系的强大功能时,Terraform 映射可在此处提供帮助!映射与其他某些语言的散列类似,允许您具有多个键,每个键都有值。下面是一个映射示例。
compute_shapes = {
"web1" = "VM.Standard2.1",
"web2" = "VM.Standard2.1",
"app1" = "VM.Standard2.4",
"app2" = "VM.Standard2.4",
"db1" = "VM.Standard2.8",
"db2" = "VM.Standard2.8"
}
下面是在 variables.tf
中定义的。
variable "compute_shapes" {
type = map(string)
}
这可能是一个数字的映射(而不是字符串)或其他有效的变量类型。
要引用映射元素,请使用项键。下面介绍如何引用 db1
值。
var.compute_shapes["db1"] # this equals "VM.Standard2.8"
示例变量定义
下面是一个“切换”变量(布尔值,可以是 true
或 false
)的示例:
variable "extra_power" {
type = bool
default = true
}
下面是一个更复杂变量的示例(从 terraform-oci-ocloud-foundation/assets/network/input.tf at main · oracle-devrel/terraform-oci-ocloud-foundation · GitHub 获取):
variable "subnet" {
type = object({
cidr_block = string,
prohibit_public_ip_on_vnic = bool,
dhcp_options_id = string,
route_table_id = string
})
description = "Parameters for each subnet to be managed"
}
在上面的示例中,子网变量包含多个不同类型的属性(cidr_block
、prohibit_public_ip_on_vnic
等)。这只是有关如何制作复杂变量的示例。不过,不要担心这一点,因为复杂变量是可选的(对于大多数用例,您可以使用单值变量)。
这些只是几个例子。你可以变得非常疯狂的变量!与他们开心,保持创意,并记住变量在很大程度上定义了 Terraform 环境的输入接口。查看 Terraform 语言文档中的输入变量来了解其他一些变量类型和 Terraform 变量功能。