首页 文章

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

提问于
浏览
0

Update

我没有得到它,但我重申 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"
}

outputs:

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}"
}

这是运行 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.

附:我可能需要以某种方式表明在调用模块时创建了资源?

1 回答

  • 0

    这看起来像竞争条件 . Terraform尝试并行创建不依赖于彼此的资源,在这种情况下,它似乎试图从 module.security_group_staging 中破坏安全组,同时尝试在 module.security_group_staging_ec2 中创建具有相同名称的安全组 . 您是否将 security_group_staging 重命名为 security_group_staging_ec2

    破坏成功了,但创造失败了,因为它与破坏并行 .

    你第二次跑它没有竞争条件,因为 module.security_group_staging 已被摧毁 .

    作为旁注,通常不要将不同的环境保存在同一个状态文件中 .

相关问题