配置语法
- Terraform的配置文件都是以- .tf为后缀
- Terraform支持两种模式- HCL、JSON
Provider 插件
 
providers地址:Terraform Registry
Terraform 通过 provider 管理基础设施,使用 provider 与云供应商 API 进行交互,每个 Provider 都包含相关的资源和数据源。
 
声明 Provider
 
每个 Terraform 模块必须声明它需要哪些 Provider ,以便 Terraform 可以安装和使用它们。
提供者要求在一个 required_providers 块中声明。
## versions.tf
terraform {
  required_providers {
    alicloud = {
      // Provider 源地址
      source = "aliyun/alicloud"
      // Provider 版本
      version = "1.208.0"
    }
  }
}配置 Provider
 
- 关键字 provider
- Provider名称
# Configure the Alicloud Provider
provider "PROVIDER_NAME" {
  // 参数配置
  access_key = var.alicloud.access_key
  secret_key = var.alicloud.secret_key
  region     = var.region
}- 实例
## provider.tf
provider "alicloud" {
  access_key = var.alicloud.access_key
  secret_key = var.alicloud.secret_key
  region     = var.region 
}-  阿里云提供商接受多种输入凭据进行身份验证的方式 - Static credentials
- Environment variables
- Shared credentials/configuration file
- ECS Role
- Assume role
- Sidecar Credentials
 
详细使用查看官网:Terraform Registry
配置多个 Provider
 
可以为同一个 Provider 定义多个配置,并选择基于每个资源或每个模块使用哪一个。这样做的主要原因是支持一个云平台的多个区域。
引用方式:
- <PROVIDER NAME>.<ALIAS>
- alicloud.beiling
- alicloud.hangzhou
在其他配置文件中指定资源区域时,可以使用此模式引用
## provider.tf
provider "alicloud" {
  access_key = var.alicloud.access_key
  secret_key = var.alicloud.secret_key
}
provider "alicloud" {
  alias = "beijing"
  region = "cn-beijing-b"
}
provider "alicloud" {
  alias = "hangzhou"
  region = "cn-hangzhou-a"
}Resource 资源
 
- 资源来自 Provider,是Terraform中最重要的元素。每个资源块描述一个或多个基础对象,例如网络、计算实例或更高级别的组件,例如DNS记录。
- 资源名称必须以字母或下划线开头,并且只能包含字母、数宇、下划线和破折号。
resource "resource_type" "name" {
  // resource_config
}Resource-ECS 资源
 
Terraform Registry
定义一台 ECS 实例
- 可用区
- 安全组
- 实例规格
- 系统盘类型
- 名称描达
- 镜像
- 实例名称
- 交换机
- 带宽
- 付费类型
- 账户密码
## alicloud_ecs.tf
resource "alicloud_instance" "myecs" {
    // 可用区
    availability_zone = var.region
    // 安全组,需要提前定义生成
    security_groups = alicloud_security_group.group.*.id
    // 实例规格
    instance_type = "ecs.n1.tiny"
    // 系统磁盘类型
    system_disk_category = "cloud_efficiency"
    // 系统磁盘名称
    svstem_disk_name = "tf_svstem_disk_name"
    // 系统盘描述
    system_disk_description = "tf_system_disk_description"
    // 系统镜像ID
    image_id = "centos7_5_X64_206_allbase_20211130.vhd"
    // 实例名称
    instance_name = "mytestecs"
    // 交换机,需要提前定义生成
    switch_id = alicloud_vswitch.vsw.id
    // 带宽
    internet_max_bandwidth_out = 1
    // 付费类型
    internet_charge_type = "PayByTraffic"
    // 账号密码
    password = "root@123"
}Resource-DNS 资源
 
Terraform Registry
定义一条 DNS 解析记录
- ZoneName: evescn.site
- Type: A
- Record: demo
- 完整域名:demo.evescn.site
## alicloud_dns.tf
## TYPE A
## demo.evescn.com
# 老版本 API
resource "alicloud_dns_record" "record" {
  name        = "evescn.com"
  host_record = "demo"
  type        = "A"
  value       = alicloud_instance.mytestecs.public_ip
}
# 新版本 API
resource "alicloud_alidns_record" "record" {
  domain_name = "evescn.com"
  rr          = "demo"
  type        = "A"
  value       = alicloud_instance.mytestecs.public_ip
  remark      = "demo-web"
  status      = "ENABLE"
}DataSource 
 
Data数据源
 
Terraform Registry
datasource 提供资源的数据,可以通过参数过滤数据并供其他模块引用;使用 data 块声明
- 过滤阿里云上 centos_7 x86_64 镜像
data "alicloud_images" "images_ds" {
  owners     = "system"
  name_regex = "^centos_7"
  architecture = "x86_64"
}
// output 把值传递出去,给其他地方引用
output "first_image_id" {
  value = "${data.alicloud_images.images_ds.images.0.id}"
}DataSource 引用
 
ecs 配置创建替换 image_id。
resource "alicloud_instance" "myecs" {
    availability_zone = var.region
    security_groups = alicloud_security_group.group.*.id
    instance_type = "ecs.n1.tiny"
    system_disk_category = "cloud_efficiency"
    svstem_disk_name = "tf_svstem_disk_name"
    system_disk_description = "tf_system_disk_description"
    // 私有 datasource output 变量,替换此处
    image_id = data.alicloud_images.images_ds.images.0.id
    instance_name = "mytestecs"
    switch_id = alicloud_vswitch.vsw.id
    internet_max_bandwidth_out = 1
    internet_charge_type = "PayByTraffic"
    password = "root@123"
}Variables 变量
 
变量允许自定义 Terraform 模块,而无需更改模块自己的源代码。这可以实现跨不同的 Terraform 配置共享模块,使模缺可组合和可重用。
variable "alicloud_access_key" {
  type = string
}
variable "alicloud_secret_key" {
  type = string
}
variable "region" {
  type = string
}- 在variables.tf文件中定义变量;
- 在同一个模块的所有变量中必须是唯一的;
- 可以从环境变量或者文本文件中读取;
- Terraform默认读取- terraform.tfvars;
Variable 可选参数
 
- default变量的默认值
- type变量的类型
- description变量的描述信息
- validation定义变量验证规则
- sensitive限制变量在UI中显示
- nullable变量是否可为空
variable "region" {
  type = string
  description = "region name"
  default = "cn-beijing"
  sensitive = true
}Variable 参数类型
 
- any
- string
- number
- bool
- list()
- set()
- map()
- object([ATTR_NAME = ATTR_TYPE, ...)
- tuple([, ...])
Variable Map
 
示例:使用
map类型的变量来定义DNS域名
## variables.tf
variable "dns_record" {
  type = map(string)
  description = "define dns name"
}## terraform.tfvars
dns_record = {
  "dev"  = "dev-nginx",
  "stag" = "stag-nginx",
  "prod" = "prod-nginx",
}- 引用环境变量
定义一条 DNS 解析记录。
## alicloud_dns.tf
## TYPE A
## demo.evescn.com
# 老版本 API
resource "alicloud_dns_record" "record" {
  name        = "evescn.com"
  // 引用环境变量
  host_record = var.dns_record["dev"]
  type        = "A"
  value       = alicloud_instance.mytestecs.public_ip
}
# 新版本 API
resource "alicloud_alidns_record" "record" {
  domain_name = "evescn.com"
  // 引用环境变量
  rr          = var.dns_record["dev"]
  type        = "A"
  value       = alicloud_instance.mytestecs.public_ip
  remark      = "demo-web"
  status      = "ENABLE"
}Variable List
 
示例:使用
list类型的变量来定义环境列表
## variables.tf
variable "env_list" {
  type = list(string)
  description = "deploy env name"
}## terraform.tfvars
env_list = [ "dev", "stag", "prod" ]Variable object
 
示例:使用
object类型的变量来定义ECS属性信息
## variables.tf
variable "ecs_info" {
  type = object({ ecs_image = string, ecs_name = string })
}## terraform.tfvars
ecs_info = {
  ecs_image = "centos_7_5_x64_20G_alibase_20211130.vhd"
  ecs_name = "evescn"
}Variable 的使用方式
 
在变量声明后,可以使用 var.VAR_NAME 的方式引用;VAR_ NAME即variables.tf定义;
- 环境娈量
- terraform.tfvars | terraform.tfvars.json
- *.auto.tfvars | *.auto.tfvars.ison
- 命令行 -var | -var-file
## -var
terraform apply -var="region=cn-beijing"
terraform apply -var='env_list=["dev", "stag", "prod"]' -var="region=cn-beijing"## -var-file
terraform apply -var-file="dev.tfvars"## env
export TF_VAR_region='cn-beijing'
export TF_VAR_env_list='["dev", "stag", "prod"]'locals 局部变量
 
局部、本地变量;局部值有助于避免在配置中多次重复相同的值或表达式;
## 定义
locals {
  ecs_name = "evescn"
  owner    = "evescn"
}## 引用
local.ecs_name
local.ownerOutput 输出变量
 
output可以打印已定义的变量,并且可以公开信息以供其他Terraform配置使用。输出值类似于编程语言中的返回值。
## outputs.tf
output "dev_dns_name" {
  value = alicloud_dns_record.record.host_record
} Output 可选参数
 
- description变量的描述信息;
- sensitive限制变量在- UI中显示;
- depends_on依赖关系
Output-子模块之间的引用
 
例如: 如果一个名为ecs_server的子模块 声明了一个名为 instance_ip_addr 的输出,则可以将该值作为module.ecs_server.instance_ip_addr
module.<MODULE NAME>.<OUTPUT NAME>
Terraform 模版
 
Terraform 可以更轻松地扩展基础架构并保持其配置整洁。但是,随着基础架构的增长,单个目录变得难以管理。我们这个时候就需要使用模块
Module 简介
 
Terraform 模块是一种可重用现有代码的方法,减少基础设施组件开发的代码量。Terraform 模块是一个或者多个 .tf 文件集合。

实际上任何 Terraform 配置本身已经是一个模块。如果在此目录中运行 Terraform,则这些配置文件将被视为根模块
Module 语法
 
- name:模块的名称,在terraform中可以使用模块名称进行引用
- source:模块代码的路径,本地或者远程的仓库
- version:版本信息;
module "name" {
  source     = "xxx.io/your-org/terraform_test_module"
  version    = "1.0.0"
  argument_1 = var.test_1
  argument_2 = var.test_2
}Module 工作原理
 
- 远程模块:存储到根模块下的.terraform目录中(修改后,必须get/init)
- 本地模块:将通过软连接的方式引用本地的源目录(修改后,无需操作)
使用 terraform get 下载模块;
 使用 terraform graph 查看模块; -module-depth 汇总对象;
Module 调用方式
 
本地文件: "./module_name"TF注册表: "hashicorp/consul" "hashicorp/aws"
GitHub:
- http "github.com/hashicorp/example"
- ssh "git@github.com:hashicorp/example.git"
 bucket: "bitbucket.org/hashicorp/terraform-consul-aws"
通用Git:
- http: "git::https://example.com/vpc.git"
- ssh: "git::ssh://username@example.com/storage.git"
Module 输入、输出变量
 
模块的输出值,便于其他模块引用
 引用方式: module.MODULE_NAME.OUTPUT_NAME
Module 实例化
 
一个模块可以被多次实例化;
 每个实例定义唯一的名称,指定相同的 source 来源;
module "dev_ecs" {
  source = "./module/ecs"
  instance_name = "ecs_01"
}module "prod_ecs" {
  source = "./module/ecs"
  instance_name = "ecs_02"
}Module 模块优点
 
- 解决代码重复问题;
- 加强代码可读性,代码整洁性;
- 资源标准化;
- 减少人为错误发生频率;
Expressions 表达式#
 
条件表达式
condition ? true_val : false_valcondition 条件 (返回值true/false)
- true_val 条件为true的值
- false_val 条件为false的值
DEMO-条件表达式
var.region != "" ? var.region: "cn-beijing"当region变量存在时 region = var.region, 反之 region = “cn-beijing”
- for表达式
[ for VAR in OBJECT : VAR]
[ for INDEX, VAR in OBJECT: "${INDEX}=${VAR}"]借助for表达式可以对数据进行处理,生成新的数据对象;
> [ for e in var.env_list: e ]
[
  "dev",
  "stag",
  "prod",
]
> [ for i,e in var.env_list: "${i} = ${e}" ]
[
  "0 = dev",
  "1 = stag",
  "2 = prod",
]> var.dns_record
tomap({
  "dev" = "dev.app"
  "prod" = "prod.app"
  "stag" = "stag.app"
})
> [ for k,v in var.dns_record : "${k} ${v}" ]
[
  "dev dev.app",
  "prod prod.app",
  "stag stag.app",
]- splat表达式
splat 表达式提供了一种更简洁的方式来表达可以用for表达式执行的常见操作。
var.list[*].attr> var.user_role
[
  {
    "name" = "evescn"
    "role" = "admin"
  },
  {
    "name" = "hlr"
    "role" = "develop"
  },
]
> var.user_role[*].name
[
  "evescn",
  "hlr",
]
> var.user_role.*.name
[
  "evescn",
  "hlr",
] Terraform 函数
 
Functions - Configuration Language | Terraform | HashiCorp Developer
Terraform 语言包括许多内置函数,可以从表达式中调用这些函数来转换。函数调用的一般语法是函数名后跟括号中以逗号分隔的参数。
function(arg1,arg2)- 数值函数
| 函数 | 功能 | 
|---|---|
| max | 获取最大值 | 
| min | 获取最大值 | 
| parseint("string", N) | 将字符串解析为整数,N 表示转换为 N 进制 | 
…将集合扩展为单个参数
max(1,2,3,4,5)
max([1,2,3,4,5]…)
min(1,2,3,4,5)
min([1,2,3,4,5]…)
parseint("101", 10)- String字符串函数
| 函数 | 功能 | 
|---|---|
| format | 格式化 | 
| join | 字符串拼接 | 
| replace | 替换字符串 | 
| split | 字符串分割 | 
format("Hello %s!", "evescn")
join(",", ["name","age","title"])
replace("a=b=c", "=","-")
split(",", "name,age,title")- Collection集合函数
| 函数 | 功能 | 
|---|---|
| alltrue() anytrue() | 判断元素中都是、存在true | 
| chunklist( list, size) | 按照指定size拆分list | 
| compat(list) | 去除list中的空元素 | 
| concat(list1, list2) | 合并两个list | 
| contains(list, value) | 判断元素是否存在list中 | 
| distinct(list) | 去除list中的重复元素 | 
| element(list, index) | 根据index获取list中的元素 | 
| list[index] | 根据index获取list中的元素 | 
| flatten(list,list,list) | 将多层list转换成单list | 
| index(list, value) | 返回value元素的index | 
- Map映射函数
| 函数 | 功能 | 
|---|---|
| length(list) | 计算list的长度 | 
| lookup(map,key,default) | 检索map的key,不存在返回default | 
| merge(map1,map2,map3) | 合并map,相同key会被最后覆盖 | 
| keys(map) | 建map中key的list | 
| values(map) | 创建map中value的list | 
















![洛谷P1115最大子段和[神奇的题目]](https://img-blog.csdnimg.cn/direct/155dafcd3b234ce194bddb2e02edb72a.png)


