0%

terraform使用jsonencod输出json字符串

在terraform中,常见的输出json字符串或创建json文件的手段是使用流式标记, 如下代码所示:

1
2
3
4
5
6
7
8
9
10
11
12
resource "user" "admin" {
name = "admin"
}

resource "service" "portal" {
permission = <<DATA
{
"user": "${user.admin.name}"
"permission": "*"
}
DATA
}

但是这样的写法不仅繁琐,也容易出错,由于字符串中夹杂大量的变量引用,DATA标记中间的内容很难提供语法检查
常见的错误包括:

  • 最后一个元素不能带逗号
  • 引号及括号没有闭合
  • 夹杂中文字符

并且这些错误属于json语法问题,在terraform plan甚至apply期间是无法发现的,等到resource部署之后才被发现,可能会造成无法挽回的结果。

上述代码的json中便缺失一个逗号,读者是否有看出来呢?

为了解决这些问题,建议大家使用jsonencode函数代替直接编写字符串,得益于tf在语法上的良好兼容,从json迁移到jsonencode并不需要多少工作。

例如上述代码使用jsonencode可以简单的写成如下形式

1
2
3
4
5
6
7
8
9
10
resource "user" "admin" {
name = "admin"
}

resource "service" "portal" {
permission = jsonencode({
"user": "${user.admin.name}",
"permission": "*"
})
}

可以看到几乎就是简单的使用jsonencode讲原来的内容包了起来。

更进一步的,可以整理成如下形式

1
2
3
4
5
6
resource "service" "portal" {
permission = jsonencode({
user: user.admin.name,
permission: "*",
})
}

或者

1
2
3
4
5
6
resource "service" "portal" {
permission = jsonencode({
user = user.admin.name
permission = "*"
})
}

由于tf语法对逗号非常宽容,因此不论写不写逗号都不会影响输出的json,同时就算有语法错误,在plan阶段也可以轻易发现,还能少写很多引号。

因此推荐大家在输出json时都使用这种方法。