【问题标题】:Avoid Terraform module to create duplicate resources?避免 Terraform 模块创建重复资源?
【发布时间】:2019-10-31 00:17:45
【问题描述】:

我有以下项目结构来使用 Terraform 在 AWS 上构建 Lambda 函数:

.
├── aws.tf
├── dev.tfvars
├── global_variables.tf -> ../shared/global_variables.tf
├── main.tf
├── module
│   ├── data_source.tf
│   ├── main.tf
│   ├── output.tf
│   ├── role.tf
│   ├── security_groups.tf
│   ├── sources
│   │   ├── function1.zip
│   │   └── function2.zip
│   └── variables.tf
└── vars.tf

在 .main.tf 文件中,我有这段代码将创建 2 个不同的 lambda 函数:

module "function1" {
  source = "./module"

  function_name    = "function1"
  source_code      = "function1.zip"

  runtime          = "${var.runtime}"
  memory_size      = "${var.memory_size}"
  timeout          = "${var.timeout}"
  aws_region       = "${var.aws_region}"
  vpc_id           = "${var.vpc_id}"
}


module "function2" {
  source = "./module"

  function_name    = "function2"
  source_code      = "function2.zip"  
  runtime          = "${var.runtime}"
  memory_size      = "${var.memory_size}"
  timeout          = "${var.timeout}"
  aws_region       = "${var.aws_region}"
  vpc_id           = "${var.vpc_id}"
}

问题在于部署 terraform 会两次创建所有资源。对于 Lambda 来说没关系,这就是目的,但对于安全组和角色来说,这不是我想要的。

例如这个安全组被创建了 2 次:

resource "aws_security_group" "lambda-sg" {
  vpc_id = "${data.aws_vpc.main_vpc.id}"
  name   = "sacem-${var.project}-sg-lambda-${var.function_name}-${var.environment}"

  egress {
    protocol    = "-1"
    from_port   = 0
    to_port     = 0
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    protocol        = "-1"
    from_port       = 0
    to_port         = 0
    cidr_blocks     = "${var.authorized_ip}"
  }
  # To solve dependcies error when updating the security groups
  lifecycle {
    create_before_destroy = true
    ignore_changes        = ["tags.DateTimeTag"]
  }

  tags = "${merge(var.resource_tagging, map("Name", "${var.project}-sg-lambda-${var.function_name}-${var.environment}"))}"

}

很明显,问题出在项目的结构上。你能帮忙解决吗?

谢谢。

【问题讨论】:

  • 那你的模块设计有问题。将非模块特定的东西(即不应在每次使用模块时单独创建)放在模块之外。

标签: amazon-web-services terraform


【解决方案1】:

如果您在模块中创建 SecurityGroup,它将被创建每个模块包含一次

我相信 sg name 的某些变量值会在您包含模块时发生变化,对吧?因此,sg name 对于两个模块都是唯一的,可以创建两次而不会出错。

如果您选择静态名称,Terraform 在尝试从模块 2 创建 sg 时会抛出错误,因为资源已经存在(由模块 1 创建)。

因此,您可以在模块本身之外定义 sg 资源以仅创建一次。 然后,您可以将创建的 sg 的 id 作为变量传递给模块包含,并将其用于其他资源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    • 2017-11-11
    • 1970-01-01
    • 2019-08-26
    • 2022-06-15
    • 2023-02-23
    • 2019-03-19
    相关资源
    最近更新 更多