Terraform Introduction

大家好,感谢大家参与本次分享会,与我一同走进 Terraform 的世界。我是今天的主讲人李宇飞。

今天的分享由以下三个部分组成:

  • 首先,是介绍一下可观测性即代码(也就是 OaC,Observability as Code)这个概念,以及它的历史。
  • 随后,极其简略地介绍一下 Terraform 的原理和基本概念
  • 最后,用一个完整的示例,来演示如何使用观测云和 Terraform 管理可观测性资源

那么在开始之前,我们可以先互相认识一下,加深对彼此的了解,以便于后续的合作。

  • 我目前在观测云的基础架构团队,担任系统开发工程师。
  • 在过去 7 年的工作中,一直从事基础软件和平台工程方向,致力于推进中国开发者工具行业的发展。
  • 例如在 Terraform 的生态中,我写了很多 Terraform Provider 和 Backend,组织了中国早期的 IaC 社群,在 InfoQ 和云服务提供商的媒体上发表过一些深度技术文章。
  • 我喜欢深入到一线去,脚踏实地地与开发者面对面。如果你也喜欢和一线的工程师和开发者们打交道,欢迎常与我交流。

那么回到我们今天的主题,可观测性即代码。

提到可观测性即代码,就不得不提到这三个概念。声明式 API、万物即代码、可观测性即代码。

追根溯源,近些年来,我们交付软件的方式产生了极大的变化。随着 Kubernetes 和 Terraform 的兴起,声明式 API 成为基础设施配置管理的核心手段。

声明式 API 要解决什么样的问题呢?其实,可以用一句话总结,就是根据用户的意图,使目标系统的状态收敛至一个不动点。说人话就是:让系统变成人们期望的那个状态。

想象一下,如果用互联网早期的命令式 API,例如 RESTFul、RPC 等,我们完成一个更新操作,都有哪些步骤呢?

  • 首先,我们会通过 API 发起一个查询,查到当前资源的状态。
  • 随后,判断状态与当前资源之间的差异,根据差异的不同,确定调用哪个 API 来进行下一步操作。
  • 再之后,发起更新指令,改变资源的状态。
  • 最后,发起新一轮查询,判断资源状态是否符合预期。

而声明式 API,其本质就是将这一系列复杂的逻辑,封装在了控制器下,从而隐藏了上述的细节。至于更复杂的交互式 API,则代表了开发者工具领域的另一个研究方向,不在本次分享的讨论范围内,如果大家感兴趣的话,欢迎会后与我交流。

那么回到本次的主题,当我们实际操作云上资源时,都有哪些工具和编程范式可供选用?

首先是脚本式编程,脚本式编程例如,使用 API 和 SDK 编写脚本代码,来实现资源管理操作。脚本式编程存在一个显著的问题,每一家云供应商提供的 API 与 SDK 风格迥异,对于更新操作的实现也是千差万别,这会带来高昂的认知成本和管理负担,这种问题我们称之为 Tool Sprawling,也就是工具蔓延现象。

那么以 Terraform 和 Kubernetes CRD 为代表的,采用声明式代码来编写基础设施的一系列工具,则通过一个单一的工具,提供了一个统一的控制平面管理方案。但也带来了新的问题,那就是可测试性和可观测性问题。

首先我们来看第一个例子:当我们想要测试一个 Terraform Module 或者 Helm Chart 时,最先想到的方式是什么呢?通常情况下,我可能会选择通过 Terratest 或其它类似的方案,通过系统调用唤起一次对 Terraform 或 Helm CLI 的调用。

那么,我们提出的第一个问题是:如何来衡量对 HCL 或者 Yaml 这种配置语言的测试覆盖率?

另外一个例子,大家知道,现在 IDP,Internal Development Platform,内部开发平台这个概念特别火。内部开发平台可以帮助组织内的开发者,更好地去发现和管理组织内的数字研发资产。

当我们在进行内部开发平台建设时,往往并不是孤立地去采用开发工具,例如 Terraform CLI,而是与当前组织的软件开发生命周期融合,嵌入到现有系统里,共同发挥作用。

那么,我们提出的第二个问题是,基础设施代码,应该怎样融入现有的系统呢,是否有一个工程上值得信赖的办法?

这就引入了一个新的概念,基础设施即软件,这个概念的实施以 Pulumi 和 CDK 为代表,提倡采用通用编程语言来编写声明式配置,例如 Go、Python、TypeScript 等。

从某种角度看,基础设施相关的代码,既是一个控制面配置,接受静态的版本管理;另一方面,它又具有数据面特征,需要不断地去跟踪现有系统的状态,调和配置漂移。

因此,它的形态更符合一个软件的定义,需要完备的测试和集成,通用编程语言可以借助于现有的编译器工具链,完成包括覆盖率检测、远程过程调用,以及各种抽象复用的能力,以提升基础架构交付的效率和质量。这也是当前行业内,IaC 进化的方向之一。

还有一个进化的方向,我认为也非常值得关注,那就是万物即代码,将声明式代码的管理范围扩大,管理任何资源,甚至是物理世界。

它解决了这样几个问题:

  1. 首先,为任何可抽象的资源,构建了单一事实来源
  2. 第二点是,自动去检测配置漂移,从现有状态
  3. 最后,通过 GitOps 的方式,提供了对开发者友好的工作流

近些年来,我们看到中国有很多有意思的工作纷纷涌现,例如 Bytebase 的 Database as Code,Selefra 的 Select * from infrastructure,都是这种精神的体现。

我们介绍了过去一些年中,以 Terraform 为代表的,基础设施代码化技术的发展。

那么接下来介绍一下,我们当前的一些工作:可观测性即代码,Observability as Code。

可观测性即代码这个概念的起源已经很难考证了,在网络上检索到的比较早期和权威的出处,就是 ThoughtWorks 在 2018 年发布的技术雷达,上面提到:

传统的,通过 GUI 点击配置的仪表板和警报是难以重复的,无法持续测试和调整警报以避免警报疲劳或错过重要警报,并且偏离组织最佳实践。

2021 年,沃达丰在 HashiConf 上做了一个关于 Observability as Code 的报告,介绍了如何通过 Terraform 跨环境实现可观测性标准化。

2022 年,Lightstep 的 Adri Villela 发表了一篇关于 OLaC 的文章,文章在 OaC 的基础上,将应用程序的指标和遥测数据、可观测性后端、SLO 和事件响应系统这些概念组合起来,共同构成了一个全景概念(Landscape),添加到了 OaC Stack 中。

从 2017-2022 年,DataDog、NewRelic、Lightstep 都陆续发布了 Terraform 的 Provider,而我们也在 2023 年完成了这一步跨越。

关于 Terraform,这里不会占用太多的篇幅进行介绍,对于首次接触 Terraform 的同学,这里留出一节,给大家简单地介绍一下相关的核心概念:

  1. Terraform 分为 Core CLI 和 Plugin 两个部分,其中最常见的一类 Plugin 叫做 Terraform Provider,由各家服务提供商构建
  2. 当使用 CLI 应用基础设施代码时,Terraform 首先会从代码中加载目标状态,同时刷新当前的状态,比对二者的差异,生成一张有向无环图,最后根据这张图来调用插件,完成具体的编排逻辑
  3. 有向无环图在这里起到两个作用,保留资源间的拓扑结构,确保执行的顺序是正确的。例如告警策略依赖监控器,那么它可以确保监控器一定在告警策略之前创建;还可以充分并行化,没有依赖关系的资源会自动并行构建。

如果你是第一次了解 Terraform,可以参考我在 InfoQ 上发表的:Terraform 深度解析,这篇文章介绍了关于状态管理、锁机制、和自动迁移等等更多的细节。

那么接下来,我们开始两个具体的实验,直观地感受下 Observability as Code 对工程效能的提升:

两个实例都在 Killercoda 上有对应的在线实验,大家可以一起动手来实际体验一下。

第一个实验,实现一个典型的监控告警的场景。通过配置一个监控器和一个告警策略,实现每当条件被触发时,通知一个成员组或通知对象,例如一个 IM 群组。同时配置一个额外的静默规则,当每月的计划停机时间来临时,静默告警消息以进行系统维护。

第二个实验,构建一个组织内共享的仪表板模版库。通过开发者工具包,导入控制台或 Grafana 中配置好的仪表板,将现有仪表板代码化,从而实现仪表板的复用,并通过 Terraform 的 Policy,来定义组织内通用的仪表板设计规范。

OK,那么我们两个实验都完成了。

通过本次分享,我希望能够推动 OaC,也就是 Observability as Code 在中国的发展,让我们向万物即代码的目标,迈进坚实的一步。

正在做一个 Terraform + Observability as Code 的 Talk,和一个有关于 Kubernetes Prow 的分享,不知道是否契合主题~另外有一点遗憾的是,线下支持录播吗,我只能参加视频录播的 Talk,因为说话慢,每次都要用科技与狠活加速 x1.25,才能匹配正常人的语速,emmmm~

Previous
Next