您现在的位置是:首页 >其他 >Terraform网站首页其他

Terraform

xyc1211 2023-06-20 20:00:03
简介Terraform

简介

编写一些 配置文件 就可以管理多个云平台上的基础设施。

安装

https://developer.hashicorp.com/terraform/downloads

  • mac brew安装【对xcode版本有要求】
#安装 HashiCorp tap
brew tap hashicorp/tap
 
#使用hashicorp/tap/terraform
brew install hashicorp/tap/terraform

# 验证安装
terraform version

简单使用案例

  1. 新建terraform项目的文件夹
  2. 编写 Terraform 配置文件:创建一个名为的文件main.tf,语法是HCL
  3. 在文件夹下执行terraform命令
# 初始化(下载一个名为 provider 的插件,使terraform与云平台交互)
terraform init

# 把编写的配置 应用在云平台上
terraform apply

# 销毁
terraform destroy

示例项目

https://github.com/hashicorp/learn-terraform-init

概念

原理

通过 配置文件基础设施 进行绑定,将配置文件的改动执行成基础设施的变更

要做到这个,Terraform就需要记住当前基础设施的状态, 才能知道要改动那些资源

状态管理

  • 记录方式: backend
    默认将每次执行操作时的状态信息存储在当前工作目录下的terraform.tfstate文件里

  • 流程
    我们对Terraform的代码进行了一些修改,导致生成的执行计划将会改变状态,那么在实际执行变更之前,Terraform会复制一份当前的tfstate文件到同路径下的terraform.tfstate.backup中,以防止由于各种意外导致的tfstate损毁。

Backend 远程状态存储机制

支持远程状态存储与状态锁

配置语法

https://developer.hashicorp.com/terraform/language

Terraform的配置文件以 “.tf” 结尾

注释

# 		单行注释,其后的内容为注释
// 		单行注释,其后的内容为注释
/* 和 */	多行注释,可以注释多行

Argument 参数

将一个值或表达式赋值给指定的参数名

参数名 = 参数值

参数值的类型支持:

  • 基本类型
    • string:字符串类型,由一个或多个Unicode字符组成,例如 “hello”。
    • number:数字类型,可以表示整数和浮点数。
    • bool:布尔类型,只能是 true 或 false。
  • 集合类型
    • map(…):映射类型,以键值对(key-value pair) 的方式组合起来的数据元素集
      合,其中key为string类型,对应的值可以是string,number,bool等类型,且所
      有元素的值必须是同一类型。
    • list(…):列表类型,具有同类型的数据元素集合,元素可以是基本类型和块类
      型,列表索引从0开始。
    • set(…):集合类型,类似于列表类型,但是集合中的元素是没有任何辅助标识符
      或顺序,且元素具有唯一性。
  • 特殊类型 null

Block 块

块将多个参数聚合在一起,并支持嵌套。块由块类型、块标签和块主体构成

  • 顶级块:可以游离于任何其他块独立定义在配置文件中的块
    Terraform支持的顶层块类型包括:provider,resource,data,variable,output,module,locals等关键字
<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {
  # Block body
  <IDENTIFIER> = <EXPRESSION> # Argument
}

<顶级块类型> "<块标签>" "<块标签>" {
  //块主体
  <参数名>           = "参数值"
  <嵌套块类型> "<块标签>" {
  }
}

terraform块

// Terraform 配置
terraform {
 // 指定 Terraform 版本要求
 required_version = "Terraform版本约束"
 
 // 指定 Provider要求
 required_providers {
 	<Provider1本地名称> {
 	  source  = "Provider源地址, 全球唯一" //registry源
      version = "Provider版本约束"	//版本约束
 	}
 	<Provider2本地名称> {
 	  source  = "Provider源地址, 全球唯一"
      version = "Provider版本约束"
 	}
 }

  // 定义 Terraform 存储其状态数据文件的位置
 backend "backend类型" {
    organization = "example_corp"

    workspaces {
      name = "my-app-prod"
    }
 }
}

required_providers
  1. 必须在required_providers 必须声明需要哪些Provider, 才能安装和使用它们
  2. <本地名称>是特定于模块的,并在需要提供程序时分配。每个模块的本地名称必须是唯一的
  3. 内置供应商:内置于 Terraform 中,因此您无需在required_providers块中声明它即可使用其功能

Terraform 依靠 provider的插件与基础设施 (云提供者、SaaS 提供者和其他 API )进行交互
每种资源类型都由provider实现;没有provider,Terraform 无法管理任何类型的基础设施。

backend
  1. 默认后端local,它将状态存储在磁盘上的本地文件
  2. 更改后端的配置时,必须terraform init再次运行以验证和配置后端
  3. 目前支持的backend类型 及其配置:https://developer.hashicorp.com/terraform/language/settings/backends/local

在这里插入图片描述

provider块: 与基础设施交互

一些provider会要求配置一些信息来使用它们,如:端点URL、云区域…

  • 为 <Provider1本地名称> 提供配置
// 默认配置
provider "<Provider1本地名称>" {
  // Provider需要的配置参数
  region = "1"
  url	 = "1.1.1.1"
 ...
}
// alias 广州 配置
provider "<Provider1本地名称>" {
  alias  = "广州"
  region = "2"
  url	 = "2.2.2.2"
  ...
}
// alias 北京 配置
provider "<Provider1本地名称>" {
  alias  = "北京"
  region = "3"
  url	 = "3.3.3.3"
  ...
}
  1. <Provider1本地名称>应该要已包含在一个required_providers 块中
  2. 用 alias 可以为同一个provider的不同资源提供不同配置
  • 官方支持的provider
    https://developer.hashicorp.com/terraform/language/providers

resource块: 定义基础架构

//resource块
resource "<资源类型>" "<本地名称>" {
  //resource块体
  <资源参数>           = "参数值"
  <资源参数>           = "参数值"
  //metadata块
  metadata {
    //metadata块体
    参数           = "参数值"
  }
}
  1. <资源类型>, <资源参数>: 每个 Terraform 提供者都有自己的文档,描述其资源类型及其参数。
  2. <本地名称>:用于从同一 Terraform 模块的其他位置引用此资源,但在该模块的范围之外没有任何意义

data块: 数据源

Data Source 可以认为是特殊的Resource,通过关键字 “data” 进行声明。
Data Source 用于查询或计算一些已经存在资源的属性和信息 供其他地方使用
每个Data Source都属于一个provider

data "<data类型>" "<本地名称>" {
  // 查询条件
  most_recent = true

  owners = ["self"]
  tags = {
    Name   = "app-server"
    Tested = "true"
  }
}
  • Data Source会导出一个或多个属性。引用ata Source属性的语法是data.<data类型>.<本地名称>.<ATTRIBUTE>
resource  {
  参数           = data.data类型.本地名称.id
}

data类型 和 本地名称 的组合必须是唯一的

表达式(Experssion)和函数(Functions)

支持:

基础运算符
条件表达式
循环

字符串函数
数学计算函数
集合函数
类型转换
加密编码
文件操作

变量

variable 输入变量(入参)

声明变量

variable "<变量名称>" {
  type =  <变量接受的值类型:number、string、bool、list()、set()、map()>
  default = <默认值>
  description = <描述文档>
  validation {
    condition = <验证规则>
    error_message = <报错信息>
  }
  sensitive = true // 是否敏感值,敏感值不打印
  nullable = false // 是否可为空
}

引用变量: var.<变量名称>

resource "aws_instance" "example" {
  instance_type = "t2.micro"
  ami           = var.<变量名称>
}

output 输出变量(出参)

output "<变量名称>" {
  value = <表达式>
  description = <描述文档>
  sensitive = true // 是否敏感值,敏感值不打印

}

local 局部变量

只能在声明它的模块内的表达式中访问

locals  { 
  <名称>  =  <> 
}

// 使用
local.<名称>

Modules 模块

对资源封装,模块是使用 Terraform 打包和重用资源配置的主要方式。

可以引用其他人的模块,发布自己的模块(Terraform Registry托管了大量公开可用的 Terraform 模块)

  1. 模块使用variable 输入变量 接受来自调用模块的值
  2. 使用output 输出变量 将结果返回给调用模块
  • 根模块
    每个 Terraform 配置至少有一个模块,称为它的 根模块.tf
  • 子模块
    被另一个模块调用的模块通常称为子模块

创建模块

  1. 创建一个新目录
  2. 在其中放置一个或多个文件.tf
  • 简单模块可以直接全部定义都放在一个main.tf
|- 模块目录/
|- |- main.tf 【模块入口】
|- |- variables.tf 【输入变量】
|- |- outputs.tf 【输出变量】
  • 复杂模块建议拆分 嵌入模块
|- 模块目录/
|- |- main.tf 
|- |- variables.tf 
|- |- outputs.tf 
|- |- modules/ 	【嵌入模块目录】
|- |- |- 嵌入模块a/
|- |- |- |- main.tf 
|- |- |- |- variables.tf 
|- |- |- |- outputs.tf 
|- |- |- 嵌入模块b/
|- |- |- 嵌入模块c/
|- |- examples/ 【调用样例目录】

调用子模块

调用模块意味着将该模块的内容包含到配置中,并为其 输入变量赋值

module "<子模块本地名称>" { 
  // 模块的参数
  source  = "【必输参数】子模块的源代码路径"
  version = "模块版本"
  <输入变量>  =  <> 
}

使用子模块输出值

module.<子模块本地名称>.<输出值>


cli基本命令

# 检查语法错误
terraform validate

# 格式化代码格式
terraform fmt

# 生成依赖图
terraform graph
# 转为图片格式
terraform graph | dot -Tsvg > graph.svg

terraform init

terraform init会完成代码中所使用到的Provider、Backend、Modules等模块的加载

terraform init -migrate-state

terraform init -reconfigure

terraform workspace 工作空间

# 创建工作区
terraform workspace new [NAME]

# 查看所有的
terraform workspace list
# 查看当前选择的
terraform workspace show

# 选择使用的工作区
terraform workspace select [NAME]

# 删除工作区
terraform workspace delete [NAME]

terraform plan 预览计划、不执行

检测云上资源的属性和状态文件差异,将差异结果显示在命令下方

# 创建变更计划,检查当前的变更是否符合预期
terraform plan

# 输出:
......
Plan: 15 to add, 26 to change, 15 to destroy.

......
No changes. Infrastructure is up-to-date.

Terraform 将您的 Terraform 配置与在该工作区的状态文件中跟踪的真实世界基础设施进行协调,并创建一个资源列表以创建、修改或销毁。

terraform apply 执行计划

# 扫描当前目录下的代码文件(自动创建一个新的变更计划),并执行相应的变更
terraform apply

terraform state 状态管理


# 【废弃】刷新当前 state 文件的配置(远端获取最新数据并将结果写入 state 文件中)
terraform refresh

# 列出当前 state文件中配置的资源
terraform state list
# 展示当前 state文件中配置的资源及其属性值
terraform show
# 展示某个资源的所有属性值
terraform state show <资源类型>.<资源名称>

# 加载您的远程状态并将其输出到标准输出
terraform state pull

# 手动写入状态
terraform state push # 这是极其危险的,应尽可能避免

terraform destroy 销毁资源

# 销毁并回收所有Terraform管理的基础设施资源
terraform destroy
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。