Terraform基础概念——Provider

Terraform基础概念——Provider

Terraform被设计成一个多云基础设施编排工具,不像CloudFormation那样绑定AWS平台,Terraform可以同时编排各种云平台或是其他基础设施的资源。Terraform实现多云编排的方法就是Provider插件机制。

Terraform基础概念——Provider - 图1

Terraform通过RPC调用插件,插件代码通过调用SDK操作远程资源

Terraform使用的是HashiCorp自研的go-plugin库(https://github.com/hashicorp/go-plugin),本质上各个Provider插件都是独立的进程,与Terraform进程之间通过rpc进行调用。Terraform引擎首先读取并分析用户编写的Terraform代码,形成一个由data与resource组成的图(Graph),再通过rpc调用这些data与resource所对应的Provider插件;Provider插件的编写者根据Terraform所制定的插件框架来定义各种data和resource,并实现相应的CRUD方法;在实现这些CRUD方法时,可以调用目标平台提供的SDK,或是直接通过调用Http(s) API来操作目标平台。

下载Provider

我们在第一章的小例子中,写完代码后在apply之前,首先我们执行了一次terraform initterraform init会分析代码中所使用到的Provider,并尝试下载Provider插件到本地。如果我们观察执行完第一章例子的文件夹,我们会发现有一个.terraform文件夹,我们所使用的Aliyun Provider插件就被下载安装在里面。

  1. tree -a
  2. .
  3. ├── .DS_Store
  4. ├── .terraform
  5. └── providers
  6. └── registry.terraform.io
  7. └── hashicorp
  8. └── alicloud
  9. └── 1.140.0
  10. └── darwin_arm64
  11. └── terraform-provider-alicloud_v1.140.0

有的时候下载某些Provider会非常缓慢,或是在开发环境中存在许多的Terraform项目,每个项目都保有自己独立的插件文件夹非常浪费磁盘,这时我们可以使用插件缓存。

有两种方式可以启用插件缓存:

第一种方法是配置TF_PLUGIN_CACHE_DIR这个环境变量:

  1. export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"

第二种方法是使用CLI配置文件。Windows下是在相关用户的%APPDATA%目录下创建名为”terraform.rc”的文件,Macos和Linux用户则是在用户的home下创建名为”.terraformrc”的文件。在文件中配置如下:

  1. plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

当启用插件缓存之后,每当执行terraform init命令时,Terraform引擎会首先检查期望使用的插件在缓存文件夹中是否已经存在,如果存在,那么就会将缓存的插件拷贝到当前工作目录下的.terraform文件夹内。如果插件不存在,那么Terraform仍然会像之前那样下载插件,并首先保存在插件文件夹中,随后再从插件文件夹拷贝到当前工作目录下的.terraform文件夹内。为了尽量避免同一份插件被保存多次,只要操作系统提供支持,Terraform就会使用符号连接而不是实际从插件缓存目录拷贝到工作目录。

Terrafom引擎永远不会主动删除缓存文件夹中的插件,缓存文件夹的尺寸可能会随着时间而增长到非常大,这时需要手工清理。

搜索Provider

想要了解有哪些被官方接纳的Provider,有两种方法:

第一种方法是访问Terraform 官方 Provider 文档,该页面中列出了主流的Provider:

Terraform基础概念——Provider - 图2

目前推荐在registry搜索Provider,因为大量由社区开发的Provider都被注册在了那里。

Terraform基础概念——Provider - 图3

一般来说,相关Provider如何声明,以及相关data、resource的使用说明,都可以在registry上查阅到相关文档。

registry.terraform.io不但可以查询Provider,也可以用来发布Provider;并且它也可以用来查询和发布模块(Module),不过模块将是我们后续篇章讨论的话题。

Provider的声明

一组Terraform代码要被执行,相关的Provider必须在代码中被声明。不少的Provider在声明时需要传入一些关键信息才能被使用,例如我们在第一章的例子中,使用Aliyun

  1. variable "access_key" {
  2. default = "xxx"
  3. }
  4. variable "secret_key" {
  5. default = "xxx"
  6. }
  7. variable "region" {
  8. default = "cn-beijing"
  9. }
  10. provider "alicloud" {
  11. access_key = var.access_key
  12. secret_key = var.secret_key
  13. region = var.region
  14. }

在这段Provider声明中,首先在terraform节的provider里声明了本段代码必须要名为aliyun的Provider才可以执行。