首页 文章

尝试使用Terraform创建AWS VPC安全组时出现周期错误

提问于
浏览
3

我想创建2个VPC安全组 .

一个用于VPC的Bastion主机,一个用于私有子网 .

# BASTION # 
resource "aws_security_group" "VPC-BastionSG" {
  name        = "VPC-BastionSG"
  description = "The sec group for the Bastion instance"
  vpc_id      = "aws_vpc.VPC.id"

  ingress {
      from_port = 22
      to_port   = 22
      protocol  = "tcp"
      cidr_blocks = ["my.super.ip/32"]
  } 

  egress {
      # Access to the Private subnet from the bastion host[ssh]
      from_port = 22
      to_port   = 22
      protocol  = "tcp"
      security_groups = ["${aws_security_group.VPC-PrivateSG.id}"]
  }
  egress {
      # Access to the Private subnet from the bastion host[jenkins]
      from_port = 8686
      to_port   = 8686
      protocol  = "tcp"
      security_groups = ["${aws_security_group.VPC-PrivateSG.id}"]
  }

  tags = {
    Name = "VPC-BastionSG"
  }
}

# PRIVATE #
resource "aws_security_group" "VPC-PrivateSG" {
  name        = "VPC-PrivateSG"
  description = "The sec group for the private subnet"
  vpc_id      = "aws_vpc.VPC.id"

  ingress {
      from_port = 22
      to_port   = 22
      protocol  = "tcp"
      security_groups = ["${aws_security_group.VPC-BastionSG.id}"]
  }
  ingress {
      from_port = 80
      to_port   = 80
      protocol  = "tcp"
      security_groups = ["${aws_security_group.VPC-PublicSG.id}"]
  }
  ingress {
      from_port = 443
      to_port   = 443
      protocol  = "tcp"
      security_groups = ["${aws_security_group.VPC-PublicSG.id}"]
  }
  ingress {
      from_port = 3306
      to_port   = 3306
      protocol  = "tcp"
      security_groups = ["${aws_security_group.VPC-PublicSG.id}"]
  }
  ingress {
      from_port = 8686
      to_port   = 8686
      protocol  = "tcp"
      security_groups = ["${aws_security_group.VPC-BastionSG.id}"]
  }
  ingress {
      # ALL TRAFFIC from the same subnet
      from_port = 0
      to_port   = 0
      protocol  = "-1"
      self      = true
  }
  egress {
      # ALL TRAFFIC to outside world
      from_port = 0
      to_port   = 0
      protocol  = "-1"
      cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "VPC-PrivateSG"
  }
}

当我 terraform plan 它,返回此错误:

**`Error configuring: 1 error(s) occurred:
* Cycle: aws_security_group.VPC-BastionSG, aws_security_group.VPC-PrivateSG`**

如果我从PrivateSG注释掉BastionSG的入口规则,那么计划就可以了 .

另外,如果我从BastionSG注释掉PrivateSG的出口规则,它也可以正常执行 .

AWS Scenario 2 for building a VPC with Public/Private subnets and Bastion host描述了我尝试设置的架构 .

我通过AWS控制台配置完全相同的设置,它可以正常播放 .

为什么Terraform不接受它?是否有另一种方法将Bastion安全组与私有安全组连接?

EDIT

据我所知,两个组之间存在一个循环引用,即使在AWS中它是有效的,它仍然需要打破 .

因此,我考虑允许来自Bastion sec组的所有出站流量(0.0.0.0/0),而不是将其指定给各个安全组 .

它会对安全性产生不良影响吗?

1 回答

  • 13

    Terraform尝试为其正在处理的文件夹中定义的所有资源构建依赖关系链 . 这样做可以使它在需要按特定顺序构建事物时解决,并且对于它如何工作非常关键 .

    显然,您的示例将失败,因为您具有循环依赖(如Terraform帮助指出的那样),其中每个安全组依赖于已创建的另一个安全组 .

    有时这些可能很难解决,可能意味着您需要重新考虑您正在尝试做的事情(正如您所提到的,一种选择是简单地允许所有出口流量从堡垒主机输出并仅限制私有的入口流量实例)但在这种情况下,您可以选择将aws_security_group_rule资源与aws_security_group资源结合使用 .

    这意味着我们可以首先定义没有规则的空安全组,然后我们可以将其用作我们为组创建的安全组规则的目标 .

    一个简单的示例可能如下所示:

    resource "aws_security_group" "bastion" {
      name = "bastion"
      description = "Bastion security group"
    }
    
    resource "aws_security_group_rule" "bastion-to-private-ssh-egress" {
        type = "egress"
        from_port = 22
        to_port = 22
        protocol = "tcp"
        security_group_id = "${aws_security_group.bastion.id}"
        source_security_group_id = "${aws_security_group.private.id}"
    }
    
    resource "aws_security_group" "private" {
      name = "private"
      description = "Private security group"
    }
    
    resource "aws_security_group_rule" "private-from-bastion-ssh-ingress" {
        type = "ingress"
        from_port = 22
        to_port = 22
        protocol = "tcp"
        security_group_id = "${aws_security_group.private.id}"
        source_security_group_id = "${aws_security_group.bastion.id}"
    }
    

    现在,Terraform可以看到依赖链表明必须在这两个安全组规则之前创建两个安全组,因为它们都依赖于已经创建的组 .

相关问题