hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.74k stars 9.1k forks source link

aws_security_group gets updated in place with no changes when if cidr_blocks = [] #20757

Open dreinhardt89 opened 3 years ago

dreinhardt89 commented 3 years ago

Community Note

Terraform CLI and Terraform AWS Provider Version

Terraform v0.12.31 provider.aws 2.28.1

Affected Resource(s)

Terraform Configuration Files

Please include all Terraform configurations required to reproduce the bug. Bug reports without a functional reproduction may be closed without investigation.

resource "aws_security_group" "sg_access" {
  name        = "sg_access"
  description = "Allow egress"
  vpc_id      = module.eks_vpc.vpc_id
  tags        = local.tags

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = var.eks_vpc_database_subnets #for some of our workflows these are empty []
  }
}

Expected Behavior

aws_security_group should not be updated if no changes are made.

Actual Behavior

Terraform always updates aws_security_group in place adding the engress block.

Steps to Reproduce

Create an aws_security_group with the following cidr_block (cidr_blocks = []) in egress.

breathingdust commented 3 years ago

Hi @dreinhardt-terminus 👋 It looks like you are using a very old version of the provider:2.28.1. At this time we are not investigating or back-porting fixes to the 2.* series of providers. Can you update to the latest version and retest?

G-Rath commented 3 years ago

@breathingdust I think I'm seeing this issue in v3 with security_groups, which is having an empty array causes Terraform to always want to apply that change:

# module.autoscaling.aws_security_group.app_server will be updated in-place
  ~ resource "aws_security_group" "app_server" {
        id                     = "sg-123"
      ~ ingress                = [
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 22
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 22
            },
          - {
              - cidr_blocks      = []
              - description      = ""
              - from_port        = 80
              - ipv6_cidr_blocks = []
              - prefix_list_ids  = []
              - protocol         = "tcp"
              - security_groups  = [
                  - "sg-456",
                ]
              - self             = false
              - to_port          = 80
            },
          + {
              + cidr_blocks      = []
              + description      = null
              + from_port        = 80
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = [
                  + "sg-456",
                ]
              + self             = false
              + to_port          = 80
            },
        ]
        name                   = "ProductionAppServer"
        # (7 unchanged attributes hidden)
    }

This with this config:

resource "aws_security_group" "app_server" {
  name = "${var.name_prefix_pascal_case}AppServer"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"

    security_groups = var.http_sg_ids
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"

    security_groups = var.ssh_sg_ids
  }
}

I'm using 3.52.0 of the aws provider, and terraform 1.0.3.

oliveirafilipe commented 3 years ago

Hi @G-Rath, I'm facing the same behavior. But I think the update is caused by the undefined description parameter, as you can see there is a mismatch between AWS and Terraform, one is trying to define description = null and the other description = "".

The problem stopped when I defined a content for that description, which is not a bad idea, but I think that there is a bug evolving undefined description for a SG entry.

G-Rath commented 3 years ago

@oliveirafilipe that's not what's happening here - while there does appear to be a difference in the value of the description attribute in the above plan, it isn't an issue.

The issue reported here (which I've been able to reproduce) is because no security group rules are created, which is contrary to what Terraform expects should happen.

I actually ran into this again by mistakenly not setting security_groups or cidr_blocks:

resource "aws_security_group" "load_balancer" {
  name = "MyLoadBalancer"

  ingress {
    protocol    = "tcp"
    from_port   = 80
    to_port     = 80

    description = "HTTP Access"
  }

  ingress {
    protocol    = "tcp"
    from_port   = 443
    to_port     = 443

    description = "HTTPS Access"
  }

  # Allow all outgoing traffic
  egress {
    protocol  = "-1" # "-1" is a magic value which means "ALL"
    from_port = 0
    to_port   = 0

    cidr_blocks = ["0.0.0.0/0"] # tfsec:ignore:AWS009
  }
}

The resulting security group:

image

github-actions[bot] commented 1 year ago

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!

G-Rath commented 1 year ago

I've confirmed this still happened in v5.14.0 of the provider, using Terraform v1.5.1