Skip to content

Commit

Permalink
Merge pull request #16884 from hashicorp/b-networkfirewall-rule-group…
Browse files Browse the repository at this point in the history
…-remove-forcenew-from-stateful-rule-fields

resource/networkfirewall_rule_group: remove ForceNew attribute from stateful_rule field and its children
  • Loading branch information
anGie44 committed Jan 11, 2021
2 parents 40ef37d + 8123e8e commit 339584d
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 15 deletions.
22 changes: 7 additions & 15 deletions aws/resource_aws_networkfirewall_rule_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,26 +170,22 @@ func resourceAwsNetworkFirewallRuleGroup() *schema.Resource {
"stateful_rule": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"action": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(networkfirewall.StatefulAction_Values(), false),
},
"header": {
Type: schema.TypeList,
Required: true,
MaxItems: 1,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"destination": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.Any(
validateIpv4CIDRNetworkAddress,
validation.StringInSlice([]string{networkfirewall.StatefulRuleDirectionAny}, false),
Expand All @@ -198,24 +194,20 @@ func resourceAwsNetworkFirewallRuleGroup() *schema.Resource {
"destination_port": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"direction": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(networkfirewall.StatefulRuleDirection_Values(), false),
},
"protocol": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(networkfirewall.StatefulRuleProtocol_Values(), false),
},
"source": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.Any(
validateIpv4CIDRNetworkAddress,
validation.StringInSlice([]string{networkfirewall.StatefulRuleDirectionAny}, false),
Expand All @@ -224,7 +216,6 @@ func resourceAwsNetworkFirewallRuleGroup() *schema.Resource {
"source_port": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
},
Expand Down Expand Up @@ -498,19 +489,20 @@ func resourceAwsNetworkFirewallRuleGroupUpdate(ctx context.Context, d *schema.Re
log.Printf("[DEBUG] Updating NetworkFirewall Rule Group %s", arn)

if d.HasChanges("description", "rule_group", "rules", "type") {
// Provide updated object with the currently configured fields
input := &networkfirewall.UpdateRuleGroupInput{
RuleGroupArn: aws.String(arn),
Type: aws.String(d.Get("type").(string)),
UpdateToken: aws.String(d.Get("update_token").(string)),
}
if d.HasChange("description") {
input.Description = aws.String(d.Get("description").(string))
if v, ok := d.GetOk("description"); ok {
input.Description = aws.String(v.(string))
}
if d.HasChange("rule_group") {
input.RuleGroup = expandNetworkFirewallRuleGroup(d.Get("rule_group").([]interface{}))
if v, ok := d.GetOk("rule_group"); ok {
input.RuleGroup = expandNetworkFirewallRuleGroup(v.([]interface{}))
}
if d.HasChange("rules") {
input.Rules = aws.String(d.Get("rules").(string))
if v, ok := d.GetOk("rules"); ok {
input.Rules = aws.String(v.(string))
}

_, err := conn.UpdateRuleGroupWithContext(ctx, input)
Expand Down
217 changes: 217 additions & 0 deletions aws/resource_aws_networkfirewall_rule_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ func TestAccAwsNetworkFirewallRuleGroup_basic_statefulRule(t *testing.T) {
"header.0.source_port": "53",
"rule_option.#": "1",
}),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule_group.0.rules_source.0.stateful_rule.*.rule_option.*", map[string]string{
"keyword": "sid:1",
}),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
},
Expand Down Expand Up @@ -401,6 +404,8 @@ func TestAccAwsNetworkFirewallRuleGroup_rulesSourceAndRuleVariables(t *testing.T
})
}

// TestAccAwsNetworkFirewallRuleGroup_updateStatefulRule validates
// in-place updates to a single stateful_rule configuration block
func TestAccAwsNetworkFirewallRuleGroup_updateStatefulRule(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_networkfirewall_rule_group.test"
Expand Down Expand Up @@ -443,6 +448,147 @@ func TestAccAwsNetworkFirewallRuleGroup_updateStatefulRule(t *testing.T) {
})
}

// TestAccAwsNetworkFirewallRuleGroup_updateMultipleStatefulRules validates
// in-place updates to stateful_rule configuration blocks
// Reference: https://github.com/hashicorp/terraform-provider-aws/issues/16868
func TestAccAwsNetworkFirewallRuleGroup_updateMultipleStatefulRules(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_networkfirewall_rule_group.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAwsNetworkFirewall(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsNetworkFirewallRuleGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccNetworkFirewallRuleGroup_basic_statefulRule(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsNetworkFirewallRuleGroupExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "rule_group.0.rules_source.0.stateful_rule.#", "1"),
),
},
{
Config: testAccNetworkFirewallRuleGroup_multipleStatefulRules(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsNetworkFirewallRuleGroupExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "rule_group.0.rules_source.0.stateful_rule.#", "2"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule_group.0.rules_source.0.stateful_rule.*", map[string]string{
"action": networkfirewall.StatefulActionPass,
"header.#": "1",
"header.0.destination": "124.1.1.24/32",
"header.0.destination_port": "53",
"header.0.direction": networkfirewall.StatefulRuleDirectionAny,
"header.0.protocol": networkfirewall.StatefulRuleProtocolTcp,
"header.0.source": "1.2.3.4/32",
"header.0.source_port": "53",
"rule_option.#": "1",
}),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule_group.0.rules_source.0.stateful_rule.*", map[string]string{
"action": networkfirewall.StatefulActionAlert,
"header.#": "1",
"header.0.destination": networkfirewall.StatefulRuleDirectionAny,
"header.0.destination_port": networkfirewall.StatefulRuleDirectionAny,
"header.0.direction": networkfirewall.StatefulRuleDirectionAny,
"header.0.protocol": networkfirewall.StatefulRuleProtocolIp,
"header.0.source": networkfirewall.StatefulRuleDirectionAny,
"header.0.source_port": networkfirewall.StatefulRuleDirectionAny,
"rule_option.#": "1",
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccNetworkFirewallRuleGroup_updateStatefulRule(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsNetworkFirewallRuleGroupExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "rule_group.0.rules_source.0.stateful_rule.#", "1"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule_group.0.rules_source.0.stateful_rule.*", map[string]string{
"action": networkfirewall.StatefulActionDrop,
"header.#": "1",
"header.0.destination": "1.2.3.4/32",
"header.0.destination_port": "1001",
"header.0.direction": networkfirewall.StatefulRuleDirectionForward,
"header.0.protocol": networkfirewall.StatefulRuleProtocolIp,
"header.0.source": "124.1.1.24/32",
"header.0.source_port": "1001",
"rule_option.#": "1",
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

// TestAccAwsNetworkFirewallRuleGroup_statefulRule_action validates in-place
// updates to the "action" argument within 1 stateful_rule configuration block
// Reference: https://github.com/hashicorp/terraform-provider-aws/issues/16868
func TestAccAwsNetworkFirewallRuleGroup_statefulRule_action(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_networkfirewall_rule_group.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAwsNetworkFirewall(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsNetworkFirewallRuleGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccNetworkFirewallRuleGroup_statefulRule_action(rName, networkfirewall.StatefulActionAlert),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsNetworkFirewallRuleGroupExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "rule_group.0.rules_source.0.stateful_rule.#", "1"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule_group.0.rules_source.0.stateful_rule.*", map[string]string{
"action": networkfirewall.StatefulActionAlert,
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccNetworkFirewallRuleGroup_statefulRule_action(rName, networkfirewall.StatefulActionPass),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsNetworkFirewallRuleGroupExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "rule_group.0.rules_source.0.stateful_rule.#", "1"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule_group.0.rules_source.0.stateful_rule.*", map[string]string{
"action": networkfirewall.StatefulActionPass,
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccNetworkFirewallRuleGroup_statefulRule_action(rName, networkfirewall.StatefulActionDrop),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsNetworkFirewallRuleGroupExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "rule_group.0.rules_source.0.stateful_rule.#", "1"),
resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule_group.0.rules_source.0.stateful_rule.*", map[string]string{
"action": networkfirewall.StatefulActionDrop,
}),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

// Reference: https://github.com/hashicorp/terraform-provider-aws/issues/16470
func TestAccAwsNetworkFirewallRuleGroup_statefulRule_header(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
Expand Down Expand Up @@ -794,6 +940,35 @@ resource "aws_networkfirewall_rule_group" "test" {
`, rName)
}

func testAccNetworkFirewallRuleGroup_statefulRule_action(rName, action string) string {
return fmt.Sprintf(`
resource "aws_networkfirewall_rule_group" "test" {
capacity = 100
name = %[1]q
description = %[1]q
type = "STATEFUL"
rule_group {
rules_source {
stateful_rule {
action = %q
header {
destination = "124.1.1.24/32"
destination_port = 53
direction = "ANY"
protocol = "TCP"
source = "1.2.3.4/32"
source_port = 53
}
rule_option {
keyword = "sid:1"
}
}
}
}
}
`, rName, action)
}

func testAccNetworkFirewallRuleGroup_statefulRule_header(rName, dstPort, srcPort string) string {
return fmt.Sprintf(`
resource "aws_networkfirewall_rule_group" "test" {
Expand Down Expand Up @@ -841,10 +1016,52 @@ resource "aws_networkfirewall_rule_group" "test" {
source = "124.1.1.24/32"
source_port = 1001
}
rule_option {
keyword = "sid:1;rev:2"
}
}
}
}
}
`, rName)
}

func testAccNetworkFirewallRuleGroup_multipleStatefulRules(rName string) string {
return fmt.Sprintf(`
resource "aws_networkfirewall_rule_group" "test" {
capacity = 100
name = %[1]q
type = "STATEFUL"
rule_group {
rules_source {
stateful_rule {
action = "PASS"
header {
destination = "124.1.1.24/32"
destination_port = 53
direction = "ANY"
protocol = "TCP"
source = "1.2.3.4/32"
source_port = 53
}
rule_option {
keyword = "sid:1"
}
}
stateful_rule {
action = "ALERT"
header {
destination = "ANY"
destination_port = "ANY"
direction = "ANY"
protocol = "IP"
source = "ANY"
source_port = "ANY"
}
rule_option {
keyword = "sid:2"
}
}
}
}
}
Expand Down

0 comments on commit 339584d

Please sign in to comment.