7
votes

There is a repeatable configuration that I see in many Terraform projects where the provider is AWS: The configuration of an outbound (egress) rule to allow ALL outbound traffic.

As far as I understand, this is the default behavior in AWS as mentioned in the AWS user guide:

By default, a security group includes an outbound rule that allows all outbound traffic. You can remove the rule and add outbound rules that allow specific outbound traffic only. If your security group has no outbound rules, no outbound traffic originating from your instance is allowed.

An example for a common Terraform setup for security group - The focus of my question is the egress block:

 resource "aws_security_group" "my_sg" {
       name        = "my_sg"
       description = "Some description"
       vpc_id      = "${aws_vpc.my_vpc.id}"
       tags {
         Name = "my_sg_tag"
       }

       #Not redundant - Because a new security group has no inbound rules.
       ingress {
         from_port   = "80"
         to_port     = "80"
         protocol    = "TCP"
         cidr_blocks = ["0.0.0.0/0"]
       }

       #Isn't this redundant?    
       egress {
         from_port   = 0
         to_port     = 0
         protocol    = "-1"
         cidr_blocks = ["0.0.0.0/0"]
       }
}

Is this configuration being made for documentation or does it have a technical reason?

1

1 Answers

11
votes

The documentation for the aws_security_group resource specifically states that they remove AWS' default egress rule intentionally by default and require users to specify it to limit surprises to users:

NOTE on Egress rules: By default, AWS creates an ALLOW ALL egress rule when creating a new Security Group inside of a VPC. When creating a new Security Group inside a VPC, Terraform will remove this default rule, and require you specifically re-create it if you desire that rule. We feel this leads to fewer surprises in terms of controlling your egress rules. If you desire this rule to be in place, you can use this egress block:

egress {
  from_port   = 0
  to_port     = 0
  protocol    = "-1"
  cidr_blocks = ["0.0.0.0/0"]
}

There's also a technical/UX reason here in that it would be tricky to make Terraform understand whether it should keep the allow all egress rule when making changes to the security group. Should it always provide the allow all egress rule unless another egress rule is specified and then if so remove the default? How would that work with the combination of the aws_security_group_rule resource?

AWS have made the decision that a default rule to allow all egress outbound is a nicer user experience than not having it (and confusing people as to why their instance is unable to communicate outbound) without too much of a security impact (compared to the equivalent for inbound). Even if they were to change their mind on the benefit of this now they would be unable to do this without massively breaking a lot of people's setups/workflows which AWS is very reluctant to do.

Terraform, on the other hand, has made the decision the other way and that suits the tool better as well as slightly improving the security posture of the tool at the expense of making people define a repeated egress block in a lot of places.

If you particularly care about the repetition and you do always want to allow all egress traffic then you might find it useful to use a module instead that automatically includes an allow all egress rule.