【问题标题】:How can I debug custom terraform provider which I have implemented如何调试已实现的自定义 terraform 提供程序
【发布时间】:2021-05-05 13:36:58
【问题描述】:

我已经实现了一个 kubernetes terraform 提供程序,它将清单文件应用于 k8s 集群。我也创建了 .tf 文件,但是当我运行 terraform init 时,它会从 terraform 注册表下载插件。

如何让我的插件运行适用于 terraform。

【问题讨论】:

标签: terraform terraform0.12+ terraform-template-file terraform-provider-kubernetes


【解决方案1】:

调试 TerraForm 提供程序

了解设计

为了做到这一点,您首先必须了解 Go 如何构建应用程序,然后了解 terraform 如何使用它。

每个 terraform 提供者都是一种module。为了支持几乎任何语言的开放模块化系统,您需要能够动态加载模块并与它们交互。 Terraform 也不例外。

然而,go lang 团队很久以前就决定编译成静态链接的应用程序; 您拥有的任何依赖项都将被编译为 1 个单个二进制文件。与其他本地语言(如 C 或 C++)不同,a 未使用.dll.so;在运行时没有动态库可以加载,因此,模块化变成了另一个技巧。 这样做是为了避免臭名昭著的 dll 地狱,直到大多数现代系统都包含一些 一种依赖管理。是的,这仍然是个问题。

每个 terraform 提供者都是它自己的迷你 RPC 服务器。当 terraform 运行您的提供程序时,它实际上会启动一个作为您的提供程序的新进程,并通过 此 RPC 通道。使问题更加复杂的是,您的提供程序进程的生命周期非常长 短暂的;可能持续不超过几秒钟。这是您需要与调试器连接的过程

正常调试

通常,您会直接启动您的应用程序,它会将模块加载到应用程序内存中。这就是为什么你实际上可以 调试它,因为您的调试器知道如何为您的提供者找到确切的内存地址。然而,你没有 这种安排,你需要做一个远程调试会话。

难题

因此,您不会直接加载 terraform,即使您这样做了,您的 module(也称为您的提供者)也在内存中 完全不同过程的空间;并且可能持续不超过几秒钟。

解决方案

  1. 你需要调试工具delve
  2. 您必须在代码中要开始的位置附近放置一些 shim 代码 调试。我们需要在连接之前阻止此提供程序进程退出。所以,把这段代码放在适当的位置:
    connected := false
    for !connected {
        time.Sleep(time.Second) // set breakpoint here
    }

这段代码有效地创建了一个无限睡眠循环;但这实际上对于解决问题至关重要。

  1. 在此循环内放置一个断点。它还不会做任何事情。
  2. 现在运行您需要的 terraform 命令,以使用您希望调试的代码。这样做后, terraform 基本上会停止,因为它会等待您的提供商的响应;因为你在里面放了一个无限的睡眠循环
  3. 您现在必须告诉delve 使用它的PID 连接到这个远程进程。这并不像看起来那么难。 运行以下命令: dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient attach $(pgrep terraform-provider-artifactory) 最后一个参数为您的提供者获取PID 并将其提供给delve 以进行连接。立即运行此 命令,你将达到你的断点。请确保将 terraform-provider-artifactory 替换为您的提供商名称
  4. 要退出此无限循环,请使用调试器将connected 设置为true。通过这样做,您可以更改循环谓词 它将在下一次迭代中退出此循环。
  5. 调试! - 此时,您可以执行、监视、删除调用堆栈等操作。您的整个武器库都可用

【讨论】:

    猜你喜欢
    • 2019-11-23
    • 2021-03-14
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2013-01-24
    相关资源
    最近更新 更多