如何从Terraform中的外部数据源访问JSON?

时间:2019-04-05 21:56:57

标签: ruby terraform

我正在从http地形数据源接收JSON

data "http" "example" {
  url = "${var.cloudwatch_endpoint}/api/v0/components"

  # Optional request headers
  request_headers {
    "Accept" = "application/json"
    "X-Api-Key" = "${var.api_key}"
  }
}

它输出以下内容。

http = [{"componentID":"k8QEbeuHdDnU","name":"Jenkins","description":"","status":"Partial Outage","order":1553796836},{"componentID":"ui","name":"ui","description":"","status":"Operational","order":1554483781},{"componentID":"auth","name":"auth","description":"","status":"Operational","order":1554483781},{"componentID":"elig","name":"elig","description":"","status":"Operational","order":1554483781},{"componentID":"kong","name":"kong","description":"","status":"Operational","order":1554483781}]

是terraform中的字符串。为了将此字符串转换为JSON,我将其传递到external数据源,这是一个简单的ruby函数。这是通过它的地形。

data "external" "component_ids" {
  program = ["ruby", "./fetchComponent.rb",]

  query = {
    data = "${data.http.example.body}"

  }
}

这是红宝石功能

 #!/usr/bin/env ruby
require 'json'
data = JSON.parse(STDIN.read)
results = data.to_json
STDOUT.write results

所有这些工作。 external数据输出以下内容(看起来与http输出相同),但是根据terraform文档,该值应该为map

external1 = {
  data = [{"componentID":"k8QEbeuHdDnU","name":"Jenkins","description":"","status":"Partial Outage","order":1553796836},{"componentID":"ui","name":"ui","description":"","status":"Operational","order":1554483781},{"componentID":"auth","name":"auth","description":"","status":"Operational","order":1554483781},{"componentID":"elig","name":"elig","description":"","status":"Operational","order":1554483781},{"componentID":"kong","name":"kong","description":"","status":"Operational","order":1554483781}]
}

我期望现在可以访问external数据源内部的数据。我无法。

最终,我要做的是在list数据源中创建componentID个变量的external

我尝试过的一些事情

* output.external: key "0" does not exist in map data.external.component_ids.result in:

${data.external.component_ids.result[0]}

* output.external: At column 3, line 1: element: argument 1 should be type list, got type string in:

${element(data.external.component_ids.result["componentID"],0)}
* output.external: key "componentID" does not exist in map data.external.component_ids.result in:

${data.external.component_ids.result["componentID"]}
ternal: lookup: lookup failed to find 'componentID' in:

${lookup(data.external.component_ids.*.result[0], "componentID")}

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

无法使用变量cloudwatch_endpoint进行测试,因此我必须考虑解决方案。

Terraform无法在0.11.x之前直接解码json。但是有一种解决方法可用于嵌套列表。

您需要调整红宝石以使输出作为下面的变量http,然后您就可以得到所需的东西。

$ cat main.tf 
variable "http" {
  type = "list"
  default = [{componentID = "k8QEbeuHdDnU", name = "Jenkins"}]
}

output "http" {
  value = "${lookup(var.http[0], "componentID")}"
}

$ terraform apply 

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

http = k8QEbeuHdDnU