避免 Terraform 模块创建重复资源?

use*_*406 3 amazon-web-services terraform

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

\n\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 aws.tf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dev.tfvars\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 global_variables.tf -> ../shared/global_variables.tf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.tf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 module\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 data_source.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 output.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 role.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 security_groups.tf\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 sources\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 function1.zip\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 function2.zip\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 variables.tf\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 vars.tf\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
module "function1" {\n  source = "./module"\n\n  function_name    = "function1"\n  source_code      = "function1.zip"\n\n  runtime          = "${var.runtime}"\n  memory_size      = "${var.memory_size}"\n  timeout          = "${var.timeout}"\n  aws_region       = "${var.aws_region}"\n  vpc_id           = "${var.vpc_id}"\n}\n\n\nmodule "function2" {\n  source = "./module"\n\n  function_name    = "function2"\n  source_code      = "function2.zip"  \n  runtime          = "${var.runtime}"\n  memory_size      = "${var.memory_size}"\n  timeout          = "${var.timeout}"\n  aws_region       = "${var.aws_region}"\n  vpc_id           = "${var.vpc_id}"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

例如,此安全组创建了 2 次:

\n\n
resource "aws_security_group" "lambda-sg" {\n  vpc_id = "${data.aws_vpc.main_vpc.id}"\n  name   = "sacem-${var.project}-sg-lambda-${var.function_name}-${var.environment}"\n\n  egress {\n    protocol    = "-1"\n    from_port   = 0\n    to_port     = 0\n    cidr_blocks = ["0.0.0.0/0"]\n  }\n\n  ingress {\n    protocol        = "-1"\n    from_port       = 0\n    to_port         = 0\n    cidr_blocks     = "${var.authorized_ip}"\n  }\n  # To solve dependcies error when updating the security groups\n  lifecycle {\n    create_before_destroy = true\n    ignore_changes        = ["tags.DateTimeTag"]\n  }\n\n  tags = "${merge(var.resource_tagging, map("Name", "${var.project}-sg-lambda-${var.function_name}-${var.environment}"))}"\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

谢谢。

\n

rfl*_*ume 5

如果您在模块内创建 SecurityGroup,则每个模块包含都会创建一次

我相信当您包含该模块时,sg 的某些变量值会name发生变化,对吗?因此,sgname对于两个模块来说都是唯一的,并且可以创建两次而不会出现错误。

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

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