正则表达式模式以匹配terraform模块代码

时间:2020-04-22 21:27:52

标签: python regex terraform multiline

我正在尝试使用正则表达式来匹配terraform模块并将注释添加到该行的开头。我不能仅将正则表达式用于模块块。请注意,某些行确实在其他块(如资源)上重复。想法是扫描模块块并将其注释。任何帮助将不胜感激。花了很多时间跳动想法...

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 }
}

1 个答案:

答案 0 :(得分:0)

Terraform语言不是regular language,因此没有使用正则表达式处理它的通用方法。

但是,该语言对其块语法有一些约束,这意味着您可能会编写一种“足够好”的启发式方法,以应对大多数情况(但仍不是全部)。以下是有关Terraform语言的一些有用事实,可以帮助您稍微限制一下问题:

  • 块的开头必须始终出现在同一行上,包括开头大括号。在module关键字和{大括号之间添加其他换行符是无效的。

  • 有两种写块的方法:

    • 标头的常规布局应排成一行,并以引入块体{的开括号结尾。
    • 紧凑的单行布局将整个块放在一行上,并且内部有一个单独的参数,例如module "foo" { source = "./bar" }
  • 常规布局中的块的右括号始终在一行上。

当然,还有一些不太方便的事实:

  • Terraform还在其对象构造函数表达式中使用大括号,因此天真地寻找开括号和闭合大括号会同时发现块边界和对象构造函数边界。

  • 字符串模板语法使用${%{作为其开始定界符,但使用}作为其结束定界符,添加了闭合括号的第三个含义。 / p>

  • “ heredoc”语法脱离了常规的解析规则,意味着可以出现任意数量的花括号(不需要保持平衡)。但是它们始终以<<<<-开头,并在行尾加上标识符,然后在其自己的行中以相同标识符结尾。

话虽如此,如果您可以控制输入并确保输入中不包括“边沿情况”,例如块标题中间的注释,heredoc序列(看起来像模块块)等等,那么您可以能够通过逐行处理输入来获得“足够好”的结果:

  • 让B = 0
  • 对于输入中的每一行:
    • 如果B为零:
    • 如果该行与^module ["\w- ]*{相匹配,则对模块块执行您想执行的任何操作。
    • 对于该行中的每个字符:
    • 如果字符为{,则增加B
    • 如果字符为},则递减B

这使用幼稚的括号计数方法来近似地找到块的边界。如果输入中包含带有不平衡花括号的文字字符串(带引号或heredoc),它将失败,因此您也可以尝试通过计算打开/关闭引号和heredoc标记对来改善这一点。

缺少该语言的完整解析器,总会遇到一些无法解决的极端情况,但是如果您限制输入内容不包含您的简单规则集无法理解的任何情况,那么像以上可能对您有用。


如果您愿意用Go编写程序,则可以使用hclwrite软件包,该软件包是Terraform用于实现其语言语法的基础库的一部分。它具有完整的解析器,并允许对其读取的内容进行“外科手术”编辑,尽管在我撰写本文时,它似乎还没有用于向块添加注释的功能,因此它目前尚未准备好解决您的特定目标

这对于将来有其他与修改现有Terraform配置有关的其他目标的人可能有用,并且将来可能会获得其他功能来支持其他用例。