HCL 语法基础 #
什么是 HCL? #
HCL(HashiCorp Configuration Language)是 HashiCorp 开发的配置语言,专门用于定义基础设施配置。它是一种声明式语言,设计目标是既易于人类阅读和编写,又易于机器解析和处理。
text
┌─────────────────────────────────────────────────────────────┐
│ HCL 特点 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 声明式 │ │ 可读性强 │ │ JSON 兼容 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 类型丰富 │ │ 表达式强大 │ │ 模块化 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
基本语法结构 #
顶层结构 #
HCL 配置由一系列顶层块组成:
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
块(Block) #
块是 HCL 的核心结构,用于定义配置对象:
text
┌─────────────────────────────────────────────────────────────┐
│ 块的结构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ <块类型> "<标签1>" "<标签2>" { │
│ <参数名> = <参数值> │
│ <参数名> = <参数值> │
│ } │
│ │
│ 示例: │
│ resource "aws_instance" "example" { │
│ ami = "ami-123456" │
│ instance_type = "t2.micro" │
│ } │
│ │
│ 组成部分: │
│ - 块类型:resource │
│ - 标签:aws_instance, example │
│ - 块体:大括号内的内容 │
│ │
└─────────────────────────────────────────────────────────────┘
常见块类型 #
hcl
terraform {
required_version = ">= 1.0.0"
}
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
data "aws_ami" "latest" {
most_recent = true
owners = ["amazon"]
}
variable "instance_type" {
default = "t2.micro"
description = "EC2 instance type"
}
output "instance_ip" {
value = aws_instance.example.public_ip
}
locals {
common_tags = {
Environment = "dev"
Project = "my-project"
}
}
module "vpc" {
source = "./modules/vpc"
cidr_block = "10.0.0.0/16"
}
参数与参数值 #
参数定义 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
monitoring = true
count = 3
}
参数值类型 #
text
┌─────────────────────────────────────────────────────────────┐
│ 基本类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 字符串 (string) │
│ ami = "ami-0c55b159cbfafe1f0" │
│ name = "my-instance" │
│ │
│ 数字 (number) │
│ count = 3 │
│ port = 8080 │
│ size = 100.5 │
│ │
│ 布尔值 (bool) │
│ enabled = true │
│ monitoring = false │
│ │
│ 空值 (null) │
│ description = null │
│ │
└─────────────────────────────────────────────────────────────┘
复合类型 #
hcl
list_of_strings = ["a", "b", "c"]
list_of_numbers = [1, 2, 3, 4, 5]
map_of_strings = {
key1 = "value1"
key2 = "value2"
}
map_of_numbers = {
small = 1
medium = 2
large = 3
}
set_of_strings = toset(["a", "b", "c"])
object_type = {
name = "example"
size = 10
tags = ["web", "frontend"]
}
tuple_type = ["string", 123, true]
注释 #
单行注释 #
hcl
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
多行注释 #
hcl
/*
* 这是一个多行注释
* 可以跨越多行
* 用于详细说明
*/
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
字符串 #
字符串字面量 #
hcl
name = "my-instance"
description = 'Simple description'
多行字符串 #
hcl
user_data = <<-EOF
#!/bin/bash
echo "Hello, World!"
yum update -y
yum install -y httpd
systemctl start httpd
EOF
字符串插值 #
hcl
name = "instance-${var.environment}"
url = "https://${var.domain}/api"
message = "Hello, ${var.name}!"
字符串模板 #
hcl
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "s3:GetObject"
Effect = "Allow"
Resource = "arn:aws:s3:::${var.bucket_name}/*"
}
]
})
集合类型 #
列表(List) #
hcl
variable "availability_zones" {
type = list(string)
default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}
resource "aws_subnet" "example" {
count = length(var.availability_zones)
availability_zone = var.availability_zones[count.index]
}
映射(Map) #
hcl
variable "instance_types" {
type = map(string)
default = {
dev = "t2.micro"
staging = "t2.small"
prod = "t2.medium"
}
}
resource "aws_instance" "example" {
instance_type = var.instance_types[var.environment]
}
集合(Set) #
hcl
variable "ports" {
type = set(number)
default = [80, 443, 8080]
}
resource "aws_security_group_rule" "ingress" {
for_each = var.ports
type = "ingress"
from_port = each.value
to_port = each.value
protocol = "tcp"
security_group_id = aws_security_group.example.id
}
对象与元组 #
对象类型 #
hcl
variable "server_config" {
type = object({
name = string
instance_type = string
volume_size = number
tags = map(string)
})
default = {
name = "web-server"
instance_type = "t2.micro"
volume_size = 20
tags = {
Environment = "dev"
}
}
}
元组类型 #
hcl
variable "mixed_values" {
type = tuple([string, number, bool])
default = ["hello", 42, true]
}
表达式 #
算术运算 #
hcl
sum = 1 + 2
difference = 10 - 5
product = 3 * 4
quotient = 15 / 3
modulo = 10 % 3
negation = -5
比较运算 #
hcl
equal = 5 == 5
not_equal = 5 != 3
greater = 10 > 5
less = 3 < 5
greater_eq = 5 >= 5
less_eq = 3 <= 5
逻辑运算 #
hcl
and_op = true && false
or_op = true || false
not_op = !true
条件表达式 #
hcl
instance_type = var.environment == "prod" ? "t2.large" : "t2.micro"
size = var.create_large ? 100 : 50
name = var.name != "" ? var.name : "default-name"
for 表达式 #
hcl
simple_list = [for s in var.list : upper(s)]
with_filter = [for s in var.list : upper(s) if s != ""]
map_transform = {for s in var.list : s => upper(s)}
with_index = [for i, s in var.list : "${i}: ${s}"]
nested = [for item in var.items : item.name if item.enabled]
展开表达式 #
hcl
variable "availability_zones" {
default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}
resource "aws_subnet" "example" {
for_each = toset(var.availability_zones)
availability_zone = each.value
}
subnets = aws_subnet.example[*].id
names = [for item in var.items : item.name...]
splat 表达式 #
hcl
resource "aws_instance" "example" {
count = 3
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
all_ids = aws_instance.example[*].id
all_ips = aws_instance.example[*].public_ip
first_ip = aws_instance.example[0].public_ip
动态块 #
基本语法 #
hcl
resource "aws_security_group" "example" {
name = "example-sg"
dynamic "ingress" {
for_each = var.ingress_rules
content {
from_port = ingress.value.from_port
to_port = ingress.value.to_port
protocol = ingress.value.protocol
cidr_blocks = ingress.value.cidr_blocks
}
}
}
带迭代器 #
hcl
resource "aws_security_group" "example" {
name = "example-sg"
dynamic "ingress" {
for_each = var.ingress_rules
iterator = rule
content {
from_port = rule.value.from_port
to_port = rule.value.to_port
protocol = rule.value.protocol
cidr_blocks = rule.value.cidr_blocks
}
}
}
嵌套动态块 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
dynamic "ebs_block_device" {
for_each = var.ebs_volumes
content {
device_name = ebs_block_device.value.device_name
volume_size = ebs_block_device.value.size
dynamic "tags" {
for_each = ebs_block_device.value.tags
content {
key = tags.key
value = tags.value
}
}
}
}
}
类型约束 #
基本类型约束 #
hcl
variable "name" {
type = string
}
variable "count" {
type = number
}
variable "enabled" {
type = bool
}
复杂类型约束 #
hcl
variable "names" {
type = list(string)
}
variable "ports" {
type = list(number)
}
variable "tags" {
type = map(string)
}
variable "config" {
type = object({
name = string
size = number
})
}
variable "items" {
type = tuple([string, number, bool])
}
any 类型 #
hcl
variable "value" {
type = any
}
可选属性 #
hcl
variable "config" {
type = object({
name = string
size = optional(number, 10)
tags = optional(map(string), {})
})
}
文件组织 #
推荐的文件结构 #
text
project/
├── main.tf 主配置文件
├── variables.tf 输入变量定义
├── outputs.tf 输出值定义
├── providers.tf Provider 配置
├── locals.tf 本地值定义
├── data.tf 数据源定义
├── versions.tf 版本约束
├── terraform.tfvars 变量值文件
└── README.md 项目说明
文件命名约定 #
hcl
main.tf 主要资源配置
variables.tf 变量定义
outputs.tf 输出定义
providers.tf Provider 配置
backend.tf 后端配置
versions.tf 版本约束
data.tf 数据源
locals.tf 本地值
modules.tf 模块调用
JSON 语法 #
HCL 也支持 JSON 格式:
json
{
"resource": {
"aws_instance": {
"example": {
"ami": "ami-0c55b159cbfafe1f0",
"instance_type": "t2.micro",
"tags": {
"Name": "example-instance"
}
}
}
}
}
代码风格 #
格式化 #
bash
terraform fmt
推荐风格 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
Environment = var.environment
}
root_block_device {
volume_size = 20
volume_type = "gp3"
}
}
对齐参数 #
hcl
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
monitoring = true
disable_api_termination = false
}
下一步 #
掌握了 HCL 语法基础后,接下来学习 第一个资源,实际创建一个基础设施资源!
最后更新:2026-03-29