匹配terraform模块代码的Regex模式。

问题描述 投票:0回答:1

我试图使用regex来匹配terraform模块并在行首添加注释。我不能只对模块块使用regex。需要注意的是,有些行会在其他模块上重复,比如资源。我的想法是扫描模块块并添加注释。任何帮助都将是非常感激的。花了很多时间弹幕...

module my module {
name = myaws
version = 1.0
source = terraform.mycompany.com
tag = { cost = poc }
}

data "my file" "file-name-creation-data" {
  template = file("path/file.json")
}

resource aws_iam_role_policy "my-role" {
 name = "first-policy"
 role = new role.rolename
 tag = { cost = pic }
}
python regex terraform multiline
1个回答
0
投票

Terraform语言不是一个 普通话 所以没有完全通用的方法来用正则表达式处理它。

然而,该语言对其块状语法有一些约束,这意味着你有可能写出一个 "足够好 "的启发式,它可以处理大多数情况(但仍然不是所有情况)。以下是关于Terraform语言的一些有用的事实,可以帮助约束一下这个问题。

  • 一个区块的开头必须总是出现在同一条线上,包括开头的括号。块的开头必须总是出现在同一行,包括开头括号。module 关键字和 { 支架。

  • 块有两种写法。

    • 正常的布局是让页眉自成一行,以引入块体的开头括号结束。{.
    • 紧凑的单行布局是将整个块放在一行,里面只有一个参数,如 module "foo" { source = "./bar" }.
  • 在正常布局中,块的收尾支撑总是在自己的一条线上。

当然也有一些不太方便的事实。

  • Terraform的对象构造函数表达式也使用大括号, 所以天真地寻找开括号和收括号会发现块的边界和对象构造函数的边界.

  • 字符串模板语法使用 ${%{ 作为其开头定界符,但它使用的是 } 作为它的结尾定界符,增加了结尾括号的第三种含义。

  • heredoc "语法摆脱了正常的解析规则,意味着可以出现任意数量的括号(不需要平衡)。但它们总是以一个 <<<<- 在一行的末尾跟上一个标识符,然后在自己的一行上跟上同一个标识符。

说了这么多,如果你能控制输入,并确保它不包含 "边缘情况",比如块头中间的注释,包含看起来像模块块的遗传序列等等,那么你可能会通过逐行处理输入得到一个 "足够好 "的结果。

  • 让B=0
  • 对于输入的每一行。
    • 如果B为零
    • 如果该行符合 ^module ["\w- ]*{ 然后对一个模块块采取任何你想采取的行动。
    • 对于行中的每个字符。
    • 如果字符是 { 然后增加B
    • 如果字符是 } 然后递减B

这使用了一种天真的括号计数方法来近似地查找块的边界。如果输入包含字面字符串(无论是引号还是 heredoc),并且里面有不平衡的大括号,它就会失败,所以你可以尝试通过计算开闭引号和 heredoc 标记对来改进这一点。

任何短于语言的完整解析器的东西总是会有一些它无法处理的边缘情况,但如果你能约束你的输入,不包含任何你的简单规则集无法理解的情况,那么像上面这样的方法可能对你有用。


如果你愿意用Go写程序,那么你就可以使用 hclwrite 包,它是Terraform用来实现其语言语法的底层库的一部分。它有一个完整的解析器,允许对它所读到的内容进行 "外科手术式 "的编辑,不过在我写这篇文章的时候,它似乎还没有特别为块添加注释的功能,所以它目前还不能解决你的具体目标。

它可能会对将来发现这个问题的其他人有其他与修改现有的Terraform配置有关的目标有用,而且它可能会在将来获得额外的功能来支持其他的用例。

© www.soinside.com 2019 - 2024. All rights reserved.