# 语法介绍

Terraform配置语言（简称称HCL，Terraform Configuration Language）是描述并操作通过Terraform管理的基础设施的重要凭据。

通过该语言编写的配置文件，您可以告诉Terraform：

* 需要安装哪些插件
* 需要创建哪些基础设施
* 需要获取哪些数据

Terraform配置语言还允许您定义资源之间的依赖关系，且允许使用单个配置块管理多个相似的资源，具有配置简单，可读性强等特点，并且兼容JSON语法。

## 关于Terraform语言

Terraform语言的主要目的是声明**资源（resources）**，这些资源代表基础设施对象。其他所有语言特性的存在都是为了使资源定义更加灵活和方便。

**Terraform配置**是Terraform语言中的一个完整文档，它告诉Terraform如何管理给定的基础设施集合。一个配置可以由多个文件和目录组成。

### 基本语法元素

Terraform 语言的语法由以下几个基本元素组成：

```hcl
<块类型> "<块标签>" "<块标签>" {
  # 块内容（包括但不仅限于元参数、变量定义）
  <标识符> = <表达式>
}
```

1. **块（Blocks）**：作为其他内容的容器，通常表示某种对象的配置，如资源。块有一个**块类型**，可以有零个或多个**标签**，并有一个**块体**，包含任意数量的参数和嵌套块。Terraform的大部分功能由配置文件中的顶级块控制。
2. **参数（Arguments）**：为名称赋值。它们出现在块内。
3. **表达式（Expressions）**：表示一个值，可以是字面值或通过引用以及组合值来表示。它们作为参数的值出现，或在其他表达式中出现。

### 声明式特性

Terraform语言是声明式的，描述期望的目标状态而不是达到该目标的步骤。块和文件的组织顺序通常不重要，它们会在Terraform配置文件被执行时由Terraform绘制执行图并确定其执行顺序，在声明时仅需考虑资源之间的隐式和显式引用关系。

## 配置示例

以下示例描述了华为云的一个简单网络拓扑，展示了Terraform语言的整体结构和语法。类似的配置可以应用至其他服务所提供的的资源类型中，实际的网络配置通常包含此处未显示的其他元素。

```hcl
terraform {
  required_providers {
    huaweicloud = {
      source  = "huaweicloud/huaweicloud"
      version = ">= 1.76.0"
    }
  }
}

variable "region_name" {}

provider "huaweicloud" {
  region = var.region_name
}

variable "vpc_name" {
  description = "VPC的名称，必填参数"
}

variable "vpc_cidr_block" {
  description = "VPC将使用的/16 CIDR范围定义，如192.168.0.0/16，选填参数"
  default     = "192.168.0.0/16"
}

resource "huaweicloud_vpc" "test" {
  # 通过引用vpc_name和vpc_cidr_block变量的最终值（可选参数如缺省则采用默认值）创建VPC网络
  name = var.vpc_name
  cidr = var.vpc_cidr_block
}

variable "subnet_name" {
  description = "子网的名称，必填参数"
}

variable "availability_zones" {
  description = "要在VPC中创建的子网的所属可用区信息"
  type        = list(string)
}

resource "huaweicloud_vpc_subnet" "test" {
  # 通过遍历可用区列表，为每个给定的可用区都创建一个子网
  count = length(var.availability_zones)

  # 对于每个子网，使用指定的可用区之一
  availability_zone = var.availability_zones[count.index]

  # 通过引用huaweicloud_vpc.test对象的属性构建隐式依赖（必填参数由于其值在创建前已经确定，故不构成隐式依赖），让Terraform知道子网必须待VPC创建完成后才能开始创建
  vpc_id = huaweicloud_vpc.test.id

  name = var.subnet_name
  # 内置函数和运算符可用于值的简单转换，如计算子网地址
  # 为每个子网创建一个/20前缀且连续的地址块
  cidr = cidrsubnet(huaweicloud_vpc.test.cidr, 4, count.index+1)
  # 函数可以引用其他函数的计算结果
  # 使用除广播地址外的首个地址范围内的IP地址作为子网的网关
  gateway_ip = cidrhost(cidrsubnet(huaweicloud_vpc.test.cidr, 4, count.index+1), 1)
}
```

## 基础知识学习

要掌握Terraform配置语言的核心概念，建议按以下顺序学习基础知识：

1. [配置语言基础](https://developer.hashicorp.com/terraform/language)
   * **文件和目录结构**：了解Terraform配置文件的组织方式，包括`.tf`文件、变量文件、状态文件等
   * **语法规则**：掌握HCL语法的基础规则，包括块、参数、表达式的正确写法
   * **资源和数据源**：理解资源与数据源的区别，以及它们在配置中的作用
2. [资源和数据源](https://developer.hashicorp.com/terraform/language/resources)
   * **资源行为**：了解资源的状态管理、创建、更新、删除等生命周期行为
   * **依赖关系**：掌握资源间的隐式和显式依赖关系，以及Terraform如何解析这些依赖
   * **元参数**：学习count、for\_each、depends\_on等元参数的使用方法
3. [变量和输出](https://developer.hashicorp.com/terraform/language/values)
   * **变量定义**：掌握输入变量的定义、类型约束、默认值设置等
   * **输出值**：了解输出值的定义和使用，以及如何在其他配置中引用
   * **本地值**：学习本地值的概念和使用场景，提高配置的可维护性
4. [表达式](https://developer.hashicorp.com/terraform/language/expressions)
   * **引用表达式**：掌握如何引用资源属性、变量、数据源等
   * **运算符**：学习算术、逻辑、比较等运算符的使用
   * **条件表达式**：了解条件表达式的语法和应用场景

## 深入学习

在掌握基础知识后，可以进一步学习以下高级特性：

1. [函数](https://developer.hashicorp.com/terraform/language/functions)
   * 内置函数
   * 数字函数
   * 字符串函数
   * 集合函数
2. [模块](https://developer.hashicorp.com/terraform/language/modules)
   * 模块使用
   * 模块创建
   * 模块组合

> **实践建议：** 尝试[Terraform配置编写教程](https://developer.hashicorp.com/terraform/tutorials/configuration-language)。

其他内容通过以下链接进行学习：

* [Terraform 官方文档](https://developer.hashicorp.com/terraform/language)
