#terraform #hcl
#terraform #hcl
Вопрос:
У меня есть поддерживаемый сторонней компанией файл с большим количеством строк, и он выглядит как:
# a comment lines
aaa.bbb.cc 423
ddd.ee.fff 452
...
tons.like.them 111
Есть ли какой-либо способ загрузить файл на локальную карту и получить доступ к его ключам в Terraform, используя синтаксис, подобный?:
"${lookup(var.locals.mylist, 'ddd.ee.fff', 0)}"
Комментарии:
1. Вероятно, это связано
local-exec
с каким-то сценарием / манипуляцией.2. Да, я пробую этот вариант прямо сейчас, и, похоже, это перспективный выбор.
Ответ №1:
Часто лучше предварительно обработать файлы, подобные этому, используя отдельную программу, написанную на языке программирования общего назначения, поскольку DSL Terraform не очень подходит для такого рода логики однорангового синтаксического анализа.
В Terraform версии 0.11 и более ранних отсутствуют примитивы, необходимые для реализации подобного синтаксического анализа в самом языке. В версии v0.12.0 (которая на момент написания находится в бета-версии) представлены некоторые примитивы, которые действительно позволяют реализовать такого рода синтаксический анализ, хотя я все равно обычно предпочитаю делать это вне Terraform в качестве этапа предварительной обработки, если это вообще возможно.
С учетом сказанного, вот пример преобразования файла, подобного вашему примеру, в карту с использованием функций Terraform v0.12:
locals {
raw_lines = [
for line in split("n", file("${path.module}/input.txt")) :
split(" ", trimspace(line))
]
lines = [
for line in local.raw_lines :
line if length(line[0]) > 0 amp;amp; substr(line[0], 0, 1) != "#"
]
records = { for line in local.lines : line[0] => line[1] }
}
output "result" {
value = local.records
}
Учитывая следующий входной файл:
# a comment line
aaa.bbb.cc 423
ddd.ee.fff 452
tons.like.them 111
# another comment
another.record abc
Это приводит к следующему результату с использованием Terraform v0.12.0-beta1:
$ terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
result = {
"aaa.bbb.cc" = "423"
"another.record" = "abc"
"ddd.ee.fff" = "452"
"tons.like.them" = "111"
}
Комментарии:
1. Спасибо. Очень хороший ответ для 0.12. Я отмечаю это как решение, хотя я не могу протестировать его прямо сейчас. Но версия 0.12 — это большой шаг вперед для Terraform, и я надеюсь, что она скоро выйдет.
Ответ №2:
Имя файла — myfile.txt
, а содержимое -:
# a comment line
aaa.bbb.cc 423
ddd.ee.fff 452
...
tons.like.them 111
Запрос данных должен выглядеть следующим образом:
data "external" "myfile" {
program = [
"bash",
"${path.module}/template/parser.sh",
"${path.module}/template/myfile.txt",
"ddd.ee.fff"
]
}
И template/parser.sh
содержит:
#!/usr/bin/env bash
set -eo pipefail
CONFIG=$(cat $1|grep -v '#' | sed 's/ /=/g' | jq -R -n -c '.data = ([inputs|split("=")|{(.[0]):.[1]}] |add)')
OUTPUT=$(echo $CONFIG | jq -r '.data["'$2'"]')
jq -n --arg output "$OUTPUT" '{"output":$output}'
Этот сложный скрипт вернет:
{"output": 452}
И интерполяция может быть использована для получения результирующего значения:
${data.external.myfile.result.output}
К сожалению, я не нашел, как загрузить полный список строк в Terraform и получить к ним доступ, используя «переменную переменной» или lookup(). Если скрипты bash возвращают результат первого jq
вызова, Terraform выдает исключение:
command "bash" produced invalid JSON: json: cannot unmarshal object into Go value of type string
Update2: Для доступа к результирующим значениям вам необходимо использовать дополнительный ключ «.result» перед фактическим ключом «.output» из скрипта.
Комментарии:
1. эй, как мы можем получить список значений или список пар ключ-значение.. У меня есть
{"privateIpAddress":"10.48.131.30"} {"privateIpAddress":"10.48.131.34"}
это, и я хотел бы извлечь только ip-адреса и обработать их дальше..