一、基础介绍
Terraform是HashiCorp公司推出的基础设施管理工具,以简洁的声明式语言,以及多云管理能力,使得备受运维工作者青睐。Terrform配置文件所使用的语言为HCL(HashiCorp配置语言)。.tf文件书写规范,需要遵守HCL语法,以及各厂商provider定义的资源管理规范。
二、.tf配置文件组成
tf配置文件由不同的资源块组成,主要包含required_providers,provider,resource,data,module。
- required_providers字段
required_providers:声明本tf文件所使用的provider和版本
# 本文使用字节跳动旗下云计算平台-火山引擎的provider
terraform {
required_providers {
volcengine = {
source = "volcengine/volcengine" #火山引擎provider
version = ">=0.0.46"
}
}
}
version参数声明provider版本,可以指定固定版本,比如version = "0.0.46"
,也可以指定版本范围,比如version >= "0.0.46"
,代表大于等于0.0.46的任何版本都可以满足本tf文件的资源管理需求。
- provider字段
provider资源块,声明region,同一个tf文件可以声明多个region,便于管理多region的资源。
当管理多region资源时,一定要为每个region设置一个alias,方便不同资源管理模块选择所需的region。未设置alias的region会被当成默认region。
# 声明广州region的alias为gz
provider "volcengine" {
alias = "guangzhou"
region = "cn-guangzhou"
}
# 声明上海region的alias为sh
provider "volcengine" {
alias = "shanghai"
region = "cn-shanghai"
}
resource块下指定region的方法为,在resource块里加上provider = volcengine.shanghai
(以上面定义的火山引擎上海region为例)即可。
- resource字段
resource:是terraform最重要的元素之一,用来描述一个或多个资源对象,比如vpc,ecs,eip等
#管理eip的resource资源块
resource "volcengine_eip_address" "yuan" {
billing_type = "PostPaidByTraffic"
bandwidth = 100
isp = "BGP"
name = "tf-yuanjy"
description = "tf-yuanjy"
}
#管理eip和instance之间的绑定关系的resource资源块
resource "volcengine_eip_associate" "yuan" {
allocation_id = volcengine_eip_address.yuan.id
instance_id = volcengine_ecs_instance.yuan.id
instance_type = "EcsInstance"
}
- data resource字段
data resource:data可以用来查询和使用非terraform定义的资源,比如通过控制台创建的资源。
#查询ssh密钥对的信息,密钥对名字包含“jiaoyang”
data "volcengine_ecs_key_pairs" "yuan" {
name_regex = "jiaoyang" # 模糊查询使用用name_regex
}
每个provider都要提供resource和data resource资源管理规范,类似于api文档。比如volcengine provider规范。
- module字段
- 每个terraform至少有1个module,即1个根module,若干子module。每个module可以包含一个主配置文件main.tf,一个定义输入变量的文件variables.tf,和一个定义输出变量的文件outputs.tf。
main.tf
:module内的主配置文件,resource和data resource块均在该文件中进行描述。outputs.tf
:用来声明module的输出变量- 根module下的outpus.tf才会在plan或apply后输出,仅在子module内定义的output变量不会输出到state文件。
- 子module之间的output可以相互调用。
variables.tf
:main.tf的输入变量。
variables.tf样例
#file modules/ecs/variables.tf
variable "subnet_id" {
type = string
}
variable "security_group_ids" {
type = list(string)
}
output.tf样例
$ cat outputs.tf
# /dev/modules/vpc/outputs.tf
output "subnet_ids" {
value = volcengine_vpc.xu.subnet_ids
}
output "sg_ids" {
value = volcengine_security_group.xu-gz.id
}
state文件-状态管理常用命令
state一个自动生成的状态文件。它记录被terraform管理的资源的最新状态,文件名terraform.tfstate
。每次执行apply时,terraform会比对configuration与state之间的差异,如果有差异,则按configuration执行资源变更,如果没有,则什么都不执行。
Terraform 对资源状态的管理,实际上是对State文件中数据的管理。 State文件保存了当前Terraform管理的所有资源及其属性,内容都是由Terraform自动存储的,为了保证数据的完整性,不建议手动修改State内容。 对State数据的操作可以通过 terraform state 命令来完成。
TERRAFORM STATE LIST
state list 列出当前state中的所有资源 按照 <资源类型>.<资源名称> 的格式列出当前state中存在的所有资源(包括datasource) $ terraform state list data.alicloud_slbs.default alicloud_vpc.default alicloud_vswitch.this
TERRAFORM STATE SHOW
state show 展示某一个资源的属性 该命令按照Key-Value的格式展示出特定资源的所有属性及其值,命令的完整格式为 terraform state show <资源类型>.<资源名称> $ terraform state show alicloud_vswitch.this # alicloud_vswitch.this: resource "alicloud_vswitch" "this" availability_zone = "eu-central-1a" cidr_block = "172.16.0.0/24" id = "vsw-gw8gl31wz******" vpc_id = "vpc-gw8calnzt*******"
TERRAFORM GRAPH -DRAW-CYCLES | DOT -TSVG > GRAPH.SVG
生成依赖关系图 # 安装dot,graphviz http://www.graphviz.org/download/ yum install graphviz
- Meta-arguments字段
terraform的hcl语言包含一些元参数,在resource、output、variable等资源块下可使用。这些经常被用到的元参数是count,for_each,for。
count:用于同时创建多个相同资源,count_index作为索引。
variable "name_list" {
type = list(string)
default = ["vpc_demo1", "vpc_demo2"]
}
variable "cidr_list" {
type = list(string)
default = ["192.168.0.0/16", "172.16.0.0/16"]
}
resource "volcengine_vpc" "vpcs" {
count = 2
name = var.name_list[count.index]
cidr = var.cidr_list[count.index]
}
for_each:用于同时创建多个不同资源,用each.key,each.value为特定参数赋不同的值。
resource "volcengine_security_group" "bj" {
vpc_id = "vpc-13ffv1kye1f5s3n6nu45nes7s"
for_each = toset(["abraham","bob","cotton","tommy"])
security_group_name = each.key
}
for
for,和python中的for循环用法一样,为循环语句。
以下样例中,通过data查询到的所有ubuntu镜像的信息,查询结果包含镜像数十个,每个镜像都有十几种参数。data的格式是一个列表,列表中的元素是map。我只想输出每个镜像中的image_name和image_id信息,就可以使用for循环,依次取出这两个参数,并存放在map对象中。
#查找Ubuntu的所有镜像版本
data "volcengine_images" "default" {
name_regex = title("ubuntu")
}
output "image_info" {
value = [for i in data.volcengine_images.default.images:{
image_name=i["image_name"],
image_id=i["image_id"]
}
]
}
HCL语言支持的数据结构
- string: 字符串,比如 “hello”
- number: 数值。比如整数 15 ,小数 6.283185
- bool: 布尔值, true or false
- list: 列表,比如 [“cn-beijing”, “cm-shanghai”]
- map: 类似于字典,包含一组key,value。比如 {name = “Mabel”, age = 52}