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

时间:2018-08-29 19:36:49

标签: 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

现在我的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}"
}

这是运行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。我可能需要以某种方式指示在调用模块时已创建资源?

1 个答案:

答案 0 :(得分:1)

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

破坏成功,但创建失败,因为它与破坏同时进行。

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

请注意,通常不要将单独的环境放在同一状态文件中。