hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.

Home Page:https://registry.terraform.io/providers/hashicorp/aws

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot remove inline ingress or egress from aws_security_group

Nuru opened this issue · comments

commented

It appears this behavior has been part of aws_security_group from the start. There are bug reports about it from as far back as 2017 (now over 4 years old). If this is not going to be fixed, then please document and explain the behavior and provide a workaround.

After you provision an aws_security_group with dynamic inline ingress and egress rules, if you try to remove all of one kind of rule, the plan/apply succeeds, but none of the rules are removed.

Although this is something of a duplicate, I am opening it anyway because the bugs it duplicates are so old and this is a serious bug. I suggest leaving this open despite it being a duplicate because it has all the Terraform code and commands you need to reproduce this bug easily.

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform CLI and Terraform AWS Provider Version

Terraform v1.0.1
on darwin_amd64

  • provider registry.terraform.io/hashicorp/aws v3.47.0

Affected Resource(s)

  • aws_security_group

Terraform Configuration Files

Terraform code
variable "traffic_disabled" {
  type        = bool
  default     = false
  description = "Set true to remove all access provided by this security group"
}

locals {
  all_ingress_rules = var.traffic_disabled ? [] : [{
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }]
  all_egress_rules = var.traffic_disabled ? [] : [{
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["10.0.0.0/8"]
  }]
}

resource "aws_security_group" "default" {
  name   = "example-sg"
  vpc_id = "vpc-05d0373b3df8bde3b"
  tags   = { Name = "github-issue-example" }

  dynamic "ingress" {
    for_each = local.all_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
    }
  }

  dynamic "egress" {
    for_each = local.all_egress_rules
    content {
      from_port   = egress.value.from_port
      to_port     = egress.value.to_port
      protocol    = egress.value.protocol
      cidr_blocks = egress.value.cidr_blocks
    }
  }
}

provider "aws" {
  region = "us-west-2"
}

Expected Behavior

Removing inline ingress or egress rules should remove them from the security group

Actual Behavior

Removing all inline ingress or egress rules has no effect on the security group. (The security group is updated
as expected if at least one inline ingress and one inline egress rule remain.)

Steps to Reproduce

  • Terraform code posted above under "Terraform Configuration Files".
  • Change the vpc_id to a VPC in your account.
  • (optional) Change the region in the AWS provider to your preferred region.
  1. Initial provisioning with no inline rules: traffic_disabled = true
  • Security group is created with no ingress or egress rules
- Terraform output
$ terraform apply -lock=false -var traffic_disabled=true

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_security_group.default will be created
  + resource "aws_security_group" "default" {
      + arn                    = (known after apply)
      + description            = "Managed by Terraform"
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = (known after apply)
      + name                   = "example-sg"
      + name_prefix            = (known after apply)
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + tags                   = {
          + "Name" = "github-issue-example"
        }
      + tags_all               = {
          + "Name" = "github-issue-example"
        }
      + vpc_id                 = "vpc-05d0373b3df8bde3b"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_security_group.default: Creating...
aws_security_group.default: Creation complete after 2s [id=sg-0b7ce8ca55451342e]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
  1. Add ingress and egress: traffic_disabled = false
  • Rules properly added
- Terraform output
$ terraform apply -lock=false -var traffic_disabled=false
aws_security_group.default: Refreshing state... [id=sg-0b7ce8ca55451342e]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.default will be updated in-place
  ~ resource "aws_security_group" "default" {
      ~ egress                 = [
          + {
              + cidr_blocks      = [
                  + "10.0.0.0/8",
                ]
              + description      = ""
              + from_port        = 0
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "-1"
              + security_groups  = []
              + self             = false
              + to_port          = 0
            },
        ]
        id                     = "sg-0b7ce8ca55451342e"
      ~ ingress                = [
          + {
              + cidr_blocks      = [
                  + "0.0.0.0/0",
                ]
              + description      = ""
              + from_port        = 443
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 443
            },
        ]
        name                   = "example-sg"
        tags                   = {
            "Name" = "github-issue-example"
        }
        # (6 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_security_group.default: Modifying... [id=sg-0b7ce8ca55451342e]
aws_security_group.default: Modifications complete after 1s [id=sg-0b7ce8ca55451342e]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
  1. Remove rules: traffic_disabled = true
  • No change detected, rules are not removed
- Terraform output
$ terraform apply -lock=false -var traffic_disabled=true
aws_security_group.default: Refreshing state... [id=sg-0b7ce8ca55451342e]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
  1. Destroy security group, note that rules are still in place
- Terraform output
$ terraform destroy -lock=false -var traffic_disabled=true
aws_security_group.default: Refreshing state... [id=sg-0b7ce8ca55451342e]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_security_group.default will be destroyed
  - resource "aws_security_group" "default" {
      - arn                    = "arn:aws:ec2:us-east-2:REDACTED:security-group/sg-0b7ce8ca55451342e" -> null
      - description            = "Managed by Terraform" -> null
      - egress                 = [
          - {
              - cidr_blocks      = [
                  - "10.0.0.0/8",
                ]
              - description      = ""
              - from_port        = 0
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "-1"
              - security_groups  = []
              - self             = false
              - to_port          = 0
            },
        ] -> null
      - id                     = "sg-0b7ce8ca55451342e" -> null
      - ingress                = [
          - {
              - cidr_blocks      = [
                  - "0.0.0.0/0",
                ]
              - description      = ""
              - from_port        = 443
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = []
              - self             = false
              - to_port          = 443
            },
        ] -> null
      - name                   = "example-sg" -> null
      - owner_id               = "REDACTED" -> null
      - revoke_rules_on_delete = false -> null
      - tags                   = {
          - "Name" = "github-issue-example"
        } -> null
      - tags_all               = {
          - "Name" = "github-issue-example"
        } -> null
      - vpc_id                 = "vpc-05d0373b3df8bde3b" -> null
    }

Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_security_group.default: Destroying... [id=sg-0b7ce8ca55451342e]
aws_security_group.default: Destruction complete after 0s

Destroy complete! Resources: 1 destroyed.

References

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

commented

Please keep open

This functionality has been released in v5.8.0 of the Terraform AWS Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.