Hello all,
I’m trying to generate a working HCL configuration as explained here
.
The HCL syntax is not overly complex and I’m using HashiCorp hclwrite for the task:
resource "grafana_data_source" "prometheus" {
type = "prometheus"
name = "mimir"
url = "https://my-instances.com"
basic_auth_enabled = true
basic_auth_username = "username"
json_data_encoded = jsonencode({
httpMethod = "POST"
prometheusType = "Mimir"
prometheusVersion = "2.4.0"
})
secure_json_data_encoded = jsonencode({
basicAuthPassword = "password"
})
}
But I’m stuck on how to generate the sections for json_data_encoded
and secure_json_data_encoded
as they are dictionaries but they are embedded into the jsonencode() function call.
My data comes from an existing JSON file which I got using the REST API and my Golang code looks like this:
func WriteHcl(hclFile string, jsonPayload []map[string]interface{}, verbose bool, dryRun bool) error {
// https://grafana.com/docs/grafana-cloud/infrastructure-as-code/terraform/terraform-cloud-stack/
// https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source
hcl := hclwrite.NewEmptyFile()
rootBody := hcl.Body()
encodedRegexp, _ := regexp.Compile(`jsonData|secureJsonData`)
for _, dataSource := range jsonPayload {
dsName := dataSource["name"]
resourceBlock := rootBody.AppendNewBlock("resource", []string{"grafana_data_source", dsName.(string)})
resourceBody := resourceBlock.Body()
resourceBody.AppendNewline()
resourceBody.SetAttributeValue("provider", cty.StringVal("grafana"))
resourceBody.SetAttributeValue("is_default", cty.BoolVal(false))
for key, value := range dataSource {
str, check := value.(string)
if check {
resourceBody.SetAttributeValue(key, cty.StringVal(str))
}
bol, check := value.(bool)
if check {
resourceBody.SetAttributeValue(key, cty.BoolVal(bol))
}
itg, check := value.(int64)
if check {
resourceBody.SetAttributeValue(key, cty.NumberIntVal(itg))
}
flt, check := value.(float64)
if check {
resourceBody.SetAttributeValue(key, cty.NumberFloatVal(flt))
}
match := encodedRegexp.MatchString(key)
if match {
// This is where I need to embed JSON encoded extra DATA
fmt.Println("DEBUG: ", key, "->", value)
}
}
resourceBody.AppendNewline()
}
rootBody.AppendNewline()
if verbose {
fmt.Printf("HCL payload: %s", hcl.Bytes())
}
if !dryRun {
return os.WriteFile(hclFile, hcl.Bytes(), 0644)
}
return nil
}
I’m fairly new to Golang, please apologize if there is an obvious way to do this which I missed.
Thanks,