我将分享有关Terraform调试的经验和知识

我将记下在调试Terraform时我感受到的要点。

Terraform的使用流程

由于”さくらのクラウド入門チュートリアル”有一张图,所以这里。

思维方式

如果在Terraform中出现错误,大致可以考虑7种情况(实际上是6种)。从上到下,遇到的概率较大。
特别是在第4种情况之后,很少会遇到。

    1. Terraform执行环境的问题

 

    1. Terraform代码的问题

 

    1. Terraform进行供应的目标(AWS方面)的问题

 

    1. Terraform本身的问题

 

    1. Terraform在内部使用的AWS SDK Go的问题

 

    1. AWS API的问题-> 如果不知道就向AWS咨询

 

    Go语言的问题(几乎不会遇到,所以不考虑)

切割方法 (Qiē

Terraform执行环境的问题

如果通过terraform -v可以显示版本,则表示执行环境正常。
如果无法显示,则需要检查环境配置和terraform二进制文件路径是否正确。

Terraform代码的问题

    1. 使用terraform validate命令进行语法检查

 

    1. 执行terraform plan

 

    1. 通常能解决大部分问题。

 

    由于Terraform本身的验证有时可能不太严格,所以有时这并不能解决问题,但如果能够成功通过plan而没有错误,基本上就没有问题了。

有关Terraform的编写方法,通常会在Terraform提供程序的文档中列出。

使用Terraform进行部署的目标(针对AWS侧)存在问题。

很有可能,这是遭遇最多的错误。
尽管Terraform的定义文件是正确的,但如果出现错误,几乎肯定是由于AWS方面的限制导致的错误。
例如,特定选项的组合在AWS方面可能是不允许的错误。
在这种情况下,首先需要阅读错误消息。
尽管错误消息是用英语显示的,但如果不阅读该消息,几乎不可能找到原因。
需要注意的是,在出现该消息的阶段,通常是在Terraform内部执行AWS的API的结果,因此可以查看AWS的API文档,或者通过AWS控制台执行相同的操作来确认是否出现错误,以确定原因。

如果您想查看详细日志,请按照Debugging Terraform中的指示,将TF_LOG添加到环境变量中,这样您就可以更改日志级别了。

Terraform本身存在的问题

从这里开始,我们将进入Terraform的内部讨论,所以即使搜索不多,也多半找不到相关信息。
可能是Terraform方面的bug。
与此相关的主要是以下三个存储库。

    1. 提供商 => 在这里写有关AWS等目标资源的配置处理,大致上可以看到各个资源是如何创建/定义的。

Terraform核心 => 写有关Terraform的常见处理,例如计划和应用的处理,但是通常很少会出现核心引起的问题,优先级较低。

插件软件开发工具包 => 当阅读提供商的代码时,会思考为什么可以通过这个处理执行各种操作,这个秘密通常在这里定义。但是通常不需要阅读这部分内容。

我会考虑一些关键词进行搜索,以确认在提供者方面是否存在类似的问题或拉请求。如果将搜索范围限定在调查对象的资源上,通常会出现问题列表,如果列表中没有相应问题,则可能存在新的问题。

Terraform在内部使用的AWS SDK Go存在问题。

我是以AWS为例的。

在Terraform提供者aws中,使用了aws-sdk-go。截至2022/12/15,我们正在使用V1版本。这也可能是问题的原因之一。

搜索方法

我会查看Terraform提供程序aws是如何创建资源的。首先,我会查找与该资源相关的代码。代码的命名规则是”/internal/service/<要查询的服务名称>/<要查询的定义名称>.go”,所以找到它并不太困难。

仅提供一种选项的中国本地化版本:

比如对于Aurora实例,
https://github.com/hashicorp/terraform-provider-aws/blob/main/internal/service/rds/cluster_instance.go
请注意,
有一个名为resourceClusterInstanceCreate的方法,其后带有Create的描述,这个方法中包含了资源的创建过程。
terraform-provider-aws中的各个资源处理代码基本上都遵循这种形式。

    • 当該リソースの定義(ResourceClusterInstance:Schemaの箇所)

 

    • CRUD

 

    • の構成になっています。

 

    なのでリソースの定義情報を確認したい場合はSchemaの箇所を確認する、作成処理を確認したい場合はCreateとついたメソッドを確認します。

如果以这个形式继续查看,就会在以下位置找到:https://github.com/hashicorp/terraform-provider-aws/blob/main/internal/service/rds/cluster_instance.go#L300

  conn.CreateDBInstanceWithContext(ctx, input)

這邊會出現 conn.<某個方法> 的處理。
這是通過 AWS SDK 呼叫 AWS API 的部分。
在這個情況下,呼叫的是 SDK 的 CreateDBInstance 代碼。
實際上在 aws-sdk-go 的部分,
可以在 https://raw.githubusercontent.com/aws/aws-sdk-go/main/service/rds/api.go 找到。

// CreateDBInstanceWithContext is the same as CreateDBInstance with the addition of
// the ability to pass a context and additional request options.
//
// See CreateDBInstance for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *RDS) CreateDBInstanceWithContext(ctx aws.Context, input *CreateDBInstanceInput, opts ...request.Option) (*CreateDBInstanceOutput, error) {
	req, out := c.CreateDBInstanceRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

有一个同名的方法存在。
接下来我们会检查该方法的具体内容并确定是否需要进行实现。

AWS API存在的问题

有时即使调查了AWS SDK Go,也找不到问题的情况。在这种情况下,需要确认调用AWS SDK Go所使用的AWS API的信息,并最终无法确定时向AWS方面查询原因。

例如,在https://github.com/hashicorp/terraform-provider-aws/issues/20789这个案例中,我们发现AWS SDK Go没有定义标签,并且需要进一步研究AWS API的处理方式。
在查看https://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_CreateHsm.html的API定义信息时,我们发现原本就没有提供标签的功能。

总结

    1. 如果在使用Terraform时遇到问题,请先检查Terraform的写法是否正确,可以使用terraform validate + plan进行验证。

 

    1. 如果仍然出现错误,请阅读错误消息。

 

    如果仍然无法理解错误消息的含义,可能是一个相当困难的问题,建议先向大家咨询一下,再继续调试。
广告
将在 10 秒后关闭
bannerAds