3

I am running on AWS and I have VPC-A and VPC-B I have a VPC peering between the two VPCs

I want to allow traffic from SecurityGroupB which is in VPC-B to SecurityGroupA in VPC-A

Up until now I did it with the ruby client with the following call

        security_group_a.authorize_ingress(
          ip_permissions: [
            {
              from_port: "-1",
              ip_protocol: "-1",
              to_port: "-1",
              user_id_group_pairs: [
                {
                  description: "Accept all traffic from SecurityGroupB",
                  group_id: security_group_b.id,
                  vpc_id: vpc_b.id,
                  vpc_peering_connection_id: peering_connection_id,
                },
              ],
            },
          ]
        )

I had a look at terraform's aws_security_group_rule but couldn't find anything equivalent to the settings described above.

When I try to just put the security group B in the ingress of security group A I get the following error:

Error: Error authorizing security group rule type ingress: InvalidGroup.NotFound: You have specified two resources that belong to different networks

what am I doing wrong here? how can I create a ruleto allow traffic from security group on VPC B into a security group on VPC A, assuming I have a peering connection set up?

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Erez Rabih
  • 15,562
  • 3
  • 47
  • 64

2 Answers2

6

Security group rules can reference security groups in peered VPCs if the following conditions are met:

  1. The VPCs must be in the same region
  2. The peering connection must be in the active state
  3. If the peered VPC is in another account, the reference must include the account number as a prefix. For example, 123456789012/sg-1a2b3c4d.

So long as these conditions are met, you should have no problem.

Here's an example of how a Terraform resource would look:

resource "aws_security_group_rule" "example" {
  type                     = "ingress"
  from_port                = 0
  to_port                  = 65535
  protocol                 = "tcp"
  security_group_id        = "sg-123456"
  source_security_group_id = "sg-789012"
}
Ben Whaley
  • 32,811
  • 7
  • 87
  • 85
  • Slight nitpick but that third option is woolly. If you omit it then the AWS API will resolve it to the correct account ID and append it. This then creates a diff as Terraform will want to change `123456789012/sg-1a2b3c4d` back to `sg-1a2b3c4d` because it isn't aware of this mangling. I suspect if you were unlucky enough to end up with multiple security group IDs that were the same across peered VPCs in different accounts then something bad would happen because I don't think security group IDs are globally unique and only account wide unique. – ydaetskcoR May 12 '20 at 08:37
  • It is surprising behaviour though and I'd always recommend that people specify the account ID as a prefix even if you didn't mind the Terraform diff it created (or weren't using Terraform). Also the answer would probably be improved with a link to the docs around VPC peering and security groups. – ydaetskcoR May 12 '20 at 08:38
2

so @Ben Whaley's answer was correct in terms of specifying a security group from another VPC in an ingress rule.

Regarding the error I received

Error: Error authorizing security group rule type ingress: InvalidGroup.NotFound: You have specified two resources that belong to different networks

The cause was that I had to add a dependency on the vpc peering connection before adding the security group to the ingress rule:

resource "aws_security_group_rule" "vpc_a_to_vpc_b" {
  security_group_id = var.vpc_a_security_group_id

  description = "Allow vpc_b to communicate with vpc_a"
  type = "ingress"
  from_port = 0
  to_port = 0
  protocol = "-1"
  source_security_group_id = aws_security_group.vpc_b.id

  depends_on = [aws_vpc_peering_connection.vpc_a_to_vpc_b]
}

The depends_on is what made the difference

Erez Rabih
  • 15,562
  • 3
  • 47
  • 64