мое требование состоит в том, чтобы сгенерировать файл переменных terraform на основе среды, я пытаюсь сгенерировать их с помощью сценария bash/shell, но у меня возникают трудности с преобразованием вывода в язык terraform HCL (я не могу использовать JSON, потому что я манипулирую ими далее в модуле terraform)
Текущий вывод API (который необходимо преобразовать в HCL):
'cluster_name1' 'REGION1' 'Volume_Size1' 'Instance_Size1'
'cluster_name2' 'REGION2' 'Volume_Size2' 'Instance_Size2'
'cluster_name3' 'REGION3' 'Volume_Size3' 'Instance_Size3'
{...}
Вывод в формате CSV:
"cluster_name1","REGION1","Volume_Size1","Instance_Size1"
"cluster_name2","REGION2","Volume_Size2","Instance_Size2"
"cluster_name3","REGION3","Volume_Size3","Instance_Size3"
{...}
Требуемый формат:
variable "cluster_configuration" {
default = [
{
"cluster_name" : "cluster_name1"
"cluster_region" : "REGION1"
"instance_db_size" : "Volume_Size1"
"instance_size" : "Instance_Size1"
},
{
"cluster_name" : "cluster_name2"
"cluster_region" : "REGION2"
"instance_db_size" : "Volume_Size2"
"instance_size" : "Instance_Size2"
},
{
"cluster_name" : "cluster_name3"
"cluster_region" : "REGION3"
"instance_db_size" : "Volume_Size3"
"instance_size" : "Instance_Size3"
},
{....}
]
}
Мой код Terraform, просто для справки:
locals {
dbconfig = [
for db in var.cluster_configuration : [{
instance_name = db.cluster_name
db_size = db.instance_db_size
instance_size = db.instance_size
cluster_region = db.cluster_region
}
]
]
}
Я пробовал с AWK и SED, но пока безуспешно.
Не могли бы вы показать код bash, который вы пробовали?
@MarkReed Я пробовал так, cat details| awk '{print "\"cluster_name\" : ", "\""$1"\"" "\"cluster_region\" : ", "\""$2"\"" }'
@chepner, я уже просмотрел эти документы, но пока безрезультатно.
Вы также можете определить TF_VAR_cluster_configuration
и присвоить этой переменной среды значение при запуске плана/применения.
Terraform может обрабатывать данные JSON, если вы правильно определяете объекты. Возможно, вы сможете использовать jq
для форматирования данных CSV в соответствующий JSON для использования Terraform. Если я правильно помню, фильтр будет примерно таким
# This *very* much assumes that the quotes aren't actually
# quoting fields that contain a real comma. jq is not suitable
# for robustly parsing CSV data.
[
inputs |
split(",") |
map(ltrimstr("\"")) |
map(rtrimstr("\"")) |
{
cluster_name: .[0],
cluster_region: .[1],
instance_db_size: .[2],
instance_size: .[3]
}
] | {variable: {cluster_configuration: {default: .}}}
(Возможно, есть место для улучшения.) Предположим, вы сохранили это в файл, например api.jq
, а вывод вашего API находится в output.csv
, тогда
$ jq -nRf api.jq output.csv
{
"variable": {
"cluster_configuration": {
"default": [
{
"cluster_name": "cluster_name1",
"cluster_region": "REGION1",
"instance_db_size": "Volume_Size1",
"instance_size": "Instance_Size1"
},
{
"cluster_name": "cluster_name2",
"cluster_region": "REGION2",
"instance_db_size": "Volume_Size2",
"instance_size": "Instance_Size2"
},
{
"cluster_name": "cluster_name3",
"cluster_region": "REGION3",
"instance_db_size": "Volume_Size3",
"instance_size": "Instance_Size3"
}
]
}
}
}
Однако может быть проще выбрать язык по вашему выбору с помощью соответствующего анализатора CSV для создания JSON.
Это решение отлично работает, спасибо за помощь. @chepner
Решение с использованием jq.
Содержимое соответствует запросу (но указанное форматирование игнорируется)
INPUT = "
'cluster_name1' 'REGION1' 'Volume_Size1' 'Instance_Size1'
'cluster_name2' 'REGION2' 'Volume_Size2' 'Instance_Size2'
'cluster_name3' 'REGION3' 'Volume_Size3' 'Instance_Size3'
"
jq -srR '
split("\n") | # split lines
map(split(" ") | # split fields
select(any) | # remove emty lines
map(.[1:-1]) | # remove enclosing quotes
{
cluster_name: .[0],
cluster_region: .[1],
instance_db_size: .[2],
instance_size: .[3]
}) |
"variable \"cluster_configuration\" {",
" default = ",
.,
"}"
' <<< "$INPUT"
Выход
variable "cluster_configuration" {
default =
[
{
"cluster_name": "cluster_name1",
"cluster_region": "REGION1",
"instance_db_size": "Volume_Size1",
"instance_size": "Instance_Size1"
},
{
"cluster_name": "cluster_name2",
"cluster_region": "REGION2",
"instance_db_size": "Volume_Size2",
"instance_size": "Instance_Size2"
},
{
"cluster_name": "cluster_name3",
"cluster_region": "REGION3",
"instance_db_size": "Volume_Size3",
"instance_size": "Instance_Size3"
}
]
}
Terraform может обрабатывать соответствующим образом определенные объекты JSON. Они более подробные, чем соответствующие HCL, но их легче генерировать программно. См. developer.hashicorp.com/terraform/language/syntax/json.