Дело будет диктовать Использование карт в терраформе - PullRequest
0 голосов
/ 20 апреля 2020

Я ищу способ определения списка ключей s sh в файле переменных, чтобы я мог получить их в коде модуля tf для моего вычислительного экземпляра следующим образом:

  metadata = {
    ssh-keys = join("\n", [for user, key in var.ssh_keys : "${user}:${key}"])
  }

Вот содержимое файла variables, который я написал для достижения этого:

variable "ssh_keys" {
  type = "map"

  default = {
    {
      user   = "amary"
      key = "${file("/Users/nixmind/.ssh/amary.pub")}"
    }
    {
      user   = "nixmind"
      key = "${file("/Users/nixmind/.ssh/nixmind.pub")}"
    }
  }

}

Но у меня возникает эта ошибка:

Ошибка: отсутствует значение атрибута

в строке variables.tf, в переменной "ssh_keys":
4:
5:
6:
7:
8:
9:

Ожидается значение атрибута, представленное знаком равенства ("=").

Я не уверен, что действительно получу, что там делать.

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Здесь есть несколько разных проблем. Я буду говорить о них по одному.

Во-первых, ваше default выражение не использует правильный синтаксис карты. Вот исправленная версия:

variable "ssh_keys" {
  type = map(string)
  default = {
    amary   = file("/Users/nixmind/.ssh/amary.pub")
    nixmind = file("/Users/nixmind/.ssh/nixmind.pub")
  }
}

Вторая проблема заключается в том, что значение переменной default не может включать вызовы функций, поэтому вызовы file выше недопустимы. Здесь есть несколько различных вариантов того, как с этим справиться, но если это переменная в модуле root, то я ожидаю, что было бы наиболее удобно, чтобы переменная была картой имена файлов , а не карта содержимого этих файлов, а затем сам модуль может читать содержимое этих файлов на более позднем этапе:

variable "ssh_key_files" {
  type = map(string)
  default = {
    amary   = "/Users/nixmind/.ssh/amary.pub"
    nixmind = "/Users/nixmind/.ssh/nixmind.pub"
  }
}

Ваше выражение for для построения список строк «user: key» был корректен в соответствии с тем, как вы определили переменную ранее, но с учетом вышеописанной настройки использования имен файлов вместо содержимого нам потребуется дополнительный шаг для фактического чтения файлов:

locals {
  ssh_keys = { for u, fn in var.ssh_key_files : u => file(fn) }
}

Затем мы можем использовать local.ssh_keys, чтобы получить карту от имени пользователя до ключа, необходимого для выражения метаданных:

  metadata = {
    ssh-keys = join("\n", [for user, key in local.ssh_keys : "${user}:${key}"])
  }

Если вы do хотите этого модуль может принимать уже загруженные данные ключа S SH вместо имен файлов, тогда это возможно, но вместо переменной по умолчанию потребуется переменная, потому что она будет зависеть от вызывающего odule для загрузки файлов.

Определение без значения по умолчанию будет выглядеть так:

variable "ssh_keys" {
  type = map(string)
}

Тогда ваш вызывающий модуль, если он есть (то есть, если это не так) модуль root) может вызывать file для загрузки в:

module "example" {
  source = "./modules/example"

  ssh_keys = {
    amary   = file("/Users/nixmind/.ssh/amary.pub")
    nixmind = file("/Users/nixmind/.ssh/nixmind.pub")
  }
}

Выше приведен разумный интерфейс для общего модуля, который будет вызываться из другого модуля, подобного этому, но это не удобный дизайн для модуля root, потому что в этом случае «вызывающий» - это человек или сценарий, запускающий программу terraform, и поэтому для предоставления данных из этих файлов потребуется их чтение вне Terraform и передавая результаты.

0 голосов
/ 22 апреля 2020

Моя проблема была semanti c, а не syntacti c, потому что я не могу использовать карту карты, как пытался. Вместо этого я использовал список и ошибка исчезла.

variable ssh_keys {
 type = list(object({
  user=string
  key=string
 }))
 default = [
  {
   "user"  = "amaret93"
   "key" = "/Users/valerietchala/.ssh/amaret93.pub"
  },
  {
   "user"  = "nixmind"
   "key" = "/Users/valerietchala/.ssh/nixmind.pub"
  }
 ]
}

Но ответ Мартина выше также является более хорошим подходом

...