Terraform - Как использовать tfvars с модулями

В трех разных средах я хочу иметь возможность динамически устанавливать переменные в зависимости от среды. В моем примере ниже допустим, что тип экземпляра отличается для dev и prod. Я не могу ссылаться на instance_type в модуле, ЕСЛИ у меня нет vars.tf файла вместе с моим terraform.tfvars.

Я получаю следующую ошибку:

unknown variable referenced: 'instance_type'. define it with 'variable' blocks

Если это так, то разве этот файл не будет таким же файлом в modules/apollo/vars.tf?

Я думал, что modules/apollo/vars.tf определяет необходимые переменные, необходимые для модуля. Я не думал, что это необходимо на уровне "корня" под env-dev/services/apollo/. Если есть «лучший» способ сделать это, я весь в ушах.

├── env-dev
│   └── services
│       └── apollo
│           ├── main.tf
│           ├── terraform.tfvars    
│           └── vars.tf # Do i need this?
├── env-test
├── global
├── mgmt
└── modules
    ├── apollo
    │   ├── main.tf
    │   ├── user_data.tpl
    │   └── vars.tf
    └── defaults
        └── main.tf

env-dev / services / apollo / terraform.tfvars

instance_type    = "t2.medium"

env-prod / services / apollo / terraform.tfvars

instance_type    = "t2.large"

модули / apollo / vars.tf

variable "instance_type" {
  description = "EC2 Instance Type"
}

модули / apollo / main.tf

resource "aws_instance" "instance" {     
  ...
  instance_type           = "${var.instance_type}"
  ...
}

person sdot257    schedule 10.10.2017    source источник
comment
Не уверен, что лучше всего, но я не использую файл terraform.tfvars. Я предоставлю значения непосредственно внутри использования блока модуля. В этом случае я предоставлю значения переменных модуля в env-dev / services / apollo / main.tf и удалю terraform.tfvars и vars.tf. Я добавлю output.tf для любых желаемых значений. Для любых конфиденциальных значений я буду использовать хранилище ключей.   -  person Aurvoir    schedule 07.10.2020
comment
Одним из недостатков моего использования, указанного выше, будет то, что в случае использования нескольких модулей в env-dev / services / apollo / main.tf значения общих переменных должны будут предоставляться несколько раз. Позднее изменение значения переменной потребует изменений в нескольких местах. Вот где .tfvars станет удобным для однократного определения переменных и использования значений в нескольких модулях. В случае изменения переменной можно изменить только одно место.   -  person Aurvoir    schedule 08.10.2020


Ответы (2)


Отрегулируйте структуру, это я понимаю для ваших приложений.

├── dev
│   └── apollo_terraform.tfvars    
├── test
│   └── apollo_terraform.tfvars
├── global
│   └── apollo_terraform.tfvars
├── mgmt
│   └── apollo_terraform.tfvars
├── main.tf,  vars.tf, output.tf, apollo.tf, default.tf, etc
└── modules
    ├── apollo
    │   ├── main.tf
    │   ├── user_data.tpl
    │   └── vars.tf
    └── defaults
        └── main.tf

apollo.tf будет иметь исходный код модуля для использования модуля совместного использования apollo. Такая же настройка для default.tf

ваша команда plan / apply должна быть такой:

terraform plan -var-file=${env}/apollo_terraform.tfvars
person BMW    schedule 10.10.2017
comment
В этом случае вы бы объявили свои конфигурации инфраструктуры для всех сред в одних и тех же файлах, а также имели бы один файл состояния, что не идеально? - person Aurimas N.; 31.07.2019

Я пытался добиться чего-то похожего, так как интуитивно кажется, что так оно и должно работать, однако я прихожу к выводу, что модули просто не предназначены для этого варианта использования. В основном вы присваиваете значения переменным, которых нет в вашем test / prod, чтобы обойти это, вместо предоставления присваиваний в .tfvars, вы можете попытаться объявить их со значениями по умолчанию: env-dev / services / apollo / variables.tf

variable "instance_type" {
 default = "t2.medium"
}

env-prod / services / apollo / variables.tf

variable "instance_type" {
 default = "t2.large"
}

если они объявлены и назначены со значениями по умолчанию, они по-прежнему не связываются автоматически с входными переменными, объявленными в вашем модуле, поэтому дополнительно в env-dev/services/apollo/main.tf и env-prod/services/apollo/main.tf вам все равно потребуется заполнить свойства для вашего модуля:

module "aws_inst" {
 source = "..\\..\\..\\modules\\apollo"
 instance_type = "${var.instance_type}"
}

Вы можете быстро увидеть, как это противоречит цели модулей в этом сценарии.

Чтобы уточнить, я думаю, что модули не были предназначены для определения одного ресурса для каждого модуля, чтобы иметь возможность динамически заполнять его значения, а скорее для создания «коллекций» ресурсов внутри модуля, где они могут совместно использовать / повторно использовать одни и те же переменные.

Обратите внимание, что когда вы присваиваете значение ключу instance_type в вызов модуля, вы фактически передаете это значение модулям входной переменной, которая затем присваивается ключу ресурса с тем же именем.

person Aurimas N.    schedule 31.07.2019