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

And*_*ius 8 continuous-integration terraform terraform-provider-aws

更新

我不明白,但我重新运行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
Run Code Online (Sandbox Code Playgroud)

现在我的 security_group_ec2 内容:

主要.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"]
  }
}
Run Code Online (Sandbox Code Playgroud)

变量.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"
}
Run Code Online (Sandbox Code Playgroud)

输出:

output "sg_id" {
  value = "${aws_security_group.sg.id}"
}
Run Code Online (Sandbox Code Playgroud)

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

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}"
}
Run Code Online (Sandbox Code Playgroud)

这是运行时的错误输出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.
Run Code Online (Sandbox Code Playgroud)

PS我可能需要以某种方式指示在调用模块时创建了资源?

Ale*_*der 5

这看起来像是一个竞争条件。Terraform 尝试并行创建彼此不依赖的资源,在这种情况下,它看起来像是试图销毁安全组,同时尝试使用相同的名称module.security_group_staging创建它们。你改名了吗?module.security_group_staging_ec2 security_group_stagingsecurity_group_staging_ec2

毁灭成功了,但创造却失败了,因为它与毁灭同时进行。

第二次运行它时,没有竞争条件,因为module.security_group_staging已经被破坏了。

顺便说一句,不要将单独的环境保留在同一个状态文件中通常是一个好主意。