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