那些年在 Terraform 上吃到的糖和踩过的坑

2024年 7月 24日 90.9k 0

前言

最近看到个资源管理的工具——Terraform。笔者基于自身开发经验,简单聊聊对 Terraform 的看法,读者如果有自己的观点,随时欢迎交流。

本文主要包含以下几个内容:

  • 讲讲为啥要用 terraform,terraform 有啥好处;
  • 列举几个常见的 terraform 命令,让读者快速用起来。若读者有相关经验,可以直接跳过。
  • 实现一个简单的 terrform provider,让开发者开发起来;
  • 讲讲使用 terraform 遇到的坑,每个坑都能再写一篇文章。
  • 何为 Terraform,为什么要用 terraform 去做

    先来看看官方高大上的定义:

    Terraform is an infrastructure as code tool that lets you build, change, and version infrastructure safely and efficiently. This includes low-level components like compute instances, storage, and networking; and high-level components like DNS entries and SaaS features.

    确实够高大上。简单来说,用户能够通过编写 Terraform 语法的配置文件,来实现各类资源的管理,包括存储、网络、实例等底层资源,或者 dns 服务等高级资源。

    这时候就来了个疑问,为啥要用 terraform 去创建这些资源呢,直接在页面上点点,或者通过 OpenAPI 不更好、更方便吗?在笔者看来,认为 terraform 最大的优势在于“万物统一”。terraform 定义了一套规范语法,而各厂商去实现 terraform provider,这样可以通过一套逻辑去管理所有的资源,类似于插座和插头的关系。

    如下图所示(官方图),terraform 通过与各个 terraform provider 去交互(RPC 通信),terraform provider 的逻辑由各云厂商去实现。一般来说,云厂商会去调用 OpenAPI 实现创建、更新、查询等逻辑。在该模式下,terraform 官方无需去对接各家云厂商,而是由各家厂商去适配 terraform,从而达到了“万物统一”的效果,也很符合 OAM 规范。

    那些年在 Terraform 上吃到的糖和踩过的坑-1

    常见的 terraform 操作和示例

    对于初学者来说,最好的是能够完成某个动作,增强信心。在这就来带大家熟悉常见的几个动作,感兴趣的读者也可以自己尝试一下。
    首先编写一个 terraform 文件,以华为云 cce 为例,数据均为官网虚假数据【笔者认为实现较完整的 provider 之一 华为云terraform provider:】

    # test.hcl
    terraform {
      required_providers {
        huaweicloud = {
          source = "huaweicloud/huaweicloud"
          version = "1.56.1"
        }
      }
    }
    
    provider "huaweicloud" {
      # Configuration options
    }
    
    resource "huaweicloud_vpc" "myvpc" {
      name = "vpc"
      cidr = "192.168.0.0/16"
    }
    
    resource "huaweicloud_vpc_subnet" "mysubnet" {
      name       = "subnet"
      cidr       = "192.168.0.0/16"
      gateway_ip = "192.168.0.1"
    
      //dns is required for cce node installing
      primary_dns   = "100.125.1.250"
      secondary_dns = "100.125.21.250"
      vpc_id        = huaweicloud_vpc.myvpc.id
    }
    
    resource "huaweicloud_cce_cluster" "cluster" {
      name                   = "cluster"
      flavor_id              = "cce.s1.small"
      vpc_id                 = huaweicloud_vpc.myvpc.id
      subnet_id              = huaweicloud_vpc_subnet.mysubnet.id
      container_network_type = "overlay_l2"
    }
    

    执行 init 命令,初始化目录,可以发现在工作目录下有个 .terraform 的隐藏文件夹,其实保存了 provider 的缓存;

    terraform init
    

    执行 plan 命令,plan 能够起到 dry-run 的效果。针对 Resource 类型的资源,terraform 会对比 hcl 文件以及当前状态文件 tfstate 中的内容,展示 diff 结果。针对 DataSource 类型,terraform plan 的效果和 apply 是一致的,能够直接拿到云上数据。至于何为 Resource 和 DataSource,各位读者可自行查阅。

    terraform plan
    

    执行 apply 命令。资源的新建和变更。执行该命令后,terraform provider 会真正地去调用云上接口,创建资源。执行结束后,可从 tfstate 状态中查看当前云上状态。

    terraform apply
    

    执行 import 命令,从云上同步状态到本地。

    terraform import {resourceId}
    

    执行 refresh 命令,从云上同步状态到本地,与 import 不同的是,import 可以在 state 为空的情况下去拿云上数据,而 refresh 需要有 state 文件。

    terraform refresh
    

    实现个简单的 terraform provider

    多说不如多练,这就来实现个很简单的 terraform provider,感兴趣的同学可以看笔者的另一篇文章。

    terraform provider 最简单实践

    Terraform 的坑

    说了这么多好处,terraform 没坑吗,当然有啦。下面就举几个笔者遇到的例子,一起来感受下 terraform “不好用”的地方:

  • terraform init 是个很吃内存的操作,terraform init 会尝试去加载 provider、初始化目录等,而某些 provider 动则几百兆(比如说 tke),导致内存压力很大(几百兆);
  • terraform 动作不具备原子性,当 terraform 出现中间状态时【比如访问某一个接口失败了】,非常难以处理。假设创建集群的 terraform apply 操作包括创建 EIP 和创建集群两个动作,若创建公网 IP 成功,创建集群失败,此时云上就会莫名多出来一个 EIP,本地 Terraform State 文件还无法感知到;
  • 各家的 provider 实在不敢恭维【即使是一些大公司】。下面是笔者跟过的一个问题
    华为云获取节点列表 provider issue:华为云在获取节点列表的时候,调用了 n 次 tag 接口【n 为节点数】,导致大规模场景下,terrafrom 执行时间太长,甚至超时。
  • 当然 provider 的问题还有很多,比如说 refresh 不到关键字段,字段和文档不对齐等,总之各家对 provider 重视程度与实现方式不同,使用者按需使用。

    相关文章

    KubeSphere 部署向量数据库 Milvus 实战指南
    探索 Kubernetes 持久化存储之 Longhorn 初窥门径
    征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
    无需 Kubernetes 测试 Kubernetes 网络实现
    Kubernetes v1.31 中的移除和主要变更
    SAPwned:SAP AI 漏洞暴露客户云环境和私有 AI 工件

    发布评论