Terraform:如何在使用模块创建时不复制安全组?

Terraform: how to not duplicate security groups when creating it using modules?

更新

我不明白,但我重新运行 terraform apply 并且它没有尝试复制资源(没有错误)。现在它可以正确检查资源。有点意外的事件结束。


我正在学习 Terraform,我创建了允许创建一些基本安全组的模块。它 运行 第一次很好,并按预期创建资源。但是如果我 运行 terraform apply 第二次,它会尝试再次创建相同的组然后我会得到重复的错误,因为这样的安全组已经存在。

如果我在没有 module 的情况下直接创建安全组,Terraform 会识别它并且不会尝试重新创建现有资源。

我这里可能做错了。

这是我的模块以及我如何尝试使用它:

我的项目结构是这样的

├── main.tf
├── modules
│   ├── security_group_ec2
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── security_group_rds
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── scripts
│   └── update-odoo-cfg.py
├── security_groups.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── variables.tf
└── vpc.tf

现在我的security_group_ec2内容:

main.tf:

resource "aws_security_group" "sg" {
  name = "${var.name}"
  description = "${var.description}"
  vpc_id = "${var.vpc_id}"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

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

variables.tf:

variable "name" {
  description = "Name of security group"
}

variable "description" {
  description = "Description of security group"
}
variable "vpc_id" {
  description = "Virtual Private Cloud ID to assign"
}

输出:

output "sg_id" {
  value = "${aws_security_group.sg.id}"
}

这是我调用模块创建两个安全组的文件。

security_groups.tf:

# EC2
module "security_group_staging_ec2" {
  source = "modules/security_group_ec2"
  name = "ec2_staging_sg"
  description = "EC2 Staging Security Group"
  vpc_id = "${aws_default_vpc.default.id}"
}

module "security_group_prod_ec2" {
  source = "modules/security_group_ec2"
  name = "ec2_prod_sg"
  description = "EC2 Production Security Group"
  vpc_id = "${aws_default_vpc.default.id}"
}

这是运行ning terraform apply:

时的错误输出
module.security_group_staging.aws_security_group.sg: Destruction complete after 1s
module.security_group_prod.aws_security_group.sg: Destruction complete after 1s

Error: Error applying plan:

2 error(s) occurred:

* module.security_group_staging_ec2.aws_security_group.sg: 1 error(s) occurred:

* aws_security_group.sg: Error creating Security Group: InvalidGroup.Duplicate: The security group 'ec2_staging_sg' already exists for VPC 'vpc-2a84a741'
    status code: 400, request id: 835004f0-d8a1-4ed5-8e21-17f01eb18a23
* module.security_group_prod_ec2.aws_security_group.sg: 1 error(s) occurred:

* aws_security_group.sg: Error creating Security Group: InvalidGroup.Duplicate: The security group 'ec2_prod_sg' already exists for VPC 'vpc-2a84a741'
    status code: 400, request id: 953b23e8-20cb-4ccb-940a-6a9ddab54d53

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

P.S。我可能需要以某种方式指示调用模块时创建了资源?

这看起来像是一个竞争条件。 Terraform 尝试并行创建不相互依赖的资源,在这种情况下,它看起来像是试图从 module.security_group_staging 中销毁安全组,同时尝试在 module.security_group_staging_ec2 中创建它们 同名。您是否将 security_group_staging 重命名为 security_group_staging_ec2

销毁成功,但创建失败,因为它运行与销毁并行

你第二次 运行 它没有竞争条件,因为 module.security_group_staging 已经被摧毁了。

附带说明一下,不要将不同的环境保存在同一个状态文件中通常是个好主意。