IaC : infrastructure as code 通过自动化基础设施管理的方法,通过代码描述和配置基础设施资源,实现快速,可靠和可重复的部署和过程。
在众多IaC实现中,Terraform为最出色的一款,Terraform核心架构如下:
插件 Terraform的插件作用是和云厂商接口对接,获取更新云上的资源配置。
Terraform 通过Provide 去调用各个云提供商的SDK,或者是SaaS的API 来获取资源,你可以按照 Terraform plugin 官方文档来开发自己的 Provider,然后发布到 Terraform 的官方网站上。
有些场景中声明式配置无法表达,这种情况下,Provisioner可以作为一种补充手段来完成这种类型的操作。后面就是一个获取机器 IP 的例子,你可以借助它来加深理解。
resource "aws_instance" "web" {
...
provisioner "local-exec" { command = "echo The server's IP address is ${self.private_ip}" } }
现在我们在 Terraform 的官方网站,可以搜索到几乎所有云提供商的 Provider,这些都是官方接纳的 Provider。你可以直接复用已有的 Provider,只要在文件里定义使用哪一个 Provider,Provider 相关参数是什么即可。后面这段代码演示了如何在 Terraform 的 main.cf 里定义自己所需要的 Provider。
# Configure the AWS provider "aws"
{
access_key = ""
secret_key = ""
region = "eu-west-1"
}
resource "aws_s3_bucket" "my_bucket"
{
# S3 bucket configuration here
}
resource "aws_instance" "my_ec2_instance"
{
# EC2 instance configuration here # Explicit dependency on the S3 bucket resource
depends_on = [aws_s3_bucket.my_bucket]
}
这两个 resource 的作用是配置 AWS EC2 实例和 S3 存储桶。因为 EC2 实例中程序需要向 S3 Bucket 里写数据,所以 S3 Bucket 就需要在 EC2 实例启动之前就建立起来。为了强制执行这个创建顺序,我们使用 depends_on 来处理资源的依赖关系。
Terraform 应该用什么顺序创建资源,才能保证每个资源都是在其依赖项之后创建的? Terraform 用图来表示基础设施,其中Resource 为顶点,依赖项为边,Terraform 里有多种图算法,比如深度优先搜索等。
Pulumi
了解了 Terraform 的工作原理和用法,你可能会发现 Terraform 存在一个问题——Terraform 对于状态文件的管理并不是特别理想。因为它是明文存储且默认没有状态文件的版本管理,只能依赖外部存储对文件做加密与版本管理。
我在最开始的时候提到 IaC 工具需要满足快速,可靠和可重复这三个特点。我们写下的 Terraform 代码 + 状态文件,才能组成完整的 Terraform 形态,满足可靠这条基准线。
另外,Terraform 的 HCL 语法虽然很简单,很容易上手,但是 HCL 语法里没有 for/if-else 这些流程控制。所以如果我们遇到的场景需要用非常复杂的逻辑实现,基于 HCL 语法的声明式配置就会显得捉襟见肘,我们往往要复制粘贴大段的 Terraform 代码,才能实现想要的配置。
针对Terraform的语法弱点,Pulumi引入了主流编程语言来编写基础设施 其次,在状态管理方面 Pulumi默认提供了状态管理云服务,帮助用户保存状态,也支持将状态保存在自己的管理对象存储中。