Terraform的基本概念

本文主要描述编写Terraform部署文件的基本概念。

1. 基本概念

1.1. 提供商(Provider)

Provider实现了每一种可配置的资源类型。可以理解为实现了资源增删改查的通用接口。

提供商通常定义在 providers.tf 文件中,您需要指定包含提供商定义的 Terraform 块。当声明了提供商后,Terraform 通过 init 命令自动下载提供商插件。

官方provider的仓库:https://registry.terraform.io/

terraform {
  required_providers {
    alicloud = {
      source = "aliyun/alicloud"
      version = "1.225.0"
    }
  }
}

provider "alicloud" {
  # 配置你的阿里云凭据和地域信息
  # 出于安全考虑,建议不要在这个文件中直接包含你的阿里云AccessKey和SecretKey,推荐使用环境变量或其它安全方式设置凭据:
  # export ALICLOUD_ACCESS_KEY="<你的阿里云Access Key>"
  # export ALICLOUD_SECRET_KEY="<你的阿里云Secret Key>"
  region = "cn-hangzhou"
}

1.2. 资源(Resources)

资源(Resources)是定义基础设施组件的代码块,可以按照资源类型单独使用一个独立的 .tf 文件来存放,例如:database.tf。资源通过关键字 resource 来标识,之后是具体的资源类型和自定义名称。

resource "resource_type" "resource_name" {
  # 指定资源类型的参数(Argument)
}

1.2.1. 属性参数引用

当从一个资源块访问另一个资源属性时,使用格式:<resource_type>.<resource_name>.<attribute>

1.2.2. 资源定义考虑事项

  • resource_name 必须唯一。

  • resource_type 资源类型是与提供商关联的关键字,不能由用户自定义。

  • 所有配置参数必须包含在资源块体内,即大括号之间。

  • 所有必填参数必须设置。

1.3. 变量(Variables)

变量用于参数化你的 Terraform 配置。输入变量作为参数供给 Terraform 使用,使其允许在无需更改源配置代码的情况下轻松定制和共享配置。在 Terraform 运行时可以有多种不同的方式来设置其值:环境变量、CLI 参数、键值文件等。

变量必须在 variable 块中声明。建议将所有的变量声明保存在一个名为 variables.tf 的文件中。变量没有必选的参数,因此变量块可以为空,Terraform 可以根据变量值自动推断类型和默认值。

变量名称有两个设置规则:

  • 变量名在模块内必须唯一

  • 变量名不能是关键字,例如:count,for_each等

variable "variable_name" {
    type=<变量类型>
    description=<变量的描述>
    default=<赋予变量的默认值>
    sensitive=<是否是敏感信息>
    validation=<变量值的验证规则>
}

1.3.1. type

type 参数指定了变量接受的值的类型。Terraform 支持以下基本变量类型:

  • bool,用于二进制值,如 true 或 false(不带引号)

  • number,用于数值变量

  • string,用于字符序列

1.3.2. default

要访问模块内声明的变量值,可以使用表达式 var.

resource "alicloud_vpc" "my_vpc" {
  vpc_name    = "main-vpc"
  cidr_block  = var.vpc_cidr_block
  description = ""
}

variable "vpc_cidr_block" {
  default = "10.0.0.0/16"
}

默认值可以通过分配值在环境变量或 .tfvars 文件或 -var 选项中被覆盖,如:

# 通过 CLI -var 选项覆盖变量默认值
$ terraform plan -var vpc_cidr_block="172.16.0.0/16"

1.3.3. sensitive

敏感值的可接受值为true。当设置为true时,变量的值在 terraform plan 或terraform apply 的输出中标记为敏感。

$ terraform plan
Terraform will perform the following actions:

  # alicloud_vpc.my-vpc will be created
  + resource "alicloud_vpc" "my-vpc" {
      + cidr_block            = (sensitive value)   # 标记为敏感信息
      + create_time           = (known after apply)
      + id                    = (known after apply)
      + status                = (known after apply)
      + user_cidrs            = (known after apply)
      + vpc_name              = "main-vpc"
      ...
    }

1.3.4. validation

验证块包含一个条件参数,用于指定验证规则。你可以通过在变量块中包含验证子块来验证赋给变量的值。

在如下示例中,length 和 substr 用作条件参数,验证 vpc_name 的值是否长度超过 4 并且是否以 tf- 为开头:

variable "vpc_name" {
  validation {
    condition     = length(var.vpc_name) > 4 && substr(var.vpc_name, 0, 3) == "tf-"
    error_message = "The vpc name must start with 'tf-' and be longer than 4 characters."
  }
}

1.3.5. 变量的设置方式

# .tfvars 文件(推荐)
$ terraform apply -var-file my-vars.tfvars

# CLI 选项
$ terraform apply -var vpc_cidr_block=“172.16.0.0/16”

# 环境变量
$ export TF_VAR_vpc_dicr_block=“172.16.0.0/16”
$ terraform apply

# 默认的变量文件 terraform.tfvars
$ terraform apply

1.3.6. 变量的最佳实践

  • 只参数化每个实例或环境中会变化的值

  • 尽可能使用 .tfvars 变量文件

  • 给变量起与其使用目的相关的名称

  • 变量必须要有描述,增强 Terraform 配置文件的可读性和可维护性。

1.4. 输出(Outputs)

outputs.tf 文件保存了资源的输出值。由 Terraform 管理的每个资源实例都可以导出属性,这些属性的值可在 Terraform 配置的其他地方被引用。

output "vswitch_id" {
  value = alicloud_vswitch.main_vswitch.id
}

1.5. 状态(State)

Terraform 在状态文件中保存它管理的资源的状态。默认情况下,状态文件是存储在本地,但它也可以远端存储。在团队协作场景中,远端存储通常是首选方法。

不要修改或触碰此文件,它是自动创建和更新的,一旦状态文件损坏,将会导致继续执行 Terraform 失败或者重复创建新的资源。

2. Terraform目录

  • 根模块

    根模块也被称为根配置文件,是运行 Terraform 命令的工作目录。

  • 子模块

    子模块是可选的,每个子模块可以是出于对某类复用功能的抽象,也可以是出于对根模块复杂逻辑的简化。根模块通过对子模块的引用来降低根模块的编写复杂度,提升复用性和可读性。

├── main.tf
├── modules
 ├── network
 │ ├── main.tf
 │ ├── variables.tf
 │ └── outputs.tf
 └── server
   ├── main.tf
   ├── variables.tf
   └── outputs.tf

输出调用关系图

# install graphviz for mac
brew install graphviz
# 生成调用关系
terraform graph | dot -Tsvg > graph.svg

参考: