diff --git a/builtin/providers/aws/network_acl_entry.go b/builtin/providers/aws/network_acl_entry.go index 0504d599e..9c93544c1 100644 --- a/builtin/providers/aws/network_acl_entry.go +++ b/builtin/providers/aws/network_acl_entry.go @@ -66,3 +66,19 @@ func protocolIntegers() map[string]int { } return protocolIntegers } + +// expectedPortPair stores a pair of ports we expect to see together. +type expectedPortPair struct { + to_port int64 + from_port int64 +} + +// validatePorts ensures the ports and protocol match expected +// values. +func validatePorts(to int64, from int64, expected expectedPortPair) bool { + if to != expected.to_port || from != expected.from_port { + return false + } + + return true +} diff --git a/builtin/providers/aws/network_acl_entry_test.go b/builtin/providers/aws/network_acl_entry_test.go index 3c38613f3..7ca66dcd8 100644 --- a/builtin/providers/aws/network_acl_entry_test.go +++ b/builtin/providers/aws/network_acl_entry_test.go @@ -135,3 +135,20 @@ func Test_flattenNetworkACLEntry(t *testing.T) { } } + +func Test_validatePorts(t *testing.T) { + for _, ts := range []struct { + to int64 + from int64 + expected *expectedPortPair + wanted bool + }{ + {0, 0, &expectedPortPair{0, 0}, true}, + {0, 1, &expectedPortPair{0, 0}, false}, + } { + got := validatePorts(ts.to, ts.from, *ts.expected) + if got != ts.wanted { + t.Fatalf("Got: %t; Expected: %t\n", got, ts.wanted) + } + } +} diff --git a/builtin/providers/aws/resource_aws_network_acl.go b/builtin/providers/aws/resource_aws_network_acl.go index 4635bec3f..af91f9cce 100644 --- a/builtin/providers/aws/resource_aws_network_acl.go +++ b/builtin/providers/aws/resource_aws_network_acl.go @@ -266,6 +266,24 @@ func updateNetworkAclEntries(d *schema.ResourceData, entryType string, conn *ec2 return err } for _, add := range toBeCreated { + // Protocol -1 rules don't store ports in AWS. Thus, they'll always + // hash differently when being read out of the API. Force the user + // to set from_port and to_port to 0 for these rules, to keep the + // hashing consistent. + if *add.Protocol == "-1" { + to := *add.PortRange.To + from := *add.PortRange.From + expected := &expectedPortPair{ + to_port: 0, + from_port: 0, + } + if ok := validatePorts(to, from, *expected); !ok { + return fmt.Errorf( + "to_port (%d) and from_port (%d) must both be 0 to use the the 'all' \"-1\" protocol!", + to, from) + } + } + // Add new Acl entry _, err := conn.CreateNetworkACLEntry(&ec2.CreateNetworkACLEntryInput{ NetworkACLID: aws.String(d.Id()),