Terraform教程01 - 简介


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会先删除就资源,然后创建新资源,但也可以在定义资源时声明:

terraform
resource "local_file" "demo.txt" {
  filename = "/tmp/demo.txt"
  content = "demo content"
  file_permission = "0600"

  lifecycle {
    create_before_destroy = true
  }
}

prevent_destroy

也可以声明不删除资源,尤其是对数据库:

terraform
  # ...
  lifecycle {
    prevent_destroy = true
  }
}

但需要注意的是,如果运行terraform destory,资源仍会被删除。这个属性只是防止在terraform apply更新资源时删除旧资源。

ignore_changes

当声明这个属性的时候,terraform将会忽略指定的属性更改。也就是说,一旦资源创建后,对该特定属性的更改将被忽略,除非在另一个新环境中重新创建资源。

terraform
resource "aws_instance" "web1" {
  ami = "ami-xxxxxxxxxxxx"
  instance_type = "t2.micro"
  tags = {
    Name = "production"
  }
  lifecycle {
    ignore_changes = [
      tags
    ]
  }
}

有些时候甚至更为极端,当不希望所有资源被更改时:

terraform
  # ......
  lifecycle {
    ignore_changes = all
  }
}

安装CLI

Linux环境

运行如下命令:

bash
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

安装完毕后测试一下:

bash
terraform -v

Windows

首先下载terraform: https://www.terraform.io/downloads
然后将可执行文件terraform.exe解压到相应目录下,然后将该目录添加到系统PATH中。
打开命令行窗口,可以进行测试了:

bash
terraform -v

安装Terraform VS Code插件

关于terraform使用的语法

Terraform使用HCL(Hashicorp Configuration Language)来进行声明。例如:

terraform
resource "local_file" "demo" {
  filename = "/tmp/demo.txt"
  content "Demo file"
}

Terraform中的常见文件

  • main.tf: 主要资源相关定义都在这里
  • variables.tf: 定义各种变量
  • outputs.tf:定义输出信息
  • provider.tf:包含各种provider的信息

指定provider的版本号

terraform
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账户。

然后项目的组织结构类似这样:

bash
├───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资源。


文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !