Terraform初学者指南 – Terraform教程

想知道 Terraform 是什么吗?让我们来了解一下。

基础设施即代码(Infrastructure as Code,IaC)是在专业人士中广泛使用的术语。它是使用可读机器定义文件来管理和提供完整的 IT 基础设施(包括物理和虚拟机器)的过程。它是一种面向运营的软件工程方法。它通过使用编程脚本来自动化完整的数据中心。

尽管 Infrastructure as Code 提供了许多功能,但它也面临着多个挑战:

  • 需要学习编码
  • 不知道变更的影响
  • 需要还原变更
  • 无法跟踪变更
  • 无法自动化资源
  • 基础设施有多个环境

Terraform 就是为解决这些挑战而创建的。

Terraform 是什么?

Terraform 是 HashiCorp 开发的开源基础设施即代码工具。它用于使用易于学习的声明性语言定义和提供完整的基础设施。

它是一个基础设施配置工具,您可以将云基础设施设置存储为代码。它与诸如 CloudFormation 的工具非常相似,您可以使用该工具自动化 AWS 基础设施,但只能在 AWS 上使用。而使用 Terraform,您还可以在其他 cloud platforms 上使用它。

以下是使用 Terraform 的一些好处。

  • 提供编排功能,而不仅仅是配置管理
  • 支持多个提供者,如 AWS、Azure、GCP、DigitalOcean 等等
  • 提供不可变基础设施,其中配置平稳变更
  • 使用易于理解的语言 HCL(HashiCorp 配置语言)
  • 轻松移植到任何其他提供者
  • 支持仅客户端架构,因此无需在服务器上进行额外的配置管理

Terraform 核心概念

以下是 Terraform 中使用的核心概念/术语:

  • 变量:也称为输入变量,它是 Terraform 模块使用的键值对,用于自定义。
  • 提供者:它是与服务的 API 进行交互并访问其相关资源的插件。
  • 模块:它是一个包含 Terraform 模板的文件夹,其中定义了所有配置
  • 状态:它包含 Terraform 管理的基础设施和相关配置的缓存信息。
  • 资源:它指的是一个或多个基础设施对象(计算实例、虚拟网络等)的块,用于配置和管理基础设施。
  • 数据源:它由提供者实现,用于返回有关外部对象的 terraform 信息。
  • 输出值:这些是 terraform 模块的返回值,可以被其他配置使用。
  • 计划:这是其中一个阶段,它确定从基础设施的真实/当前状态到期望状态需要创建、更新或销毁的内容。
  • 应用:这是其中一个阶段,它将变更应用于基础设施的真实/当前状态,以达到期望状态。

Terraform 生命周期

Terraform 生命周期包括 – initplanapplydestroy

  • Terraform init初始化工作目录,其中包含所有配置文件
  • Terraform计划用于创建执行计划以达到所需的基础设施状态。更改配置文件是为了实现所需状态。
  • Terraform apply然后根据计划对基础设施进行更改,并使其达到所需的状态。
  • Terraform destroy用于删除所有旧的基础设施资源,在应用阶段后标记为有污点。

Terraform工作原理是什么?

Terraform的架构由两个主要组件组成:

  • Terraform核心
  • 提供商

Terraform核心

Terraform核心使用两个输入源来完成其工作。

第一个输入源是您作为用户配置的Terraform配置。在这里,您定义需要创建或提供的内容。而第二个输入源是状态,其中terraform保持基础架构当前设置的最新状态。

因此,Terraform核心的工作是接受输入,并确定需要执行的计划。它比较状态,即当前状态和您在最终结果中希望的配置。它确定需要执行哪些操作以实现配置文件中的所需状态。它确定需要创建、更新和删除哪些内容以创建和提供基础架构。

提供商

架构的第二个组件是特定技术的提供商。这可以是云提供商,如AWS、Azure、GCP,或其他基础设施即服务平台。还有提供商用于更高级别的组件,如Kubernetes或其他平台即服务工具,甚至是一些自助服务工具。

它使您可以在不同级别上创建基础架构。

例如-在AWS基础架构上创建一个Kubernetes,然后在该Kubernetes集群内创建服务/组件。

Terraform有100多个不同技术的提供商,每个提供商都为Terraform用户提供访问其资源的权限。例如,通过AWS提供商,您可以访问数百个AWS资源,如EC2实例、AWS用户等。通过Kubernetes提供商,您可以访问通用资源,例如服务、部署和命名空间等。

因此,这就是Terraform的工作原理,以及通过这种方式,它试图帮助您从基础架构到应用程序的完整应用程序设置。

让我们做一些实际的事情。👨‍💻

我们将在Ubuntu上安装Terraform并提供一个非常基本的基础架构。

安装Terraform

下载最新的terraform包。

请参考official download page获取相应操作系统的最新版本。

yaoweibin@yaoweibin:~$ wget https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
--2020-08-14 16:55:38--
https://releases.hashicorp.com/terraform/0.13.0/terraform_0.13.0_linux_amd64.zip
正在解析 releases.hashicorp.com (releases.hashicorp.com)... 151.101.153.183, 2a04:4e42:24::439
正在连接 releases.hashicorp.com (releases.hashicorp.com)|151.101.153.183|:443... 已连接。
正在发送 HTTP 请求,正在等待回应... 200 OK
长度:34851622 (33M) [application/zip]
正在保存至: ‘terraform_0.13.0_linux_amd64.zip’

terraform_0.13.0_linux_amd64.zip 100%[=================================================================>] 33.24M 90.3KB/s 用时 5m 28s

2020-08-14 17:01:06 (104 KB/s) - 已保存 ‘terraform_0.13.0_linux_amd64.zip’ [34851622/34851622]

解压下载的包。

yaoweibin@yaoweibin:~$ unzip terraform_0.13.0_linux_amd64.zip
归档:
terraform_0.13.0_linux_amd64.zip
解压中:terraform

将terraform可执行文件移动到下面显示的路径下。检查terraform版本。

yaoweibin@yaoweibin:~$ sudo mv terraform /usr/local/bin/
[sudo] 密码为 yaoweibin:
yaoweibin@yaoweibin:~$ terraform -v
Terraform v0.13.0

您可以看到这些是terraform可用的执行命令。

yaoweibin@yaoweibin:~$ terraform
用法:terraform [-version] [-help]  [args]

下面列出了可执行的命令。
首先显示最常用和有用的命令,然后是不太常见或更高级的命令。如果您刚开始使用Terraform,请使用常用命令。对于其他命令,请在使用之前阅读帮助和文档。

常用命令:
apply 构建或更改基础设施
console Terraform内插的交互式控制台
destroy 销毁Terraform管理的基础设施
env 工作区管理
fmt 重写配置文件为规范格式
get 下载并安装配置的模块
graph 创建Terraform资源的可视图
import 将现有的基础设施导入到Terraform
init 初始化Terraform工作目录
login 获取并保存远程主机的凭据
logout 删除本地存储的远程主机凭据
output 从状态文件读取输出
plan 生成并显示执行计划
providers 打印配置中使用的提供程序树
refresh 将本地状态文件与真实资源更新
show 检查Terraform状态或计划
taint 手动标记资源以重新创建
untaint 手动取消标记资源为有缺陷
validate 验证Terraform文件
version 打印Terraform版本
workspace 工作区管理

所有其他命令:
0.12upgrade 重写v0.12之前的模块源代码
0.13upgrade 重写v0.13之前的模块源代码
debug 调试输出管理(实验性)
force-unlock 手动解锁terraform状态
push Terraform Enterprise遗留命令(v1)
state 高级状态管理

使用Terraform部署AWS EC2实例

在此演示中,我将使用Terraform启动新的AWS EC2 instance

为此Terraform演示创建一个工作目录。

yaoweibin@yaoweibin:~$ mkdir terraform_demo

进入该目录并创建一个terraform配置文件,在其中定义提供程序和启动AWS EC2实例所需的资源。

yaoweibin@yaoweibin:~$ cd terraform_demo/
yaoweibin@yaoweibin:~/terraform_demo$ gedit awsec2.tf

provider "aws" {
access_key = "B5KG6Fe5GUKIATUF5UD"
secret_key = "R4gb65y56GBF6765ejYSJA4YtaZ+T6GY7H"
region = "us-west-2"
}

resource "aws_instance" "terraform_demo" {
ami = "ami-0a634ae95e11c6f91"
instance_type = "t2.micro"
}

注意:我已经更改了访问密钥和秘密密钥😛,您需要使用自己的。

从上面提到的配置中,您可以看到我提到了AWS之类的提供程序。在提供程序内部,我提供了AWS用户凭证和实例必须启动的区域。

在资源中,我提供了Ubuntu的AMI详细信息(ami-0a634ae95e11c6f91),并指定实例类型应为t2.micro

您可以看到配置文件非常简单和易读,即使您不是一个狂热的编码者。

terraform init

现在,第一步是初始化terraform。

yaoweibin@yaoweibin:~/terraform_demo$ terraform初始化

正在初始化后端…

初始化提供程序插件…
– 使用先前安装的hashicorp / aws v3.2.0

以下提供程序在配置中没有任何版本约束,
因此安装了最新版本。

为了防止自动升级到可能包含破坏性的新主版本,
更改,我们建议在所需提供程序块中添加版本约束
在您的配置中,建议使用下面的约束字符串。

* hashicorp / aws:version =“〜> 3.2.0”

Terraform初始化成功!

您现在可以开始使用Terraform。尝试运行“terraform计划”以查看
对基础架构所需的任何更改。所有Terraform命令
现在都应该工作。

如果您曾经设置或更改过Terraform的模块或后端配置,
重新运行此命令以重新初始化工作目录。如果您忘记了,其他
必要时,命令将检测到它并提醒您这样做。

terraform计划

接下来是计划阶段;它将创建用于创建和配置基础架构的执行图。

yaoweibin@yaoweibin:~/terraform_demo$ terraform plan
刷新内存中的Terraform状态以便执行计划...
刷新的状态将用于计算此计划,但不会保留在本地或远程状态存储中。

------------------------------------------------------------------------

已生成执行计划如下所示。
使用以下符号表示资源操作:
+ 创建

Terraform将执行以下操作:

# 将创建aws_instance.terraform_demo
+ resource "aws_instance" "terraform_demo" {
+ ami = "ami-0a634ae95e11c6f91"
+ arn = (计划后已知)
+ associate_public_ip_address = (计划后已知)
+ availability_zone = (计划后已知)
+ cpu_core_count = (计划后已知)
+ cpu_threads_per_core = (计划后已知)
+ get_password_data = false
+ host_id = (计划后已知)
+ id = (计划后已知)
+ instance_state = (计划后已知)
+ instance_type = "t2.micro"
+ ipv6_address_count = (计划后已知)
+ ipv6_addresses = (计划后已知)
+ key_name = (计划后已知)
+ outpost_arn = (计划后已知)
+ password_data = (计划后已知)
+ placement_group = (计划后已知)
+ primary_network_interface_id = (计划后已知)
+ private_dns = (计划后已知)
+ private_ip = (计划后已知)
+ public_dns = (计划后已知)
+ public_ip = (计划后已知)
+ secondary_private_ips = (计划后已知)
+ security_groups = (计划后已知)
+ source_dest_check = true
+ subnet_id = (计划后已知)
+ tenancy = (计划后已知)
+ volume_tags = (计划后已知)
+ vpc_security_group_ids = (计划后已知)

+ ebs_block_device {
+ delete_on_termination = (计划后已知)
+ device_name = (计划后已知)
+ encrypted = (计划后已知)
+ iops = (计划后已知)
+ kms_key_id = (计划后已知)
+ snapshot_id = (计划后已知)
+ volume_id = (计划后已知)
+ volume_size = (计划后已知)
+ volume_type = (计划后已知)
}

+ ephemeral_block_device {
+ device_name = (计划后已知)
+ no_device = (计划后已知)
+ virtual_name = (计划后已知)
}

+ metadata_options {
+ http_endpoint = (计划后已知)
+ http_put_response_hop_limit = (计划后已知)
+ http_tokens = (计划后已知)
}

+ network_interface {
+ delete_on_termination = (计划后已知)
+ device_index = (计划后已知)
+ network_interface_id = (计划后已知)
}

+ root_block_device {
+ delete_on_termination = (计划后已知)
+ device_name = (计划后已知)
+ encrypted = (计划后已知)
+ iops = (计划后已知)
+ kms_key_id = (计划后已知)
+ volume_id = (计划后已知)
+ volume_size = (计划后已知)
+ volume_type = (计划后已知)
}
}

计划: 1个要添加,0个要更改,0个要销毁。

------------------------------------------------------------------------

注意:您没有指定“-out”参数来保存此计划,因此Terraform无法保证在随后运行“terraform apply”时会执行完全这些操作。

terraform apply

应用阶段将执行配置文件并启动AWS EC2实例。当您运行apply命令时,它会询问您:“是否要执行这些操作?”,您需要键入yes并按Enter键。

yaoweibin@yaoweibin:~/terraform_demo$ terraform apply

已生成执行计划如下所示。
资源操作用以下符号表示:
+ 创建

Terraform 将执行以下操作:

# 将创建 aws_instance.terraform_demo
+ resource “aws_instance” “terraform_demo” {
+ ami = “ami-0a634ae95e11c6f91”
+ arn = (在应用后可知)
+ associate_public_ip_address = (在应用后可知)
+ availability_zone = (在应用后可知)
+ cpu_core_count = (在应用后可知)
+ cpu_threads_per_core = (在应用后可知)
+ get_password_data = false
+ host_id = (在应用后可知)
+ id = (在应用后可知)
+ instance_state = (在应用后可知)
+ instance_type = “t2.micro”
+ ipv6_address_count = (在应用后可知)
+ ipv6_addresses = (在应用后可知)
+ key_name = (在应用后可知)
+ outpost_arn = (在应用后可知)
+ password_data = (在应用后可知)
+ placement_group = (在应用后可知)
+ primary_network_interface_id = (在应用后可知)
+ private_dns = (在应用后可知)
+ private_ip = (在应用后可知)
+ public_dns = (在应用后可知)
+ public_ip = (在应用后可知)
+ secondary_private_ips = (在应用后可知)
+ security_groups = (在应用后可知)
+ source_dest_check = true
+ subnet_id = (在应用后可知)
+ tenancy = (在应用后可知)
+ volume_tags = (在应用后可知)
+ vpc_security_group_ids = (在应用后可知)

+ ebs_block_device {
+ delete_on_termination = (在应用后可知)
+ device_name = (在应用后可知)
+ encrypted = (在应用后可知)
+ iops = (在应用后可知)
+ kms_key_id = (在应用后可知)
+ snapshot_id = (在应用后可知)
+ volume_id = (在应用后可知)
+ volume_size = (在应用后可知)
+ volume_type = (在应用后可知)
}

+ ephemeral_block_device {
+ device_name = (在应用后可知)
+ no_device = (在应用后可知)
+ virtual_name = (在应用后可知)
}

+ metadata_options {
+ http_endpoint = (在应用后可知)
+ http_put_response_hop_limit = (在应用后可知)
+ http_tokens = (在应用后可知)
}

+ network_interface {
+ delete_on_termination = (在应用后可知)
+ device_index = (在应用后可知)
+ network_interface_id = (在应用后可知)
}

+ root_block_device {
+ delete_on_termination = (在应用后可知)
+ device_name = (在应用后可知)
+ encrypted = (在应用后可知)
+ iops = (在应用后可知)
+ kms_key_id = (在应用后可知)
+ volume_id = (在应用后可知)
+ volume_size = (在应用后可知)
+ volume_type = (在应用后可知)
}
}

计划:添加 1 个,更改 0 个,销毁 0 个。

您要执行这些操作吗?
Terraform 将执行上述所述的操作。
只接受 ‘yes' 以确认。

输入一个值:yes

正在创建 aws_instance.terraform_demo…
仍在创建 aws_instance.terraform_demo… [已用时间 10s] 仍在创建 aws_instance.terraform_demo… [已用时间 20s] 仍在创建 aws_instance.terraform_demo… [已用时间 30s] 仍在创建 aws_instance.terraform_demo… [已用时间 40s] 创建完成 aws_instance.terraform_demo [已用时间 44s] [id=i-0eec33286ea4b0740]

应用完成!资源:已添加 1 个,已更改 0 个,已销毁 0 个。

转到您的 AWS EC2 仪表板,您将看到一个带有在应用命令末尾提到的实例 ID 的新实例。

您已成功使用 Terraform 启动 AWS EC2 实例。

terraform destroy

最后,如果您要删除基础架构,需要运行 destroy 命令。

yaoweibin@yaoweibin:~/terraform_demo$ terraform destroy
aws_instance.terraform_demo: 正在刷新状态… [id=i-0eec33286ea4b0740]

已生成执行计划并显示如下。
资源操作使用以下符号表示:
– destroy

Terraform 将执行以下操作:

# aws_instance.terraform_demo 将被销毁
– 资源 “aws_instance” “terraform_demo” {
– ami = “ami-0a634ae95e11c6f91” -> null
– arn = “arn:aws:ec2:us-west-2:259212389929:instance/i-0eec33286ea4b0740” -> null
– associate_public_ip_address = true -> null
– availability_zone = “us-west-2c” -> null
– cpu_core_count = 1 -> null
– cpu_threads_per_core = 1 -> null
– disable_api_termination = false -> null
– ebs_optimized = false -> null
– get_password_data = false -> null
– hibernation = false -> null
– id = “i-0eec33286ea4b0740” -> null
– instance_state = “running” -> null
– instance_type = “t2.micro” -> null
– ipv6_address_count = 0 -> null
– ipv6_addresses = [] -> null
– monitoring = false -> null
– primary_network_interface_id = “eni-02a46f2802fd15634” -> null
– private_dns = “ip-172-31-13-160.us-west-2.compute.internal” -> null
– private_ip = “172.31.13.160” -> null
– public_dns = “ec2-34-221-77-94.us-west-2.compute.amazonaws.com” -> null
– public_ip = “34.221.77.94” -> null
– secondary_private_ips = [] -> null
– security_groups = [
– “default”,
] -> null
– source_dest_check = true -> null
– subnet_id = “subnet-5551200c” -> null
– tags = {} -> null
– tenancy = “default” -> null
– volume_tags = {} -> null
– vpc_security_group_ids = [
– “sg-b5b480d1”,
] -> null

– credit_specification {
– cpu_credits = “standard” -> null
}

– metadata_options {
– http_endpoint = “enabled” -> null
– http_put_response_hop_limit = 1 -> null
– http_tokens = “optional” -> null
}

– root_block_device {
– delete_on_termination = true -> null
– device_name = “/dev/sda1” -> null
– encrypted = false -> null
– iops = 100 -> null
– volume_id = “vol-0be2673afff6b1a86” -> null
– volume_size = 8 -> null
– volume_type = “gp2” -> null
}
}

计划: 0 个添加, 0 个更改, 1 个销毁。

您确定要销毁所有资源吗?
Terraform 将销毁所有已托管的基础结构, 如上所示。
此操作无法撤消。只有输入 ‘yes' 才会被接受确认。

输入一个值: yes

aws_instance.terraform_demo: 正在销毁… [id=i-0eec33286ea4b0740] aws_instance.terraform_demo: 仍在销毁… [id=i-0eec33286ea4b0740, 已耗时 10s] aws_instance.terraform_demo: 仍在销毁… [id=i-0eec33286ea4b0740, 已耗时 20s] aws_instance.terraform_demo: 仍在销毁… [id=i-0eec33286ea4b0740, 已耗时 30s] aws_instance.terraform_demo: 34s 后销毁完成

销毁完成! 资源: 1 个已销毁。

如果您重新检查 EC2 控制台,您将看到实例已被终止。

结论

我相信上面的内容给您了解 Terraform 的起点。请继续尝试我刚刚展示的示例。

您还应该查看这些infrastructure automation software

如果您有兴趣了解更多信息,则建议查看Learning DevOps with Terraform course

类似文章