Проверьте, существует ли переменная - Синтаксис шаблона Terraform - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь проверить, существует ли переменная в файле шаблона, используя синтаксис шаблона terraform, но я получаю сообщение об ошибке This object does not have an attribute named "proxy_set_header.

$ cat nginx.conf.tmpl

%{ for location in jsondecode(locations) }
location ${location.path} {
    %{ if location.proxy_set_header }
       proxy_set_header ${location.proxy_set_header};
    %{ endif }
}
%{ endfor }

Я пытался использовать if location.proxy_set_header != "" и if location.proxy_set_header без успеха.

Как проверить, существует ли переменная с шаблонами строк?

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Если вы используете Terraform 0.12.20 или более поздней версии, вы можете использовать новую функцию can, чтобы кратко написать чек, подобный этому:

%{ for location in jsondecode(locations) }
location ${location.path} {
    %{ if can(location.proxy_set_header) }
       proxy_set_header ${location.proxy_set_header};
    %{ endif }
}
%{ endfor }

can Функция возвращает значение true, если данное выражение может вычисляться без ошибки.


В документации действительно рекомендуется использовать try в большинстве случаев, но в этой конкретной ситуации ваша цель - показать вообще ничего, если этот атрибут отсутствует, и поэтому этот эквивалентный подход с try, я думаю, сложнее понять для будущего читателя:

%{ for location in jsondecode(locations) }
location ${location.path} {
    ${ try("proxy_set_header ${location.proxy_set_header};", "") }
}
%{ endfor }

А также быть (субъективно) более непрозрачно для намерения, это игнорирует рекомендацию в документах try использовать его только с поиском атрибутов и выражениями преобразования типов. Поэтому я думаю, что использование can выше оправдано из-за его относительной ясности, но любой способ должен работать.

1 голос
/ 14 февраля 2020

Я бы сделал что-то вроде следующего, используя contains и keys

%{ for location in jsondecode(locations) }
location ${location.path} {
    %{ if contains(keys(location), "proxy_set_header") }
       proxy_set_header ${location.proxy_set_header};
    %{ endif }
}
%{ endfor }

Проанализированный JSON по существу становится map, который можно проверить на содержание ключа.

Я проверил это с помощью следующего кода

data "template_file" "init" {
  template = file("${path.module}/file.template")
  vars = {
    locations = <<DOC
[
  {
    "path": "foo",
    "proxy_set_header": "foohdr"
  },
  {
    "path": "bar"
  }
]
DOC
  }
}

output "answer" {
  value = data.template_file.init.rendered
}

, и у него был следующий вывод

Outputs:

answer = 
location foo {

       proxy_set_header foohdr;

}

location bar {

}

...