安全组和子网属于不同的网络

15

我正在创建一个基本的AWS CloudFormation模板,其中包含一个VPC、3个安全组和5个EC2实例,我的安全组类似于:

{
  "WebApplicationServerSG": {
    "Type": "AWS::EC2::SecurityGroup",
    "Properties": {
      "VpcId": {
        "Ref": "DevVpc"
      },
      "GroupDescription": "Enable HTTP, HTTPS and SSH access",
      "Tags": [
        {
          "Key": "Name",
          "Value": "WebApplicationServer Service Group"
        }
      ],
      "SecurityGroupIngress": [
        {
          "IpProtocol": "tcp",
          "FromPort": "443",
          "ToPort": "443",
          "CidrIp": "0.0.0.0/0"
        },
        {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        },
        {
          "IpProtocol": "tcp",
          "FromPort": "22",
          "ToPort": "22",
          "CidrIp": "0.0.0.0/0"
        }
      ],
      "SecurityGroupEgress": [
        {
          "IpProtocol": "tcp",
          "FromPort": "443",
          "ToPort": "443",
          "CidrIp": "0.0.0.0/0"
        },
        {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        },
        {
          "IpProtocol": "tcp",
          "FromPort": "22",
          "ToPort": "22",
          "CidrIp": "0.0.0.0/0"
        }
      ]
    },
    "Metadata": {
      "AWS::CloudFormation::Designer": {
        "id": "a7977f00-48d6-488f-9e23-9bcd0785d399"
      }
    }
  }
}

而 VPC 大致如下 -

{
  "DevVpc": {
    "Type": "AWS::EC2::VPC",
    "Properties": {
      "CidrBlock": "172.31.0.0/16",
      "EnableDnsSupport": "false",
      "EnableDnsHostnames": "false",
      "InstanceTenancy": "dedicated",
      "Tags": [
        {
          "Key": "Name",
          "Value": "DevStackVpc"
        }
      ]
    }
  }
}

使用模板创建堆栈时,我遇到了错误 -

安全组sg-31f91b5a和子网subnet-ea0aa3a7属于不同的网络。

11:13:01 UTC+0550   CREATE_FAILED   AWS::EC2::Instance  WebApplicationServer    Security group sg-5147a53a and subnet subnet-ea0aa3a7 belong to different networks.

这里有一个gist提供完整的模板,任何帮助都将不胜感激。


1
你的VPC子网在哪定义的? - Matt Houser
1
很可能问题出在子网定义上,完整的模板可以帮助确定。如果想要完全掌控代码,不要使用可视化编辑器 :) - Putnik
1
我在你的模板中没有看到任何子网声明。如果你交叉引用错误中的子网ID,你可能会发现它来自于你所在地区的默认VPC,而不是这个堆栈中的VPC,因此你的实例会去那里而不是这里。 - Michael - sqlbot
1
@Michael-sqlbot,能否请您提供一个示例呢?感谢您的指引。 - Jeet
1
据我所知,您需要创建EC2子网,然后为RDS实例声明两个或多个这些子网的逻辑集合,以用于RDS 子网组 - Michael - sqlbot
显示剩余5条评论
3个回答

22

如果有人在使用 Terraform 时遇到了这个问题,我曾经也收到过类似的错误消息,最终发生了以下情况:

variable "name" {}

locals {
  vpc_id    = "..."
  subnet_id = "..."
}

resource "aws_instance" "web" {
  ami                         = "ami-09def150731bdbcc2"
  instance_type               = "t3.micro"
  vpc_security_group_ids      = ["${aws_security_group.allow_http.id}"]

  user_data = <<-EOF
    #!/bin/bash
    sudo amazon-linux-extras install nginx1.12 -y
    sudo nginx
  EOF

  tags {
    Name = "${var.name}"
  }
}

resource "aws_security_group" "allow_http" {
  description = "Allow inbound HTTP traffic for ${var.name} instance"
  vpc_id      = "${local.vpc_id}"

  ingress {
    from_port   = 80
    to_port     = 80
    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"]
  }
}

我部署的子网未开启自动分配公共 IP功能。因此,我更新了aws_instance以包括subnet_idassociate_public_ip_address

resource "aws_instance" "web" {
  ami                         = "ami-09def150731bdbcc2"
  instance_type               = "t3.micro"
  subnet_id                   = "${local.subnet_id}"
  vpc_security_group_ids      = ["${aws_security_group.allow_http.id}"]
  associate_public_ip_address = true

  user_data = <<-EOF
    #!/bin/bash
    sudo amazon-linux-extras install nginx1.12 -y
    sudo nginx
  EOF

  tags {
    Name = "${var.name}"
  }
}

此后,一切正常运作。


这里我记录了故障排除步骤-https://jhooq.com/terraform-security-group-with-different-subnet - Rahul Wagh

15

我通过评论中提供的指针解决了上述问题,子网VPC安全组EC2实例之间的关系如下:

第一件要做并且应该被创建的是VPC, 第二个是子网,在这里你提到了之前创建的VpcId 第三步是在这里创建安全组,同时也提到了之前创建的VpcId 第四个是一个属性NetworkInterfaces,其中您提供SubnetIdGroupSet,它是安全组ID数组,这是您定义安全组、VPC和子网之间关系的位置,并且这就是解决问题的方法。

以下是实际起作用的示例模板 -

{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
    "DevServerKeyPair": {
        "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
        "Type": "AWS::EC2::KeyPair::KeyName",
        "ConstraintDescription": "Must be the name of an existing EC2 KeyPair."
    }
},
"Resources": {
    "DevVpc": {
        "Type": "AWS::EC2::VPC",
        "Properties": {
            "CidrBlock": "172.31.0.0/16",
            "EnableDnsSupport": "false",
            "EnableDnsHostnames": "false",
            "InstanceTenancy": "dedicated",
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "DevStackVpc"
                }
            ]
        }
    },
    "DevSubnet": {
        "Type": "AWS::EC2::Subnet",
        "Properties": {
            "VpcId": {
                "Ref": "DevVpc"
            },
            "CidrBlock": "172.31.0.0/16",
            "AvailabilityZone": {
                "Fn::Select": [
                    0,
                    {
                        "Fn::GetAZs": ""
                    }
                ]
            }
        }
    },
    "WebApplicationServerSG": {
        "Type": "AWS::EC2::SecurityGroup",
        "Properties": {
            "VpcId": {
                "Ref": "DevVpc"
            },
            "GroupDescription": "Enable HTTP, HTTPS and SSH access",
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "WebApplicationServer Service Group"
                }
            ],
            "SecurityGroupIngress": [
                {
                    "IpProtocol": "tcp",
                    "FromPort": "443",
                    "ToPort": "443",
                    "CidrIp": "0.0.0.0/0"
                },
                {
                    "IpProtocol": "tcp",
                    "FromPort": "80",
                    "ToPort": "80",
                    "CidrIp": "0.0.0.0/0"
                },
                {
                    "IpProtocol": "tcp",
                    "FromPort": "22",
                    "ToPort": "22",
                    "CidrIp": "0.0.0.0/0"
                }
            ],
            "SecurityGroupEgress": [
                {
                    "IpProtocol": "tcp",
                    "FromPort": "443",
                    "ToPort": "443",
                    "CidrIp": "0.0.0.0/0"
                },
                {
                    "IpProtocol": "tcp",
                    "FromPort": "80",
                    "ToPort": "80",
                    "CidrIp": "0.0.0.0/0"
                },
                {
                    "IpProtocol": "tcp",
                    "FromPort": "22",
                    "ToPort": "22",
                    "CidrIp": "0.0.0.0/0"
                }
            ]
        }
    },
    "WebApplicationServer": {
        "Type": "AWS::EC2::Instance",
        "Properties": {
            "ImageId": "ami-f3e5aa9c",
            "InstanceType": "t2.micro",
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "WebApplicationServer"
                }
            ],
            "KeyName": {
                "Ref": "DevServerKeyPair"
            },
            "NetworkInterfaces": [
                {
                    "SubnetId": {"Ref": "DevSubnet"},
                    "AssociatePublicIpAddress": "true",
                    "DeviceIndex": "0",
                    "GroupSet": [{ "Ref" : "WebApplicationServerSG" }]
                }
            ]
        }
    }
  }
}

希望这能帮助到寻找类似问题答案的人。


1
//你对关系的清晰解释帮了我很多,Jeet。感谢你的跟进。 - Nathan Basanese
很有帮助。我添加了一个 AWS::EC2::NetworkInterface,然后在 AWS::EC2::Instance 资源的 NetworkInterfaces 属性的 NetworkInterfaceId 属性中引用它。请确保删除 SecurityGroupIds 和 AssociatePublicIpAddress 属性。 - abk
我之前缺失了这部分代码 // 在这里你需要提到 VpcId 的安全组 现在将 VpcId 添加到安全组中,它可以正常工作了。 谢谢Jeet。 - Kamran

3
你所使用的安全组存在问题!当你使用模板创建一个安全组时,默认使用默认VPC。在创建安全组的CloudFormation模板中,需要标识出你想要使用的(非默认)VpcId,这样可以解决这个问题。或者你可以手动创建一个新的安全组并使用(非默认)VPC,然后运行新的实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接