Terraform - почему это не вызывает круговую зависимость? - PullRequest
1 голос
/ 22 февраля 2020

Реестр Terraform AWS VP C пример terraform- aws -vpc / examples / complete-vpc / main.tf имеет приведенный ниже код, который кажется мне круговой зависимостью.

data "aws_security_group" "default" {
  name   = "default"
  vpc_id = module.vpc.vpc_id
}

module "vpc" {
  source = "../../"

  name = "complete-example"

...
 # VPC endpoint for SSM
  enable_ssm_endpoint              = true
  ssm_endpoint_private_dns_enabled = true
  ssm_endpoint_security_group_ids  = [data.aws_security_group.default.id] # <----- 

...

data.aws_security_group.default относится к «module.vp c .vpc_id», а module.vp c относится к «data.aws_security_group». default.id».

Пожалуйста, объясните, почему это не вызывает ошибку, и почему module.vp c может ссылаться на data.aws_security_group.default.id?

1 Ответ

1 голос
/ 04 марта 2020

В языке Terraform модуль создает отдельное пространство имен, но это , а не узел в графе зависимостей. Вместо этого каждая из входных переменных и выходных значений модуля является отдельными узлами в графе зависимостей.

По этой причине эта конфигурация содержит следующие зависимости:

  • Ресурс data.aws_security_group.default зависит от module.vpc.vpc_id, который является именно блоком output "vpc_id" в этом модуле, а не модулем в целом.
  • Переменная vpc модуля *1013* зависит от ресурса data.aws_security_group.default.

Мы не можем видеть внутреннюю часть модуля vpc в вашем вопросе здесь, но с вышесказанным все в порядке, пока внутри модуля нет соединения зависимостей между output "vpc_id" и variable "ssm_endpoint_security_group_ids".

Я предполагаю, что такого соединения не существует, и поэтому порядок оценки объектов здесь будет примерно таким:

  • aws_vpc.example в module.vpc создано (Я просто придумал название для этого, потому что оно не включено в ваш вопрос)
  • Оценивается output "vpc_id" в module.vpc, ссылаясь на module.vpc.aws_vpc.example и производя module.vpc.vpc_id.
  • data.aws_security_group.default в режиме root Файл читается, используя значение module.vpc.vpc_id.
  • . variable "ssm_endpoint_security_group_ids" для module.vpc оценивается, ссылаясь на data.aws_security_group.default.
  • aws_vpc_endpoint.example в module.vpc создан включая ссылку на var.ssm_endpoint_security_group_ids.

Обратите внимание, что во всем вышесказанном я говорю об объектах в модулях, а не о самих модулях. Модули служат только для создания отдельных пространств имен для объектов, а затем сами отдельные объекты (включая отдельные блоки variable и output) участвуют в графике зависимостей.


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

Еще одна причина, по которой мы могли бы использовать это Это возможно, когда два модуля естественно зависят друг от друга, например, в экспериментальном модуле, который я построил , который скрывает некоторые хитрые детали настройки пиринговых соединений VP C:

locals {
  vpc_nets = {
    us-west-2 = module.vpc_usw2
    us-east-1 = module.vpc_use1
  }
}

module "peering_usw2" {
  source = "../../modules/peering-mesh"

  region_vpc_networks = local.vpc_nets
  other_region_connections = {
    us-east-1 = module.peering_use1.outgoing_connection_ids
  }

  providers = {
    aws = aws.usw2
  }
}

module "peering_use1" {
  source = "../../modules/peering-mesh"

  region_vpc_networks = local.vpc_nets
  other_region_connections = {
    us-west-2 = module.peering_usw2.outgoing_connection_ids
  }

  providers = {
    aws = aws.use1
  }
}

(выше приведен только соответствующий фрагмент из примера в репозитории модулей .)

В приведенном выше случае модуль peering-mesh тщательно спроектирован, чтобы разрешить эту взаимную ссылку, внутренне решить для каждой пары региональных VPC, какой из них будет инициатором пиринга, а какой - пиринговым акцептором. Вывод outgoing_connection_ids относится только к ресурсу aws_vpc_peering_connection, а aws_vpc_peering_connection_accepter относится только к var.other_region_connections, поэтому в результате получается куча параллельных операций для создания ресурсов aws_vpc_peering_connection, за которыми следует куча параллельных операций для создать aws_vpc_peering_connection_accepter ресурсов.

...