Я использую Terraform для создания кластера AWS EMR, который использует спотовые экземпляры в качестве основных экземпляров.
Я знаю, что могу использовать переменную bid_price
в блоке core_instance_group
на ресурсе aws_emr_cluster
, но я не хочу жестко кодировать цены, так как мне придется менять их вручную каждый раз, когда изменяется тип экземпляра.
Используя веб-интерфейс AWS, я могу выбрать вариант "Использовать по требованию как максимальную цену". Именно это я и пытаюсь воспроизвести, но в 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
возвращает json
, содержащий сведения об одном продукте (вы можете проверить ответ примера здесь). Фактическая цена по запросу скрыта где-то внутри этого json, но я не знаю, как ее получить (изображение, сгенерированное с помощью 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
документы источника данных не раскрывает, как его следует эффективно использовать, но обсуждение в пулреквесте, который его добавил, дает некоторое представление.
В Terraform 0.12 вы должны иметь возможность использовать jsondecode
функция, чтобы получить то, что вы хотите, со следующим примером, приведенным в связанном запросе на вытягивание:
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
Привет! В конце концов я отказался от управления EMR и перешел на Databricks. Это отличный продукт для моего случая использования. Тем не менее, спасибо за ваш ответ. Такие люди, как ты, делают это НАСТОЛЬКО классным! = Д
Я использую Terraform 0.12, так что все в порядке. Я попытался создать локальную переменную со значением
"${jsondecode(data.aws_pricing_product.m4_large_price.value).terms.OnDemand.*.priceDimensions.*.pricePerUnit.USD}"
, но получил следующую ошибку: Знаковое выражение (*) нельзя использовать внутри другого знакового выражения, состоящего только из атрибутов.. Я попробовал несколько вариантов этого выражения, но безуспешно.