我的目標是決議一個 HCL 配置(Terraform Configuration),然后將收集到的關于變數、輸出、資源塊和資料塊的資料寫入 Markdown 檔案。
但是,只要我嘗試解碼具有多個標簽的資源塊,變數和輸出就沒有問題。
作品:
variable "foo" {
type = "bar"
}
不作業:
resource "foo" "bar" {
name = "biz"
}
錯誤:Extraneous label for resource; Only 1 labels (name) are expected for resource blocks.
型別宣告代碼:
import (
"log"
"os"
"strconv"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsyntax"
)
type Variable struct {
Name string `hcl:",label"`
Description string `hcl:"description,optional"`
Sensitive bool `hcl:"sensitive,optional"`
Type *hcl.Attribute `hcl:"type,optional"`
Default *hcl.Attribute `hcl:"default,optional"`
Options hcl.Body `hcl:",remain"`
}
type Output struct {
Name string `hcl:",label"`
Description string `hcl:"description,optional"`
Sensitive bool `hcl:"sensitive,optional"`
Value string `hcl:"value,optional"`
Options hcl.Body `hcl:",remain"`
}
type Resource struct {
Name string `hcl:"name,label"`
Options hcl.Body `hcl:",remain"`
}
type Data struct {
Name string `hcl:"name,label"`
Options hcl.Body `hcl:",remain"`
}
type Config struct {
Outputs []*Output `hcl:"output,block"`
Variables []*Variable `hcl:"variable,block"`
Resources []*Resource `hcl:"resource,block"`
Data []*Data `hcl:"data,block"`
}
解碼代碼:
func createDocs(hclPath string) map[string][]map[string]string {
var variables, outputs []map[string]string
parsedConfig := make(map[string][]map[string]string)
hclConfig := make(map[string][]byte)
c := &Config{}
// Iterate all Terraform files and safe the contents in the hclConfig map
for _, file := range filesInDirectory(hclPath, ".tf") {
fileContent, err := os.ReadFile(hclPath "/" file.Name())
if err != nil {
log.Fatal(err)
}
hclConfig[file.Name()] = fileContent
}
// Iterate all file contents
for k, v := range hclConfig {
parsedConfig, diags := hclsyntax.ParseConfig(v, k, hcl.Pos{Line: 1, Column: 1})
if diags.HasErrors() {
log.Fatal(diags)
}
diags = gohcl.DecodeBody(parsedConfig.Body, nil, c)
if diags.HasErrors() {
log.Fatal(diags)
}
}
for _, v := range c.Variables {
var variableType string
var variableDefault string
if v.Type != nil {
variableType = (v.Type.Expr).Variables()[0].RootName()
}
if v.Default != nil {
variableDefault = (v.Default.Expr).Variables()[0].RootName()
}
variables = append(variables, map[string]string{"name": v.Name, "description": v.Description,
"sensitive": strconv.FormatBool(v.Sensitive), "type": variableType, "default": variableDefault})
}
for _, v := range c.Outputs {
outputs = append(outputs, map[string]string{"name": v.Name, "description": v.Description,
"sensitive": strconv.FormatBool(v.Sensitive), "value": v.Value})
}
parsedConfig["variables"], parsedConfig["outputs"] = variables, outputs
return parsedConfig
}
問題:如何從資源塊中決議多個標簽?
uj5u.com熱心網友回復:
您共享的錯誤是由于type Resource
. Terraform 中的resource
塊(和塊)需要兩個標簽,指示資源型別和名稱。為了在您暗示的架構中與這些結構型別匹配,您需要定義標記為的欄位:data
label
type Resource struct {
Type string `hcl:"type,label"`
Name string `hcl:"name,label"`
Options hcl.Body `hcl:",remain"`
}
type Data struct {
Type string `hcl:"type,label"`
Name string `hcl:"name,label"`
Options hcl.Body `hcl:",remain"`
}
盡管這應該適用于您在此處顯示的有限輸入,但我想提醒您,您使用的是更高級別的gohcl
API,它只能解碼 HCL 的一個子集,該子集很好地映射到 Go 的結構型別。hcl.Body
Terraform 本身直接使用and的低級 API hcl.Expression
,這使得 Terraform 語言可以包含一些gohcl
API 無法直接表示的 HCL 特性。
根據您的目標,您可能會發現使用官方庫更好terraform-config-inspect
,它可以在比 HCL API 本身更高的抽象級別上決議、解碼和描述 Terraform 語言的子集。它還支持為 Terraform 版本撰寫的模塊,可以追溯到 Terraform v0.11,并且是支持由Terraform Registry完成的模塊分析的實作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/473043.html