【问题标题】:Terraform: how to not duplicate security groups when creating it using modules?Terraform:使用模块创建安全组时如何不重复安全组?
【发布时间】:2019-02-04 16:25:20
【问题描述】:

更新

我不明白,但我重新运行了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 内容:

ma​​in.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.

附:我可能需要以某种方式指出调用模块时创建的资源?

【问题讨论】:

  • 问题可能是您的本地状态未正确更新或以某种方式修改为以前的状态。 Terraform 严重依赖其本地状态文件来描述您的基础设施的当前状况。

标签: continuous-integration terraform terraform-provider-aws


【解决方案1】:

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

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

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

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

【讨论】:

  • 是的,我确实重命名了它。感谢您的建议。我知道将环境分开是更好的主意,尽管目前我只是在玩 - 生产环境还不是真实的。但是是的,我需要把它分开。
猜你喜欢
  • 1970-01-01
  • 2020-05-30
  • 2023-03-29
  • 2019-08-20
  • 1970-01-01
  • 2020-08-27
  • 1970-01-01
  • 2021-04-06
  • 1970-01-01
相关资源
最近更新 更多