Day 28-天下无没有 bug 的 code,如何 debug terraform

本篇简述如何使用 terraform 中 debug 除错

赛後文章会整理放到个人的部落格上 http://chechia.net/

追踪粉专可以收到文章的主动推播

https://ithelp.ithome.com.tw/upload/images/20210901/20120327NvpHVr2QC0.jpg


debug

在 terraform 过程中,我们会遇到许多错误

最多的是 hcl 设定,也就是编辑 .tf 内容与 terraform 互动时,所遇到的错误

  • 可能是 .tf 写错导致错误,或是结果不如预期

其次是 state 的错误

  • 由於 terraform 仰赖 state 来做 .tf resource 与 remote resource 的对照,state 错误会导致 terraform 行为不正常
  • state 偶尔会因为其他错误原因导致 out of sync,可能导致 terraform 错误的产生或删除 resource

terraform core error

  • 指的是 terraform 本身的程序码出错了,这时就需要到 terraform github 上提交 issue,让 terraform core 团队来进行修复
  • 从使用者的角度, 使用稳定版本比较不容易遇见 bug,然而使用的是 edge 版本就有机会遇到
  • 当 terraform 行为怪怪的,我们也需要进行错误排除,才能确定是 terraform core 的错误,而不是 hcl 写错

provider error

  • terraform core 本身提供抽象的运作逻辑,实际与公有云 api 互动的是各家的 provider,provider 本身有会有 bug
  • 以笔者经验,provider 还蛮容易有机会遇到 bug,特别是公有云刚出的新功能,provider 刚支援时
  • 这时我们一样要走 debug workflow,才能确定是 provider 的问题
  • 以及在 provider 尚未修复前,我们要如何继续正常使用 terraform

更多细节可以参考hashicorp learn 文件中建议的 trouble shooting

terraform debug steps

以上面这篇文章作为范例,hashicorp 建议的 debug 步骤

  • terraform fmt
  • terraform validate
  • fix terraform version
  • fix .tf code
  • debug variable / for_each

由於 hcl 的错误是最常见的,也就是使用者 .tf 写错,因此 debug 时我们会先 validate .tf code

  • terraform fmt 将 .tf format 统一
  • terraform validate 验证 .tf context 是不是符合 provider 的规格
  • terraform version,一般来说我们使用的 terraform 版本会固定,例如本 repo 所有的范例都使用相同的 terraform 版本,降低遇见新版 terraform 错误的机率

其中 fmt, validate 很常使用,因此可以整合到工作流程中

  • 例如 terragrunt before & after hook
  • 至少务必整合到 git pre-commit hook,确保 PR 与 master code 的整洁

Terragrunt console

有些时候,terraform 可以正常运作不出错,可是产生结果不如我们预期,可能就是 .tf 参数写错。然而,复杂module 中的参数十分复杂很难除错,这时我们会使用 terraform console 协助

我们使用用到烂的 azure/foundation/compute_network 做范例,如果今天 subnet 建立出来後,发现参数怪怪的(ex. address space 很怪)

  • 我们要如何检查 terraform expression 实际 evaluating 後,各个 variable 的参数?
  • 由於我们使用 terragrunt,一样先要使用 terragrunt 带入 console 指定
  • 附上terraform console 的官方文件
cd azure/foundation/compute_network

terragrunt console
>
> help
The Terraform console allows you to experiment with Terraform interpolations.
You may access resources in the state (if you have one) just as you would
from a configuration. For example: "aws_instance.foo.id" would evaluate
to the ID of "aws_instance.foo" if it exists in your state.

Type in the interpolation to test and hit <enter> to see the result.

To exit the console, type "exit" and hit <enter>, or use Control-C or
Control-D.

进入 console 後,显示互动式令令列

  • 此时的 .tf expression 已经 evaluated,也就是参数都有静态数值可以显示
  • 除了 apply 之後的才会确定的参数,其他参数都可以显示
  • 会读取已经存在的 state

可以印出带入的 input 参数

> module.network
{
  "vnet_address_space" = tolist([
    "10.2.0.0/16",
  ])
  "vnet_id" = "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet"
  "vnet_location" = "southeastasia"
  "vnet_name" = "acctvnet"
  "vnet_subnets" = [
    "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-1",
    "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-2",
    "/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet/subnets/dev-3",
  ]
}

可以印出 object 的 output,例如 module.network 的 output.vnet_id

> module.network.vnet_id
"/subscriptions/6fce7237-7e8e-4053-8e7d-ecf8a7c392ce/resourceGroups/terraform-30-days/providers/Microsoft.Network/virtualNetworks/acctvnet"

也可以在 console 中做实验

  • 在检查复杂的参数很方便,例如 for expression,或是 for_each count meta-argument 的产物
> 1+6
7

> [for k in [1,2,3,4,5]  : k]
[
  1,
  2,
  3,
  4,
  5,
]

结束後 exit console,释放 state lock

> exit
Releasing state lock. This may take a few moments...

terraform log level

如果检查变数都没问题,但结果仍然有问题,我们就会怀疑是 provider,或是外部条件(网路环境)甚至是 core 的错误,这时可以打开 terraform debug log 来检查

  • TF_LOG 支援的的 log level,TRACE, DEBUG, INFO, WARN or ERROR
  • 由於 debug level 的输出量已经很大,建议输出到档案,再用编辑器仔细检视
cd azure/foundation/compute_network

export TF_LOG=DEBUG

TF_LOG=DEBUG terragrunt plan | tee plan_debug.log
...

vim plan_debug.log

内容有 terraform 自身更核心的 log,以及与 public cloud 互动的资讯


Terragrunt debug

上面都是 terraform debug,由於使用 terragrunt 做了很多事情,我们有时也会因为错误的设定而需要 debug terragrunt

我们可以调整 terragrunt log level 或是启用 debug mode

terragrunt apply --terragrunt-log-level debug --terragrunt-debug

细节请见 terragrunt debugging 说明


<<:  Day28. Blue Prism最安全的管家 -BP自动登入Gmail

>>:  14【推坑】考 APCS 升大学大有优势

【第4天】资料前处理-图档分类与裁切

现况 以YOLOv4模型框选中文字後,将资料集(约7万张)区分为以下类别: 1.1 word(仅有1...

[Day01] 前言

身为一个商业设计的转职者,从懵懂到认识 HTML 与 CSS 之後,接着来到进入 JavaScrip...

LeetCode解题 Day19

115. Distinct Subsequences https://leetcode.com/pr...

【RPA介绍】如何用UiPath Studio把重复性流程自动跑起来!

一、RPA是什麽? RPA 是 Robotic Process Automation的缩写,简称机器...

Day 1 - 课程大纲

大家好,我高中生 姜义新 本次课程大纲 在本次的it帮铁人竞赛,我将会以swift及SwitchUI...