我已经实现了一个 kubernetes terraform 提供程序,它将清单文件应用于 k8s 集群。我也创建了 .tf 文件,但是当我运行terraform init
它时,它会从 terraform 注册表下载插件。
如何让我的插件运行 terraform 应用。
我已经实现了一个 kubernetes terraform 提供程序,它将清单文件应用于 k8s 集群。我也创建了 .tf 文件,但是当我运行terraform init
它时,它会从 terraform 注册表下载插件。
如何让我的插件运行 terraform 应用。
为了做到这一点,您首先必须了解 Go 是如何构建应用程序的,然后是 terraform 如何与它一起工作。
每个 terraform 提供程序都是一种module
. 为了支持几乎任何语言的开放模块化系统,您需要能够动态加载模块并与它们交互。Terraform 也不例外。
然而,go lang 团队很久以前就决定编译成静态链接的应用程序;您拥有的任何依赖项都将被编译为 1 个单个二进制文件。与其他本地语言(如 C 或 C++)不同,
不使用a .dll
or ;.so
在运行时没有动态库可以加载,因此,模块化变成了另一个技巧。这样做是为了避免臭名昭著的dll 地狱,这种地狱在大多数现代系统都包含某种依赖管理之前非常普遍。是的,这仍然是一个问题。
每个 terraform 提供者都是它自己的迷你 RPC 服务器。当 terraform 运行您的提供程序时,它实际上会启动一个作为您的提供程序的新进程,并通过此 RPC 通道连接到它。使问题更加复杂的是,您的提供者进程的生命周期非常短暂。可能持续不超过几秒钟。这是您需要与调试器连接的过程
通常,您会直接启动您的应用程序,并将模块加载到应用程序内存中。这就是您可以实际调试它的原因,因为您的调试器知道如何为您的提供者找到确切的内存地址。但是,您没有这种安排,您需要进行远程调试会话。
因此,您不会直接加载 terraform,即使您这样做了,您的module
(也就是您的提供者)位于完全不同进程的内存空间中;这可能持续不超过几秒钟。
connected := false
for !connected {
time.Sleep(time.Second) // set breakpoint here
}
这段代码有效地创建了一个无限睡眠循环;但这实际上对于解决问题至关重要。
delve
使用它的 PID 连接到这个远程进程。这并不像看起来那么难。运行此命令:
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient attach $(pgrep terraform-provider-artifactory)
最后一个参数PID
为您的提供者获取并提供它以delve
进行连接。运行此命令后,您将立即到达断点。请确保替换terraform-provider-artifactory
您的提供商名称connected
为true
. 通过这样做,您可以更改循环谓词,它将在下一次迭代中退出此循环。