Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/aws: aws_security_group not properly re-applying #457

Closed
pmoust opened this issue Oct 19, 2014 · 19 comments
Closed

provider/aws: aws_security_group not properly re-applying #457

pmoust opened this issue Oct 19, 2014 · 19 comments
Labels
bug provider/aws waiting-response An issue/pull request is waiting for a response from the community

Comments

@pmoust
Copy link
Contributor

pmoust commented Oct 19, 2014

When re-applying aws_security_group blocks with multiple ingress sections Terraform tries to assign '' and then apply the configuration. I think it has to do with the ordering fix some commits ago, not sure, did not have time to check the code.

To reproduce apply twice: https://github.com/pmoust/terraform-issues/tree/security-group-ordering

First pass will be fine, while subsequent produces the following:

⮀ ~/pph/pph-iac/terraform-issues ⮀ ⭠ security-group-ordering ● ⮀ terraform apply
aws_vpc.vpc: Refreshing state... (ID: vpc-42d05027)
aws_security_group.bar: Refreshing state... (ID: sg-485c5d2d)
aws_security_group.bar: Modifying...
  ingress.#:               "2" => "5"
  ingress.0.cidr_blocks.0: "1.1.1.2/32" => "1.1.1.1/32"
  ingress.0.self:          "0" => ""
  ingress.0.to_port:       "23" => "22"
  ingress.1.cidr_blocks.0: "1.1.1.3/32" => "1.1.1.5/32"
  ingress.1.self:          "0" => ""
  ingress.1.to_port:       "24" => "22"
  ingress.2.cidr_blocks.#: "0" => "1"
  ingress.2.cidr_blocks.0: "" => "1.1.1.4/32"
  ingress.2.from_port:     "" => "22"
  ingress.2.protocol:      "" => "tcp"
  ingress.2.to_port:       "" => "22"
  ingress.3.cidr_blocks.#: "0" => "1"
  ingress.3.cidr_blocks.0: "" => "1.1.1.2/32"
  ingress.3.from_port:     "" => "22"
  ingress.3.protocol:      "" => "tcp"
  ingress.3.to_port:       "" => "23"
  ingress.4.cidr_blocks.#: "0" => "1"
  ingress.4.cidr_blocks.0: "" => "1.1.1.3/32"
  ingress.4.from_port:     "" => "22"
  ingress.4.protocol:      "" => "tcp"
  ingress.4.to_port:       "" => "24"
aws_security_group.bar: Error: Error authorizing security group ingress rules: Invalid value '' for IP protocol. No protocol value given. (InvalidParameterValue)
Error applying plan:

1 error(s) occurred:

* Error authorizing security group ingress rules: Invalid value '' for IP protocol. No protocol value given. (InvalidParameterValue)

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
@mitchellh
Copy link
Contributor

Hm, I've recently seen this too. I'm still trying to track down how this happens.

@wilb
Copy link

wilb commented Oct 20, 2014

Also seen this. Manually clearing out all of the rules for the security group in the AWS console and re-applying through terraform appears to get things back into a consistent state.

@pmoust
Copy link
Contributor Author

pmoust commented Oct 20, 2014

Perhaps we should prioritise this as it is blocking. I 'll have some time on Wednesday to give it a go, however I would be grateful if someone from Hashicorp or terraform community attacks it faster.
It is right now very dangerous to reapply configurations.

@wilb
Copy link

wilb commented Oct 20, 2014

For reference it happens pretty much every time I want to add an ingress rule to an existing security group within my VPC. Every time it can be fixed by deleting all rules associated with the security group manually, but this won't be ideal in a production environment.

@wilb
Copy link

wilb commented Oct 21, 2014

Further to this I've noticed the situation is sometimes fixed by just doing another "terraform apply". I have a hunch that this is more likely to work if the operation you're trying to do will ultimately end up in the total number of rules being less than it was when you started the operations, but haven't tested that in any detail.

@mitchellh
Copy link
Contributor

Are you still seeing this with master? Can anyone give me pointers on reproducing? A security group config would be helpful here.

@mitchellh mitchellh added the waiting-response An issue/pull request is waiting for a response from the community label Oct 21, 2014
@wilb
Copy link

wilb commented Oct 21, 2014

I'm using master from a few days ago, I'll rebuild from fresh now and test over the course of the day. Pretty much any security group modification would do it for me - add an extra ingress rule to an already defined security group and I'll get the error. Next time I encounter it I'll the details to this ticket.

@wilb
Copy link

wilb commented Oct 21, 2014

Actually, I've recreated the change I made earlier today which definitely generated an error (but was fixed by running terraform apply again):

  resource "aws_security_group" "test-servers" {
    name = "test-servers"
      vpc_id = "${aws_vpc.test.id}"
      description = "Test servers"
      ingress {
          from_port = 22
          to_port = 22
          protocol = "tcp"
          cidr_blocks = ["1.2.3.4/32","3.4.5.6/32", "5.6.7.8/32" ]
      }
      ingress {
          from_port = 80
          to_port = 80
          protocol = "tcp"
          cidr_blocks = ["1.2.3.4/32","3.4.5.6/32", "5.6.7.8/32" ]
      }
      ingress {
          from_port = 443
          to_port = 443
          protocol = "tcp"
          cidr_blocks = ["1.2.3.4/32","3.4.5.6/32", "5.6.7.8/32" ]
      }
 }

Became

  resource "aws_security_group" "test-servers" {
    name = "test-servers"
      vpc_id = "${aws_vpc.test.id}"
      description = "Test servers"
      ingress {
          from_port = 22
          to_port = 22
          protocol = "tcp"
          cidr_blocks = ["1.2.3.4/32","3.4.5.6/32", "5.6.7.8/32", "9.9.9.9/32" ]
      }
 }

@wilb
Copy link

wilb commented Oct 21, 2014

This security group is causing me repeated problems:

resource "aws_security_group" "nat" {
    name = "nat instance"
    description = "Allow all TCP traffic from app tier"
    vpc_id = "${aws_vpc.test.id}"
    ingress {
        protocol = "icmp"
        from_port = -1
        to_port = -1
        security_groups = [ "${aws_security_group.test-app-servers.id}", "${aws_security_group.test-search-servers.id}", "${aws_security_group.test-proc-servers.id}" ]
    }
    ingress {
        protocol = "tcp"
        from_port = 25
        to_port = 25
        security_groups = [ "${aws_security_group.test-app-servers.id}", "${aws_security_group.test-search-servers.id}", "${aws_security_group.test-proc-servers.id}" ]
    }
    ingress {
        protocol = "tcp"
        from_port = 80
        to_port = 80
        security_groups = [ "${aws_security_group.test-app-servers.id}", "${aws_security_group.test-search-servers.id}", "${aws_security_group.test-proc-servers.id}" ]
    }
    ingress {
        protocol = "tcp"
        from_port = 443
        to_port = 443
        security_groups = [ "${aws_security_group.test-app-servers.id}", "${aws_security_group.test-search-servers.id}", "${aws_security_group.test-proc-servers.id}" ]
    }
}

Each time I run "terraform apply" it switches between being a successful run and a failing one. From looking at the output of the run, it looks like Terraform is trying to rearrange the order which the rules are going to be applied and mixing up ICMP ones with TCP ones.

 aws_security_group.nat: Modifying...                                                                                                                                                                                                 [26/1925]
  ingress.#:                    "12" => "4"
  ingress.0.from_port:          "-1" => "25"
  ingress.0.protocol:           "icmp" => "tcp"
  ingress.0.security_groups.#:  "1" => "3"
  ingress.0.security_groups.0:  "sg-09fdxxxx" => "sg-0cfdxxxx"
  ingress.0.security_groups.1:  "" => "sg-09fdxxxx"
  ingress.0.security_groups.2:  "" => "sg-0efdxxxx"
  ingress.0.self:               "0" => ""
  ingress.0.to_port:            "-1" => "25"
  ingress.1.from_port:          "-1" => "80"
  ingress.1.protocol:           "icmp" => "tcp"
  ingress.1.security_groups.#:  "1" => "3"
  ingress.1.security_groups.0:  "sg-0efdxxxx" => "sg-0cfdxxxx"
  ingress.1.security_groups.1:  "" => "sg-09fdxxxx"
  ingress.1.security_groups.2:  "" => "sg-0efdxxxx"
  ingress.1.self:               "0" => ""
  ingress.1.to_port:            "-1" => "80"
  ingress.10.from_port:         "80" => ""
  ingress.10.protocol:          "tcp" => ""
  ingress.10.security_groups.#: "1" => "0"
  ingress.10.security_groups.0: "sg-09fdxxxx" => ""
  ingress.10.self:              "0" => ""
  ingress.10.to_port:           "80" => ""
  ingress.11.from_port:         "25" => ""
  ingress.11.protocol:          "tcp" => ""
  ingress.11.security_groups.#: "1" => "0"
  ingress.11.security_groups.0: "sg-0cfdxxxx" => ""
  ingress.11.self:              "0" => ""
  ingress.11.to_port:           "25" => ""
  ingress.2.from_port:          "25" => "443"
  ingress.2.security_groups.#:  "1" => "3"
  ingress.2.security_groups.0:  "sg-0efdxxxx" => "sg-0cfdxxxx"
  ingress.2.security_groups.1:  "" => "sg-09fdxxxx"
  ingress.2.security_groups.2:  "" => "sg-0efdxxxx"
  ingress.2.self:               "0" => ""
  ingress.2.to_port:            "25" => "443"
  ingress.3.from_port:          "443" => "-1"
  ingress.3.protocol:           "tcp" => "icmp"
  ingress.3.security_groups.#:  "1" => "3"
  ingress.3.security_groups.0:  "sg-09fdxxxx" => "sg-0cfdxxxx"
  ingress.3.security_groups.1:  "" => "sg-09fdxxxx"
  ingress.3.security_groups.2:  "" => "sg-0efdxxxx"
  ingress.3.self:               "0" => ""
  ingress.3.to_port:            "443" => "-1"
  ingress.4.from_port:          "443" => ""
  ingress.4.protocol:           "tcp" => ""
  ingress.4.security_groups.#:  "1" => "0"
  ingress.4.security_groups.0:  "sg-0efdxxxx" => ""
  ingress.4.self:               "0" => ""
  ingress.4.to_port:            "443" => ""
  ingress.5.from_port:          "25" => ""
  ingress.5.protocol:           "tcp" => ""
  ingress.5.security_groups.#:  "1" => "0"
  ingress.5.security_groups.0:  "sg-09fdxxxx" => ""
  ingress.5.self:               "0" => ""
  ingress.5.to_port:            "25" => ""
  ingress.6.from_port:          "80" => ""
  ingress.6.protocol:           "tcp" => ""
  ingress.6.security_groups.#:  "1" => "0"
  ingress.6.security_groups.0:  "sg-0cfdxxxx" => ""
  ingress.6.self:               "0" => ""
  ingress.6.to_port:            "80" => ""
  ingress.7.from_port:          "-1" => ""
  ingress.7.protocol:           "icmp" => ""
  ingress.7.security_groups.#:  "1" => "0"
  ingress.7.security_groups.0:  "sg-0cfdxxxx" => ""
  ingress.7.self:               "0" => ""
  ingress.7.to_port:            "-1" => ""
  ingress.8.from_port:          "80" => ""
  ingress.8.protocol:           "tcp" => ""
  ingress.8.security_groups.#:  "1" => "0"
  ingress.8.security_groups.0:  "sg-0efdxxxx" => ""
  ingress.8.self:               "0" => ""
  ingress.8.to_port:            "80" => ""
  ingress.9.from_port:          "443" => ""
  ingress.9.protocol:           "tcp" => ""
  ingress.9.security_groups.#:  "1" => "0"
  ingress.9.security_groups.0:  "sg-0cfdxxxx" => ""
  ingress.9.self:               "0" => ""
  ingress.9.to_port:            "443" => ""
aws_security_group.nat: Error: Error authorizing security group ingress rules: Invalid value '' for IP protocol. No protocol value given. (InvalidParameterValue)
Error applying plan:
1 error(s) occurred:
* Error authorizing security group ingress rules: Invalid value '' for IP protocol. No protocol value given. (InvalidParameterValue)
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

The result of this is that my nat security group has no ingress rules. I then run "terraform apply" again and all of the rules get reapplied correctly.

@pmoust
Copy link
Contributor Author

pmoust commented Oct 21, 2014

Yep, here is the config from the original issue report as well https://github.com/pmoust/terraform-issues/blob/security-group-ordering/test.tf

@mitchellh
Copy link
Contributor

@wilb I got a repro. Thanks.

mitchellh added a commit that referenced this issue Oct 21, 2014
Prior to this, the diff only contained changed set elements. The issue
with this is that `getSet`, the internal function that reads a set from
the ResourceData, expects that each level (state, config, diff, etc.)
has the _full set_ information. This change was done to fix merging
issues.

Because of this, we need to make sure the full set is visible in the
diff.
@mitchellh
Copy link
Contributor

Fixed. All sorts of issues culminated to this. Thanks for the repro!

@wilb
Copy link

wilb commented Oct 21, 2014

👍

@while1eq1
Copy link

@mitchellh This is still happening even from master. I just compiled moments ago. See the below code to replicate.

resource "aws_security_group" "global-test" {
  name = "global-test"
  description = "global rule"

  ingress {
    from_port = 0
    to_port = 65535
    protocol = "tcp"
    cidr_blocks = ["11.22.33.44/32", "22.33.44.55/32", "33.44.55.66/32"]
  }

  ingress {
    from_port = 0
    to_port = 65535
    protocol = "tcp"
    cidr_blocks = ["44.55.66.77/32"]
  }

  ingress {
    from_port = 0
    to_port = 65535
    protocol = "tcp"
    cidr_blocks = ["55.66.77.88/32", "66.77.88.99/32"]
  }

  tags {
    Name = "global"
  }
}

@while1eq1
Copy link

after an apply a $ terraform plan now yields

~ aws_security_group.global-test
    ingress.#:                   "1" => "3"
    ingress.0.cidr_blocks.#:     "6" => "3"
    ingress.0.cidr_blocks.0:     "11.22.33.44/32" => "11.22.33.44/32"
    ingress.0.cidr_blocks.1:     "22.33.44.55/32" => "22.33.44.55/32"
    ingress.0.cidr_blocks.2:     "33.44.55.66/32" => "33.44.55.66/32"
    ingress.0.cidr_blocks.3:     "44.55.66.77/32" => ""
    ingress.0.cidr_blocks.4:     "55.66.77.88/32" => ""
    ingress.0.cidr_blocks.5:     "66.77.88.99/32" => ""
    ingress.0.from_port:         "0" => "0"
    ingress.0.protocol:          "tcp" => "tcp"
    ingress.0.security_groups.#: "0" => "0"
    ingress.0.self:              "0" => "0"
    ingress.0.to_port:           "65535" => "65535"
    ingress.1.cidr_blocks.#:     "0" => "1"
    ingress.1.cidr_blocks.0:     "" => "44.55.66.77/32"
    ingress.1.from_port:         "" => "0"
    ingress.1.protocol:          "" => "tcp"
    ingress.1.security_groups.#: "0" => "0"
    ingress.1.self:              "" => "0"
    ingress.1.to_port:           "" => "65535"
    ingress.2.cidr_blocks.#:     "0" => "2"
    ingress.2.cidr_blocks.0:     "" => "55.66.77.88/32"
    ingress.2.cidr_blocks.1:     "" => "66.77.88.99/32"
    ingress.2.from_port:         "" => "0"
    ingress.2.protocol:          "" => "tcp"
    ingress.2.security_groups.#: "0" => "0"
    ingress.2.self:              "" => "0"
    ingress.2.to_port:           "" => "65535"

@mitchellh
Copy link
Contributor

@while1eq1 Ah, yes, this is a different issue we're aware of. This is due to API weirdness from Amazon. You can solve this by making sure all your from/to ports are consolidated into a single ingress block.

@while1eq1
Copy link

@mitchellh I understand that you can compress this down to one igress block and the error goes away however I would like to be able to use several ingress blocks. Is this something thats being worked on or something I an put in a feature request for?

@mitchellh
Copy link
Contributor

It isn't something being worked on yet, if you can open an issue that'd help.

@while1eq1
Copy link

submitted issue: #507

@ghost ghost locked and limited conversation to collaborators May 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug provider/aws waiting-response An issue/pull request is waiting for a response from the community
Projects
None yet
Development

No branches or pull requests

4 participants