Skip to content

Commit 3ad110d

Browse files
authored
Merge pull request #40889 from rbreslow/f-name_prefix-for-wafv2-resources
Add name_prefix argument for WAFv2 resources
2 parents abb74c6 + 3544af4 commit 3ad110d

11 files changed

+382
-26
lines changed

.changelog/40889.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
```release-note:enhancement
2+
resource/aws_wafv2_ip_set: Add `name_prefix` argument and plan-time validation of `name`
3+
```
4+
5+
```release-note:enhancement
6+
resource/aws_wafv2_regex_pattern_set: Add `name_prefix` argument and plan-time validation of `name`
7+
```
8+
9+
```release-note:enhancement
10+
resource/aws_wafv2_web_acl: Add `name_prefix` argument
11+
```

internal/service/wafv2/ip_set.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ import (
1010
"strings"
1111
"time"
1212

13+
"github.com/YakDriver/regexache"
1314
"github.com/aws/aws-sdk-go-v2/aws"
1415
"github.com/aws/aws-sdk-go-v2/service/wafv2"
1516
awstypes "github.com/aws/aws-sdk-go-v2/service/wafv2/types"
1617
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
18+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
1719
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1820
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1921
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
2022
"github.com/hashicorp/terraform-provider-aws/internal/conns"
23+
"github.com/hashicorp/terraform-provider-aws/internal/create"
2124
"github.com/hashicorp/terraform-provider-aws/internal/enum"
2225
"github.com/hashicorp/terraform-provider-aws/internal/errs"
2326
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
@@ -104,10 +107,26 @@ func resourceIPSet() *schema.Resource {
104107
Computed: true,
105108
},
106109
names.AttrName: {
107-
Type: schema.TypeString,
108-
Required: true,
109-
ForceNew: true,
110-
ValidateFunc: validation.StringLenBetween(1, 128),
110+
Type: schema.TypeString,
111+
Optional: true,
112+
Computed: true,
113+
ForceNew: true,
114+
ConflictsWith: []string{names.AttrNamePrefix},
115+
ValidateFunc: validation.All(
116+
validation.StringLenBetween(1, 128),
117+
validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_-]+$`), "must contain only alphanumeric hyphen and underscore characters"),
118+
),
119+
},
120+
names.AttrNamePrefix: {
121+
Type: schema.TypeString,
122+
Optional: true,
123+
Computed: true,
124+
ForceNew: true,
125+
ConflictsWith: []string{names.AttrName},
126+
ValidateFunc: validation.All(
127+
validation.StringLenBetween(1, 128-id.UniqueIDSuffixLength),
128+
validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_-]+$`), "must contain only alphanumeric hyphen and underscore characters"),
129+
),
111130
},
112131
names.AttrScope: {
113132
Type: schema.TypeString,
@@ -126,7 +145,7 @@ func resourceIPSetCreate(ctx context.Context, d *schema.ResourceData, meta any)
126145
var diags diag.Diagnostics
127146
conn := meta.(*conns.AWSClient).WAFV2Client(ctx)
128147

129-
name := d.Get(names.AttrName).(string)
148+
name := create.Name(d.Get(names.AttrName).(string), d.Get(names.AttrNamePrefix).(string))
130149
input := &wafv2.CreateIPSetInput{
131150
Addresses: []string{},
132151
IPAddressVersion: awstypes.IPAddressVersion(d.Get("ip_address_version").(string)),
@@ -150,6 +169,7 @@ func resourceIPSetCreate(ctx context.Context, d *schema.ResourceData, meta any)
150169
}
151170

152171
d.SetId(aws.ToString(output.Summary.Id))
172+
d.Set(names.AttrName, name) // Required in Read.
153173

154174
return append(diags, resourceIPSetRead(ctx, d, meta)...)
155175
}
@@ -172,12 +192,12 @@ func resourceIPSetRead(ctx context.Context, d *schema.ResourceData, meta any) di
172192

173193
ipSet := output.IPSet
174194
d.Set("addresses", ipSet.Addresses)
175-
arn := aws.ToString(ipSet.ARN)
176-
d.Set(names.AttrARN, arn)
195+
d.Set(names.AttrARN, ipSet.ARN)
177196
d.Set(names.AttrDescription, ipSet.Description)
178197
d.Set("ip_address_version", ipSet.IPAddressVersion)
179198
d.Set("lock_token", output.LockToken)
180199
d.Set(names.AttrName, ipSet.Name)
200+
d.Set(names.AttrNamePrefix, create.NamePrefixFromName(aws.ToString(ipSet.Name)))
181201

182202
return diags
183203
}

internal/service/wafv2/ip_set_test.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/YakDriver/regexache"
1212
awstypes "github.com/aws/aws-sdk-go-v2/service/wafv2/types"
13+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
1314
sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest"
1415
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
1516
"github.com/hashicorp/terraform-plugin-testing/terraform"
@@ -38,6 +39,7 @@ func TestAccWAFV2IPSet_basic(t *testing.T) {
3839
testAccCheckIPSetExists(ctx, resourceName, &v),
3940
acctest.MatchResourceAttrRegionalARN(ctx, resourceName, names.AttrARN, "wafv2", regexache.MustCompile(`regional/ipset/.+$`)),
4041
resource.TestCheckResourceAttr(resourceName, names.AttrName, ipSetName),
42+
resource.TestCheckResourceAttr(resourceName, names.AttrNamePrefix, ""),
4143
resource.TestCheckResourceAttr(resourceName, names.AttrDescription, ipSetName),
4244
resource.TestCheckResourceAttr(resourceName, names.AttrScope, string(awstypes.ScopeRegional)),
4345
resource.TestCheckResourceAttr(resourceName, "ip_address_version", string(awstypes.IPAddressVersionIpv4)),
@@ -69,6 +71,64 @@ func TestAccWAFV2IPSet_basic(t *testing.T) {
6971
})
7072
}
7173

74+
func TestAccWAFV2IPSet_nameGenerated(t *testing.T) {
75+
ctx := acctest.Context(t)
76+
var v awstypes.IPSet
77+
resourceName := "aws_wafv2_ip_set.ip_set"
78+
79+
resource.ParallelTest(t, resource.TestCase{
80+
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckScopeRegional(ctx, t) },
81+
ErrorCheck: acctest.ErrorCheck(t, names.WAFV2ServiceID),
82+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
83+
CheckDestroy: testAccCheckIPSetDestroy(ctx),
84+
Steps: []resource.TestStep{
85+
{
86+
Config: testAccIPSetConfig_nameGenerated(),
87+
Check: resource.ComposeTestCheckFunc(
88+
testAccCheckIPSetExists(ctx, resourceName, &v),
89+
acctest.CheckResourceAttrNameGenerated(resourceName, names.AttrName),
90+
resource.TestCheckResourceAttr(resourceName, names.AttrNamePrefix, id.UniqueIdPrefix),
91+
),
92+
},
93+
{
94+
ResourceName: resourceName,
95+
ImportState: true,
96+
ImportStateVerify: true,
97+
ImportStateIdFunc: testAccIPSetImportStateIdFunc(resourceName),
98+
},
99+
},
100+
})
101+
}
102+
103+
func TestAccWAFV2IPSet_namePrefix(t *testing.T) {
104+
ctx := acctest.Context(t)
105+
var v awstypes.IPSet
106+
resourceName := "aws_wafv2_ip_set.ip_set"
107+
108+
resource.ParallelTest(t, resource.TestCase{
109+
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckScopeRegional(ctx, t) },
110+
ErrorCheck: acctest.ErrorCheck(t, names.WAFV2ServiceID),
111+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
112+
CheckDestroy: testAccCheckIPSetDestroy(ctx),
113+
Steps: []resource.TestStep{
114+
{
115+
Config: testAccIPSetConfig_namePrefix("tf-acc-test-prefix-"),
116+
Check: resource.ComposeTestCheckFunc(
117+
testAccCheckIPSetExists(ctx, resourceName, &v),
118+
acctest.CheckResourceAttrNameFromPrefix(resourceName, names.AttrName, "tf-acc-test-prefix-"),
119+
resource.TestCheckResourceAttr(resourceName, names.AttrNamePrefix, "tf-acc-test-prefix-"),
120+
),
121+
},
122+
{
123+
ResourceName: resourceName,
124+
ImportState: true,
125+
ImportStateVerify: true,
126+
ImportStateIdFunc: testAccIPSetImportStateIdFunc(resourceName),
127+
},
128+
},
129+
})
130+
}
131+
72132
func TestAccWAFV2IPSet_disappears(t *testing.T) {
73133
ctx := acctest.Context(t)
74134
var r awstypes.IPSet
@@ -380,6 +440,39 @@ resource "aws_wafv2_ip_set" "ip_set" {
380440
`, name)
381441
}
382442

443+
func testAccIPSetConfig_nameGenerated() string {
444+
return `
445+
resource "aws_wafv2_ip_set" "ip_set" {
446+
description = "test"
447+
scope = "REGIONAL"
448+
ip_address_version = "IPV4"
449+
addresses = ["1.2.3.4/32", "5.6.7.8/32"]
450+
451+
tags = {
452+
Tag1 = "Value1"
453+
Tag2 = "Value2"
454+
}
455+
}
456+
`
457+
}
458+
459+
func testAccIPSetConfig_namePrefix(namePrefix string) string {
460+
return fmt.Sprintf(`
461+
resource "aws_wafv2_ip_set" "ip_set" {
462+
name_prefix = %[1]q
463+
description = %[1]q
464+
scope = "REGIONAL"
465+
ip_address_version = "IPV4"
466+
addresses = ["1.2.3.4/32", "5.6.7.8/32"]
467+
468+
tags = {
469+
Tag1 = "Value1"
470+
Tag2 = "Value2"
471+
}
472+
}
473+
`, namePrefix)
474+
}
475+
383476
func testAccIPSetConfig_addresses(name string) string {
384477
return fmt.Sprintf(`
385478
resource "aws_eip" "test" {

internal/service/wafv2/regex_pattern_set.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ import (
1010
"strings"
1111
"time"
1212

13+
"github.com/YakDriver/regexache"
1314
"github.com/aws/aws-sdk-go-v2/aws"
1415
"github.com/aws/aws-sdk-go-v2/service/wafv2"
1516
awstypes "github.com/aws/aws-sdk-go-v2/service/wafv2/types"
1617
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
18+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
1719
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1820
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1921
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
2022
"github.com/hashicorp/terraform-provider-aws/internal/conns"
23+
"github.com/hashicorp/terraform-provider-aws/internal/create"
2124
"github.com/hashicorp/terraform-provider-aws/internal/enum"
2225
"github.com/hashicorp/terraform-provider-aws/internal/errs"
2326
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
@@ -67,10 +70,26 @@ func resourceRegexPatternSet() *schema.Resource {
6770
Computed: true,
6871
},
6972
names.AttrName: {
70-
Type: schema.TypeString,
71-
Required: true,
72-
ForceNew: true,
73-
ValidateFunc: validation.StringLenBetween(1, 128),
73+
Type: schema.TypeString,
74+
Optional: true,
75+
Computed: true,
76+
ForceNew: true,
77+
ConflictsWith: []string{names.AttrNamePrefix},
78+
ValidateFunc: validation.All(
79+
validation.StringLenBetween(1, 128),
80+
validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_-]+$`), "must contain only alphanumeric hyphen and underscore characters"),
81+
),
82+
},
83+
names.AttrNamePrefix: {
84+
Type: schema.TypeString,
85+
Optional: true,
86+
Computed: true,
87+
ForceNew: true,
88+
ConflictsWith: []string{names.AttrName},
89+
ValidateFunc: validation.All(
90+
validation.StringLenBetween(1, 128-id.UniqueIDSuffixLength),
91+
validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z_-]+$`), "must contain only alphanumeric hyphen and underscore characters"),
92+
),
7493
},
7594
"regular_expression": {
7695
Type: schema.TypeSet,
@@ -106,7 +125,7 @@ func resourceRegexPatternSetCreate(ctx context.Context, d *schema.ResourceData,
106125
var diags diag.Diagnostics
107126
conn := meta.(*conns.AWSClient).WAFV2Client(ctx)
108127

109-
name := d.Get(names.AttrName).(string)
128+
name := create.Name(d.Get(names.AttrName).(string), d.Get(names.AttrNamePrefix).(string))
110129
input := &wafv2.CreateRegexPatternSetInput{
111130
Name: aws.String(name),
112131
RegularExpressionList: []awstypes.Regex{},
@@ -129,6 +148,7 @@ func resourceRegexPatternSetCreate(ctx context.Context, d *schema.ResourceData,
129148
}
130149

131150
d.SetId(aws.ToString(output.Summary.Id))
151+
d.Set(names.AttrName, name) // Required in Read.
132152

133153
return append(diags, resourceRegexPatternSetRead(ctx, d, meta)...)
134154
}
@@ -150,11 +170,11 @@ func resourceRegexPatternSetRead(ctx context.Context, d *schema.ResourceData, me
150170
}
151171

152172
regexPatternSet := output.RegexPatternSet
153-
arn := aws.ToString(regexPatternSet.ARN)
154-
d.Set(names.AttrARN, arn)
173+
d.Set(names.AttrARN, regexPatternSet.ARN)
155174
d.Set(names.AttrDescription, regexPatternSet.Description)
156175
d.Set("lock_token", output.LockToken)
157176
d.Set(names.AttrName, regexPatternSet.Name)
177+
d.Set(names.AttrNamePrefix, create.NamePrefixFromName(aws.ToString(regexPatternSet.Name)))
158178
if err := d.Set("regular_expression", flattenRegexPatternSet(regexPatternSet.RegularExpressionList)); err != nil {
159179
return sdkdiag.AppendErrorf(diags, "setting regular_expression: %s", err)
160180
}

0 commit comments

Comments
 (0)