如何在不对 bid_price 变量进行硬编码的情况下创建使用 spot 实例的 EMR 集群资源?

How can I create an EMR cluster resource that uses spot instances without hardcoding the bid_price variable?

我正在使用 Terraform 创建一个使用 spot 实例作为核心实例的 AWS EMR 集群。

我知道我可以在 aws_emr_cluster 资源的 core_instance_group 块中使用 bid_price 变量,但我不想硬编码价格,因为我必须更改每次实例类型更改时手动设置它们。

使用 AWS Web UI,我可以选择 "Use on-demand as max price" 选项。这正是我要重现的内容,但在 Terraform 中。

现在我正在尝试使用 aws_pricing_product 数据源来解决我的问题。你可以在下面看到我到目前为止的内容:

data "aws_pricing_product" "m4_large_price" {
  service_code = "AmazonEC2"

  filters {
   field = "instanceType"
   value = "m4.large"
  }

  filters {
   field = "operatingSystem"
   value = "Linux"
  }

  filters {
   field = "tenancy"
   value = "Shared"
  }

  filters {
   field = "usagetype"
   value = "BoxUsage:m4.large"
  }

  filters {
   field = "preInstalledSw"
   value = "NA"
  }

  filters {
    field = "location"
    value = "US East (N. Virginia)"
  }
}

data.aws_pricing_product.m4_large_price.result returns一个json包含单个产品的详细信息(您可以查看示例here). The actual on-demand price is buried somewhere inside this json, but I don't know how can I get it (image generated with http://jsonviewer.stack.hu/的响应):

我知道我可以通过使用外部数据源并将 aws cli 调用的输出管道传输到 jq 之类的东西来解决这个问题,例如:

aws pricing get-products --filters "Type=TERM_MATCH,Field=sku,Value=8VCNEHQMSCQS4P39" --format-version aws_v1 --service-code AmazonEC2 | jq [........]

但我想知道是否有任何方法可以完成我想用纯 Terraform 做的事情。提前致谢!

不幸的是,添加它的 aws_pricing_product data source docs don't expand on how it should be used effectively but the discussion in the pull request 增加了一些见解。

在 Terraform 0.12 中,您应该能够使用 jsondecode function 通过链接的拉取请求中的以下示例很好地获得您想要的内容:

data "aws_pricing_product" "example" {
  service_code = "AmazonRedshift"

  filters = [
    {
      field = "instanceType"
      value = "ds1.xlarge"
    },
    {
      field = "location"
      value = "US East (N. Virginia)"
    },
  ]
}

# Potential Terraform 0.12 syntax - may change during implementation
# Also, not sure about the exact attribute reference architecture myself :)
output "example" {
  values = jsondecode(data.json_query.example.value).terms.OnDemand.*.priceDimensions.*.pricePerUnit.USD
}

如果您卡在 Terraform <0.12 上,除了您已经建议的外部数据源方法之外,您可能很难在 Terraform 中本地执行此操作。

@cfelipe 将 ${jsondecode(data.aws_pricing_product.m4_large_price.value).terms.OnDemand.*.priceDimensions.*.pricePerUnit.USD}" 放在 Locals