Skip to content

Commit f55da64

Browse files
fix: string based ordering for google_compute_region_security_policy causes recreate after apply (#14093)
1 parent fe5130a commit f55da64

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

mmv1/products/compute/RegionSecurityPolicy.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ async:
3939
result:
4040
resource_inside_response: false
4141
custom_code:
42+
constants: 'templates/terraform/constants/region_security_policy.go.tmpl'
4243
sweeper:
4344
url_substitutions:
4445
- region: "us-south1"
@@ -188,6 +189,7 @@ properties:
188189
description: |
189190
The set of rules that belong to this policy. There must always be a default rule (rule with priority 2147483647 and match "*"). If no rules are provided when creating a security policy, a default rule with action "allow" will be added.
190191
default_from_api: true
192+
diff_suppress_func: 'resourceComputeRegionSecurityPolicySpecRulesDiffSuppress'
191193
item_type:
192194
type: NestedObject
193195
properties:
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{{- if ne $.Compiler "terraformgoogleconversion-codegen" }}
2+
func resourceComputeRegionSecurityPolicySpecRulesDiffSuppress(k, o, n string, d *schema.ResourceData) bool {
3+
oldCount, newCount := d.GetChange("rules.#")
4+
var count int
5+
// There could be duplicates - worth continuing even if the counts are unequal.
6+
if oldCount.(int) < newCount.(int) {
7+
count = newCount.(int)
8+
} else {
9+
count = oldCount.(int)
10+
}
11+
12+
old := make([]interface{}, 0, count)
13+
new := make([]interface{}, 0, count)
14+
for i := 0; i < count; i++ {
15+
o, n := d.GetChange(fmt.Sprintf("rules.%d", i))
16+
17+
if o != nil {
18+
old = append(old, o)
19+
}
20+
if n != nil {
21+
new = append(new, n)
22+
}
23+
}
24+
25+
oldSet := schema.NewSet(schema.HashResource(ResourceComputeRegionSecurityPolicy().Schema["rules"].Elem.(*schema.Resource)), old)
26+
newSet := schema.NewSet(schema.HashResource(ResourceComputeRegionSecurityPolicy().Schema["rules"].Elem.(*schema.Resource)), new)
27+
28+
return oldSet.Equal(newSet)
29+
}
30+
31+
{{- end }}

mmv1/third_party/terraform/services/compute/resource_compute_region_security_policy_test.go.tmpl

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,121 @@ func testAccComputeRegionSecurityPolicy_withMultipleEnforceOnKeyConfigs_update(c
722722
`, context)
723723
}
724724

725+
func TestAccComputeRegionSecurityPolicy_regionSecurityPolicyRuleOrderingWithMultipleRules(t *testing.T) {
726+
t.Parallel()
727+
728+
context := map[string]interface{}{
729+
"random_suffix": acctest.RandString(t, 10),
730+
}
731+
732+
acctest.VcrTest(t, resource.TestCase{
733+
PreCheck: func() { acctest.AccTestPreCheck(t) },
734+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
735+
CheckDestroy: testAccCheckComputeRegionSecurityPolicyDestroyProducer(t),
736+
Steps: []resource.TestStep{
737+
{
738+
Config: testAccComputeRegionSecurityPolicy_ruleOrderingWithMultipleRules_create(context),
739+
},
740+
{
741+
ResourceName: "google_compute_region_security_policy.policy",
742+
ImportState: true,
743+
ImportStateVerify: true,
744+
},
745+
{
746+
Config: testAccComputeRegionSecurityPolicy_ruleOrderingWithMultipleRules_update(context),
747+
},
748+
{
749+
ResourceName: "google_compute_region_security_policy.policy",
750+
ImportState: true,
751+
ImportStateVerify: true,
752+
},
753+
},
754+
})
755+
}
756+
757+
758+
func testAccComputeRegionSecurityPolicy_ruleOrderingWithMultipleRules_create(context map[string]interface{}) string {
759+
return acctest.Nprintf(`
760+
761+
resource "google_compute_region_security_policy" "policy" {
762+
name = "tf-test-ordering%{random_suffix}"
763+
description = "basic region security policy with multiple rules"
764+
type = "CLOUD_ARMOR"
765+
region = "us-central1"
766+
767+
rules {
768+
action = "deny"
769+
priority = "3000"
770+
match {
771+
expr {
772+
expression = "request.path.matches(\"/login.html\") && token.recaptcha_session.score < 0.2"
773+
}
774+
}
775+
}
776+
777+
rules {
778+
action = "deny"
779+
priority = "2147483647"
780+
match {
781+
versioned_expr = "SRC_IPS_V1"
782+
config {
783+
src_ip_ranges = ["*"]
784+
}
785+
}
786+
description = "default rule"
787+
}
788+
}
789+
790+
`, context)
791+
}
792+
793+
794+
func testAccComputeRegionSecurityPolicy_ruleOrderingWithMultipleRules_update(context map[string]interface{}) string {
795+
return acctest.Nprintf(`
796+
797+
resource "google_compute_region_security_policy" "policy" {
798+
name = "tf-test-ordering%{random_suffix}"
799+
description = "basic region security policy with multiple rules, updated"
800+
type = "CLOUD_ARMOR"
801+
region = "us-central1"
802+
803+
rules {
804+
action = "allow"
805+
priority = "4000"
806+
match {
807+
expr {
808+
expression = "request.path.matches(\"/login.html\") && token.recaptcha_session.score < 0.2"
809+
}
810+
}
811+
}
812+
813+
rules {
814+
action = "allow"
815+
priority = "5000"
816+
match {
817+
expr {
818+
expression = "request.path.matches(\"/404.html\") && token.recaptcha_session.score > 0.4"
819+
}
820+
}
821+
description = "new rule"
822+
}
823+
824+
rules {
825+
action = "deny"
826+
priority = "2147483647"
827+
match {
828+
versioned_expr = "SRC_IPS_V1"
829+
config {
830+
src_ip_ranges = ["*"]
831+
}
832+
}
833+
description = "default rule"
834+
}
835+
}
836+
`, context)
837+
}
838+
839+
725840
{{- if ne $.TargetVersionName "ga" }}
726841
func TestAccComputeRegionSecurityPolicy_regionSecurityPolicyWithRulesNetworkMatch(t *testing.T) {
727842
t.Parallel()

0 commit comments

Comments
 (0)