Terraform-provider-aws: Removing ingress rules from aws_security_group is not detected

Created on 30 Apr 2018  路  11Comments  路  Source: hashicorp/terraform-provider-aws

_This issue was originally opened by @BookOfGreg as hashicorp/terraform#17967. It was migrated here as a result of the provider split. The original body of the issue is below._


Terraform Version

Terraform v0.11.7
+ provider.aws v1.15.0

Terraform Configuration Files

Removing Ingress from a security group has no effect

Before:

resource "aws_security_group" "my_group" {
  vpc_id      = "${aws_vpc.my_vpc.id}"
  name        = "my_group"
  description = "App security group"

  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"]
  }
}

After:

resource "aws_security_group" "my_group" {
  vpc_id      = "${aws_vpc.my_vpc.id}"
  name        = "my_group"
  description = "App security group"

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

Expected Behavior

My security group has no ingress on it

Actual Behavior

My security group still has port 80

References

I've seen issues with similar symptoms for tools written in Go, such as this K8s bug I found:
https://github.com/kubernetes/kubernetes/issues/59482
Not sure if relevant or not, feel free to remove the link from this post if it's a red herring.

bug servicec2

Most helpful comment

What happens if you set ingress/egress to an empty list, rather than removing it entirely?

ingress = []

All 11 comments

I am also seeing this issue. Removing the last ingress or egress rule from the security group results in no plan being generated.

I have tested the following scenarios

  • Removing one or more Ingress/Egress rules but leaving at least one rule: Works correctly
  • Removing one or more Ingress/Egress rules and leaving zero remaining: Does not work correctly (no plan generated)

I think any change that removes the last rule of either type does not work correctly.

Using separate aws_security_group_rule resources instead of inline rules works around this problem.

Also seeing this.

Terraform v0.11.7
+ provider.aws v1.21.0

Using separate aws_security_group_rule resources instead of inline rules works around this problem.

This does work, unless you are trying to transition from inline ingress rules to separate aws_security_group_rule resources. Then you just get errors back from AWS telling you that you have duplicate rules.

A (somewhat ugly) solution that I'm using is to add a dummy ingress rule to force it to remove the real ingress rules as I move them to aws_security_group_rule resources. Then later the dummy rule can be removed (though the actual ingress rule won't be removed until/unless this bug is fixed at some point or someone manually fixes it).

Edit: Actually doing it this way will cause it to cycle back and forth between removing external rules and adding them back in, so there's no good non-manual solution I have found yet.

FYI, there's an open pull request to support aws_security_group_rule resource import: https://github.com/terraform-providers/terraform-provider-aws/pull/6027 (馃憤 reactions on the PR can help prioritize)

Same problem

  • Terraform v0.11.11
  • provider.aws v1.56.0
  • provider.random v2.0.0

I ran into this on egress rules as well. I feel like it is a pretty important bug since apply runs with no errors, but rules are not removed. This could potentially lead to security issues due to extra rules that are still there.

It does make me wonder how many other list-removal-related bugs there are currently if it's systematic to both this, Kubernetes, and other programs written in Go.

What happens if you set ingress/egress to an empty list, rather than removing it entirely?

ingress = []

What happens if you set ingress/egress to an empty list, rather than removing it entirely?

This worked for me. Thanks!

What happens if you set ingress/egress to an empty list, rather than removing it entirely?

ingress = []

This one works and can also be applied as workaroud when you tried to use the dynamic block.

Bugged with dynamic:

  dynamic "ingress" {
    for_each = var.security_group_ingress_rules

    content {
      from_port       = ingress.value.from_port
      to_port         = ingress.value.to_port
      protocol        = ingress.value.protocol
      cidr_blocks     = ingress.value.cidr_blocks
      security_groups = ingress.value.security_groups
      self            = ingress.value.self
    }
  }

Workaround using a for loop:

  ingress = [for _, rule in var.security_group_ingress_rules : {
    from_port       = rule.from_port
    to_port         = rule.to_port
    protocol        = rule.protocol
    cidr_blocks     = rule.cidr_blocks
    security_groups = rule.security_groups
    self            = rule.self

    description      = null
    ipv6_cidr_blocks = null
    prefix_list_ids  = null
  }]

the downside is that you have to provide all parameters (event the ones that are not required) and set unused to null.

It's ugly, but it works for now if you cannot use aws_security_group_rule resource.

Was this page helpful?
0 / 5 - 0 ratings