Terraform的作用
实现跨平台的Infrastructure as Code。目前Terraform支持AWS,Azure, GCP, Oracle Cloud等各种云平台。也就是说,学会了Terraform,就可以用它来定义各种云计算资源了。
有了Terraform,就可以定义各种云资源,比如AWS EC2。一旦创建了EC2,后续就可以使用类似Ansible, Chef, Puppet, Saltstack等运维工具来安装各种软件了。
使用Terraform,可以:
- 从零开始创建系统架构
- 在现有基础上添加、修改系统架构
- 复制系统架构到不同的环境(dev => prod)
Terraform是一种**声明式语言(Declarative)**,指需要声明最终的状态是什么(What),而无需声明如何去做(How),Terraform引擎会自动帮你创建需要的资源。
这和其他类似工具,比如Puppet中,比如声明如何做(How)的imperative方式不同。
Terraform和Ansible的区别
Terraform:用于创建底层架构
Ansible:用于进行系统配置,安装应用程序,升级安全补丁等
两者最好的搭配方式就是:先使用Terraform创建系统架构,然后使用Ansible配置系统中的组件。
Terraform系统架构
配置信息来源
- TF-Config:定义将被创建并部署的系统资源
- State:当前系统状态
Terraform CORE将根据以上信息来决定一个Plan(需要创建/更新/删除哪些资源)。
当前系统状态(current state) =》 期待的系统状态(desired state)
主要组件
- Provider: AWS, Azure, GCP等(IaaS),或Kubernetes(PaaS),或Fastly(SaaS)。Terraform共支持超过100种不同的providers。Provider又分为官方的(比如:Local,AWS,Azure,GCP),经认证的(比如:Heroku, DigitalOcean),Community(比如:ucloud)。Provider就有些像编程语言中的import,导入一个库。
- Resources:根据所选择的provider不同,会有不同的resources可以创建。Terraform共支持超过1000种不同的资源。Resource和Data这两个组件就类似于编程语言中的类实例化,或者对导入库中类/函数的引用。
Terraform运行的几个阶段
- refresh: 获取当前系统架构及其状态
- plan:创建计划
- apply:执行计划
- destroy: 删除资源
mutable vs immutable
更改系统资源有两种选择:
- Mutable: 直接更改原有资源配置
- Immutable:删除原有资源,按照最新配置重新创建新资源
Terraform采用的是immutable这种方式。
Lifecycle rules
create_before_destroy
在默认方式下,terraform会先删除就资源,然后创建新资源,但也可以在定义资源时声明:
resource "local_file" "demo.txt" {
filename = "/tmp/demo.txt"
content = "demo content"
file_permission = "0600"
lifecycle {
create_before_destroy = true
}
}
prevent_destroy
也可以声明不删除资源,尤其是对数据库:
# ...
lifecycle {
prevent_destroy = true
}
}
但需要注意的是,如果运行terraform destory,资源仍会被删除。这个属性只是防止在terraform apply更新资源时删除旧资源。
ignore_changes
当声明这个属性的时候,terraform将会忽略指定的属性更改。也就是说,一旦资源创建后,对该特定属性的更改将被忽略,除非在另一个新环境中重新创建资源。
resource "aws_instance" "web1" {
ami = "ami-xxxxxxxxxxxx"
instance_type = "t2.micro"
tags = {
Name = "production"
}
lifecycle {
ignore_changes = [
tags
]
}
}
有些时候甚至更为极端,当不希望所有资源被更改时:
# ......
lifecycle {
ignore_changes = all
}
}
安装CLI
Linux环境
运行如下命令:
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform
安装完毕后测试一下:
terraform -v
Windows
首先下载terraform: https://www.terraform.io/downloads
然后将可执行文件terraform.exe解压到相应目录下,然后将该目录添加到系统PATH中。
打开命令行窗口,可以进行测试了:
terraform -v
安装Terraform VS Code插件
关于terraform使用的语法
Terraform使用HCL(Hashicorp Configuration Language)来进行声明。例如:
resource "local_file" "demo" {
filename = "/tmp/demo.txt"
content "Demo file"
}
Terraform中的常见文件
- main.tf: 主要资源相关定义都在这里
- variables.tf: 定义各种变量
- outputs.tf:定义输出信息
- provider.tf:包含各种provider的信息
指定provider的版本号
terraform {
required_providers {
local = {
source = "hashicorp/local"
version = "1.4.0"
}
}
}
resource "local_file" "demo" {
# ...
}
关于版本声明非常灵活,比如:
- version = “< 1.4.0”
- version = “> 1.3.0, < 2.0.0, !=1.5.0”
- version = “~> 1.3.0”
关于.gitignore
在Terraform项目中,以下文件是应该被添加到.gitignore中的:
- .terraform/*: 这个目录中包含了下载的各种provider,因此无需提交
- *.tfstate以及*.tfstate.*: 这里包含了Terraform中资源的状态信息
- *.tfvars: 这里包含了一些变量,其中有可能包含敏感信息
需要注意的是,.terraform.lock.hcl应该被保存在repo中,它就有些类似package-lock.json。通过它能够保证不同团队成员都能使用同样版本的provider。
Terraform的内置函数
Terraform有很多内置函数,包括:数字相关,字符串,集合,编码,文件系统,日期和时间,Hash及加密,网络,类型转换类等。具体可以参考官网:https://www.terraform.io/language/functions
Terraform项目的结构
以AWS为例,首先需要针对prod,dev等不同环境创建不同的AWS账户。
然后项目的组织结构类似这样:
├───dev
│ dev.tf
│ provider.tf
│ terraform.tfvars
│
├───modules
│ ├───instances
│ │ instances.tf
│ │
│ └───vpc
│ output.tf
│ vpc.tf
│
└───prod
prod.tf
provider.tf
terraform.tfvars
这样就可以分别进入到dev/prod目录中运行terraform init / terraform apply,进而在不同的环境中创建AWS资源。