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

Regular expression consistency #33359

Merged
merged 6 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .ci/.semgrep-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ rules:
- metavariable-pattern:
metavariable: "$VALUE"
patterns:
- pattern-not-regex: "testAcc[a-zA-Z0-9]+Config(_[a-zA-Z0-9_]+_|_)[a-z0-9].*"
- pattern-not-regex: "testAcc[0-9A-Za-z]+Config(_[0-9A-Za-z_]+_|_)[0-9a-z].*"
- pattern-not: acctest.ConfigCompose(...)
- pattern-not: "..."
severity: WARNING
Expand All @@ -39,7 +39,7 @@ rules:
- metavariable-pattern:
metavariable: "$VALUE"
patterns:
- pattern-not-regex: "testAcc[a-zA-Z0-9]+Config(_[a-zA-Z0-9_]+_|_)[a-z0-9].*"
- pattern-not-regex: "testAcc[0-9A-Za-z]+Config(_[0-9A-Za-z_]+_|_)[0-9a-z].*"
- pattern-not-regex: "acctest\\..*"
severity: WARNING

Expand Down
22 changes: 22 additions & 0 deletions docs/regular-expressions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Using Regular Expressions

Regular expressions are a powerful tool. However, they are also very expensive in terms of memory. Ensuring correct and useful functionality is the priority but we have a few tips to minimize impact without affecting capabilities.

* **Consider non-regular expressions options.** [`strings.Contains()`](https://pkg.go.dev/strings#Contains), [`strings.Replace()`](https://pkg.go.dev/strings#Replace), and [`strings.ReplaceAll()`](https://pkg.go.dev/strings#ReplaceAll) are dramatically faster and less memory intensive than regular expressions. If one of these will work equally well, use the non-regular expression option.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that many (most?) of the regular expressions (at least in my experience) are used in attribute validators, maybe add some links to standard validators that can be used instead of rolling your own regex validator?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note above is just a suggestion for a future version of this page.
LGTM 🚀.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea! Would be great if we had far fewer "manual" regular expressions.

* **Order character classes consistently.** We use regular expression caching to reduce our memory footprint. This is more effective if character classes are consistently ordered. Since a character class is a set, order does not affect functionality. We have many equivalent regular expressions that only differ by character class order. Below is the order we recommend for consistency:
1. Numeric range, _i.e._, digits (_e.g._, `0-9`)
2. Uppercase alphabetic range (_e.g._, `A-Z`, `A-F`)
3. Lowercase alphabetic range (_e.g._, `a-z`, `a-f`)
4. Underscore (`_`)
5. Everything else (except dash, `-`) in ASCII order: `\t\n\r !"#$%&()*+,./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^abcdefghijklmnopqrstuvwxyz{|}~`
6. _Last_, dash (`-`)
- Example 1, both equivalent, Wrong order: `[_a-zA-Z0-9-,.]`, Correct: `[0-9A-Za-z_,.-]`
- Example 2, both equivalent, Wrong order: `[;a-z0-9]`, Correct: `[0-9a-z;]`
* **Inside character classes, avoid unnecessary character escaping.** Go does not complain about extra character escaping but avoid it to improve cache performance. Inside a character class, _most_ characters do not need to be escaped, as Go assumes you mean the literal character.
* These characters which normally have special meaning in regular expressions, _inside character classes_ do **not** need to be escaped: `$`, `(`, `)`, `*`, `+`, `.`, `?`, `^`, `{`, `|`, `}`.
* Dash (`-`), when it is last in the character class or otherwise unambiguously not part of a range, does not need to be escaped. If in doubt, place the dash _last_ in the character class (_e.g._, `[a-c-]`) or escape the dash (_e.g._, `\-`).
* Angle brackets (`[`, `]`) always need to be escaped in a character class.
* Example 1, both equivalent, Unnecessary escapes: `[\$\(\.\?\|]`, Correct: `[$(.?|]`
* Example 2, both equivalent, Unnecessary escapes, wrong order: `[a-z\-0-9_A-Z\.]`, Correct: `[0-9A-Za-z_.-]`

<!-- Add links to standard validators to use instead of custom -->
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.20

require (
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95
github.com/YakDriver/regexache v0.20.0
github.com/YakDriver/regexache v0.23.0
github.com/aws/aws-sdk-go v1.45.4
github.com/aws/aws-sdk-go-v2 v1.21.0
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/YakDriver/regexache v0.20.0 h1:9xfyYbdBnI4DU5ao/5PErxUbzen7yPASzbnjhtCo4uk=
github.com/YakDriver/regexache v0.20.0/go.mod h1:K4BZ3MYKAqSFbYWqmbsG+OzYUDyJjnMEr27DJEsVG3U=
github.com/YakDriver/regexache v0.23.0 h1:kv3j4XKhbx/vqUilSBgizXDUXHvvH1KdYekdmGwz4C4=
github.com/YakDriver/regexache v0.23.0/go.mod h1:K4BZ3MYKAqSFbYWqmbsG+OzYUDyJjnMEr27DJEsVG3U=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
Expand Down
2 changes: 1 addition & 1 deletion internal/generate/servicepackage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ var tmpl string

// Annotation processing.
var (
annotation = regexache.MustCompile(`^//\s*@([a-zA-Z0-9]+)(\(([^)]*)\))?\s*$`)
annotation = regexache.MustCompile(`^//\s*@([0-9A-Za-z]+)(\(([^)]*)\))?\s*$`)
)

type visitor struct {
Expand Down
4 changes: 2 additions & 2 deletions internal/generate/servicesemgrep/configs.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ rules:
- metavariable-pattern:
metavariable: "$VALUE"
patterns:
- pattern-not-regex: "testAcc[a-zA-Z0-9]+Config(_[a-zA-Z0-9_]+_|_)[a-z0-9].*"
- pattern-not-regex: "testAcc[0-9A-Za-z]+Config(_[0-9A-Za-z_]+_|_)[0-9a-z].*"
- pattern-not: acctest.ConfigCompose(...)
- pattern-not: "..."
severity: WARNING
Expand All @@ -39,7 +39,7 @@ rules:
- metavariable-pattern:
metavariable: "$VALUE"
patterns:
- pattern-not-regex: "testAcc[a-zA-Z0-9]+Config(_[a-zA-Z0-9_]+_|_)[a-z0-9].*"
- pattern-not-regex: "testAcc[0-9A-Za-z]+Config(_[0-9A-Za-z_]+_|_)[0-9a-z].*"
- pattern-not-regex: "acctest\\..*"
severity: WARNING

Expand Down
2 changes: 1 addition & 1 deletion internal/generate/tags/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ func main() {

func toSnakeCase(str string) string {
result := regexache.MustCompile("(.)([A-Z][a-z]+)").ReplaceAllString(str, "${1}_${2}")
result = regexache.MustCompile("([a-z0-9])([A-Z])").ReplaceAllString(result, "${1}_${2}")
result = regexache.MustCompile("([0-9a-z])([A-Z])").ReplaceAllString(result, "${1}_${2}")
return strings.ToLower(result)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/service/accessanalyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func resourceAnalyzer() *schema.Resource {
ForceNew: true,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 255),
validation.StringMatch(regexache.MustCompile(`^[A-Za-z][A-Za-z0-9_.-]*$`), "must begin with a letter and contain only alphanumeric, underscore, period, or hyphen characters"),
validation.StringMatch(regexache.MustCompile(`^[A-Za-z][0-9A-Za-z_.-]*$`), "must begin with a letter and contain only alphanumeric, underscore, period, or hyphen characters"),
),
},
"arn": {
Expand Down
2 changes: 1 addition & 1 deletion internal/service/account/alternate_contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func resourceAlternateContact() *schema.Resource {
"phone_number": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`^[\s0-9()+-]+$`), "must be a valid phone number"),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`^[0-9\s()+-]+$`), "must be a valid phone number"),
},
"title": {
Type: schema.TypeString,
Expand Down
2 changes: 1 addition & 1 deletion internal/service/account/primary_contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func resourcePrimaryContact() *schema.Resource {
"phone_number": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`^[+][\s0-9()-]+$`), "must be a valid phone number"),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`^[+][0-9\s()-]+$`), "must be a valid phone number"),
},
"postal_code": {
Type: schema.TypeString,
Expand Down
6 changes: 3 additions & 3 deletions internal/service/apigateway/domain_name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestAccAPIGatewayDomainName_certificateARN(t *testing.T) {
testAccCheckDomainNameExists(ctx, resourceName, &domainName),
testAccCheckResourceAttrRegionalARNEdgeDomainName(resourceName, "arn", "apigateway", domain),
resource.TestCheckResourceAttrPair(resourceName, "certificate_arn", acmCertificateResourceName, "arn"),
resource.TestMatchResourceAttr(resourceName, "cloudfront_domain_name", regexache.MustCompile(`[a-z0-9]+.cloudfront.net`)),
resource.TestMatchResourceAttr(resourceName, "cloudfront_domain_name", regexache.MustCompile(`[0-9a-z]+.cloudfront.net`)),
resource.TestCheckResourceAttr(resourceName, "cloudfront_zone_id", "Z2FDTNDATAQYW2"),
resource.TestCheckResourceAttrPair(resourceName, "domain_name", acmCertificateResourceName, "domain_name"),
),
Expand Down Expand Up @@ -140,7 +140,7 @@ func TestAccAPIGatewayDomainName_regionalCertificateARN(t *testing.T) {
testAccCheckDomainNameExists(ctx, resourceName, &domainName),
testAccCheckResourceAttrRegionalARNRegionalDomainName(resourceName, "arn", "apigateway", rName),
resource.TestCheckResourceAttr(resourceName, "domain_name", rName),
acctest.MatchResourceAttrRegionalHostname(resourceName, "regional_domain_name", "execute-api", regexache.MustCompile(`d-[a-z0-9]+`)),
acctest.MatchResourceAttrRegionalHostname(resourceName, "regional_domain_name", "execute-api", regexache.MustCompile(`d-[0-9a-z]+`)),
resource.TestMatchResourceAttr(resourceName, "regional_zone_id", regexache.MustCompile(`^Z`)),
),
},
Expand Down Expand Up @@ -189,7 +189,7 @@ func TestAccAPIGatewayDomainName_regionalCertificateName(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "certificate_private_key", key),
resource.TestCheckResourceAttrSet(resourceName, "certificate_upload_date"),
resource.TestCheckResourceAttr(resourceName, "domain_name", rName),
acctest.MatchResourceAttrRegionalHostname(resourceName, "regional_domain_name", "execute-api", regexache.MustCompile(`d-[a-z0-9]+`)),
acctest.MatchResourceAttrRegionalHostname(resourceName, "regional_domain_name", "execute-api", regexache.MustCompile(`d-[0-9a-z]+`)),
resource.TestMatchResourceAttr(resourceName, "regional_zone_id", regexache.MustCompile(`^Z`)),
),
},
Expand Down
4 changes: 2 additions & 2 deletions internal/service/apigateway/rest_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ func TestAccAPIGatewayRestAPI_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", ""),
resource.TestCheckResourceAttr(resourceName, "disable_execute_api_endpoint", "false"),
resource.TestCheckResourceAttr(resourceName, "endpoint_configuration.#", "1"),
acctest.MatchResourceAttrRegionalARN(resourceName, "execution_arn", "execute-api", regexache.MustCompile(`[a-z0-9]+`)),
acctest.MatchResourceAttrRegionalARN(resourceName, "execution_arn", "execute-api", regexache.MustCompile(`[0-9a-z]+`)),
resource.TestCheckResourceAttr(resourceName, "name", rName),
resource.TestCheckResourceAttr(resourceName, "parameters.%", "0"),
resource.TestMatchResourceAttr(resourceName, "root_resource_id", regexache.MustCompile(`[a-z0-9]+`)),
resource.TestMatchResourceAttr(resourceName, "root_resource_id", regexache.MustCompile(`[0-9a-z]+`)),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
},
Expand Down
2 changes: 1 addition & 1 deletion internal/service/apigatewayv2/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func ResourceModel() *schema.Resource {
Required: true,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 128),
validation.StringMatch(regexache.MustCompile(`^[a-zA-Z0-9]+$`), "must be alphanumeric"),
validation.StringMatch(regexache.MustCompile(`^[0-9A-Za-z]+$`), "must be alphanumeric"),
),
},
"schema": {
Expand Down
2 changes: 1 addition & 1 deletion internal/service/appconfig/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestAccAppConfigApplication_basic(t *testing.T) {
Config: testAccApplicationConfig_name(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckApplicationExists(ctx, resourceName),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[a-z0-9]{4,7}`)),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[0-9a-z]{4,7}`)),
resource.TestCheckResourceAttr(resourceName, "name", rName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
),
Expand Down
2 changes: 1 addition & 1 deletion internal/service/appconfig/configuration_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func ResourceConfigurationProfile() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[a-z0-9]{4,7}`), ""),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[0-9a-z]{4,7}`), ""),
},
"arn": {
Type: schema.TypeString,
Expand Down
4 changes: 2 additions & 2 deletions internal/service/appconfig/configuration_profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func TestAccAppConfigConfigurationProfile_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckConfigurationProfileExists(ctx, resourceName),
resource.TestCheckResourceAttrPair(resourceName, "application_id", appResourceName, "id"),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[a-z0-9]{4,7}/configurationprofile/[a-z0-9]{4,7}`)),
resource.TestMatchResourceAttr(resourceName, "configuration_profile_id", regexache.MustCompile(`[a-z0-9]{4,7}`)),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[0-9a-z]{4,7}/configurationprofile/[0-9a-z]{4,7}`)),
resource.TestMatchResourceAttr(resourceName, "configuration_profile_id", regexache.MustCompile(`[0-9a-z]{4,7}`)),
resource.TestCheckResourceAttr(resourceName, "location_uri", "hosted"),
resource.TestCheckResourceAttr(resourceName, "name", rName),
resource.TestCheckResourceAttr(resourceName, "tags.%", "0"),
Expand Down
8 changes: 4 additions & 4 deletions internal/service/appconfig/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func ResourceDeployment() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[a-z0-9]{4,7}`), ""),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[0-9a-z]{4,7}`), ""),
},
"arn": {
Type: schema.TypeString,
Expand All @@ -52,7 +52,7 @@ func ResourceDeployment() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[a-z0-9]{4,7}`), ""),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[0-9a-z]{4,7}`), ""),
},
"configuration_version": {
Type: schema.TypeString,
Expand All @@ -68,7 +68,7 @@ func ResourceDeployment() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`(^[a-z0-9]{4,7}$|^AppConfig\.[A-Za-z0-9]{9,40}$)`), ""),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`(^[0-9a-z]{4,7}$|^AppConfig\.[0-9A-Za-z]{9,40}$)`), ""),
},
"description": {
Type: schema.TypeString,
Expand All @@ -80,7 +80,7 @@ func ResourceDeployment() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[a-z0-9]{4,7}`), ""),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[0-9a-z]{4,7}`), ""),
},
"state": {
Type: schema.TypeString,
Expand Down
2 changes: 1 addition & 1 deletion internal/service/appconfig/deployment_strategy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestAccAppConfigDeploymentStrategy_basic(t *testing.T) {
Config: testAccDeploymentStrategyConfig_name(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDeploymentStrategyExists(ctx, resourceName),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`deploymentstrategy/[a-z0-9]{4,7}`)),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`deploymentstrategy/[0-9a-z]{4,7}`)),
resource.TestCheckResourceAttr(resourceName, "deployment_duration_in_minutes", "3"),
resource.TestCheckResourceAttr(resourceName, "growth_factor", "10"),
resource.TestCheckResourceAttr(resourceName, "name", rName),
Expand Down
2 changes: 1 addition & 1 deletion internal/service/appconfig/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestAccAppConfigDeployment_basic(t *testing.T) {
Config: testAccDeploymentConfig_name(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckDeploymentExists(ctx, resourceName),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[a-z0-9]{4,7}/environment/[a-z0-9]{4,7}/deployment/1`)),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[0-9a-z]{4,7}/environment/[0-9a-z]{4,7}/deployment/1`)),
resource.TestCheckResourceAttrPair(resourceName, "application_id", appResourceName, "id"),
resource.TestCheckResourceAttrPair(resourceName, "configuration_profile_id", confProfResourceName, "configuration_profile_id"),
resource.TestCheckResourceAttrPair(resourceName, "configuration_version", confVersionResourceName, "version_number"),
Expand Down
2 changes: 1 addition & 1 deletion internal/service/appconfig/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (r *resourceEnvironment) Schema(ctx context.Context, request resource.Schem
},
Validators: []validator.String{
stringvalidator.RegexMatches(
regexache.MustCompile(`^[a-z0-9]{4,7}$`),
regexache.MustCompile(`^[0-9a-z]{4,7}$`),
"value must contain 4-7 lowercase letters or numbers",
),
},
Expand Down
2 changes: 1 addition & 1 deletion internal/service/appconfig/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestAccAppConfigEnvironment_basic(t *testing.T) {
Config: testAccEnvironmentConfig_basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckEnvironmentExists(ctx, resourceName),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[a-z0-9]{4,7}/environment/[a-z0-9]{4,7}`)),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[0-9a-z]{4,7}/environment/[0-9a-z]{4,7}`)),
resource.TestCheckResourceAttrPair(resourceName, "application_id", appResourceName, "id"),
resource.TestCheckResourceAttr(resourceName, "description", ""),
resource.TestCheckResourceAttr(resourceName, "monitor.#", "0"),
Expand Down
4 changes: 2 additions & 2 deletions internal/service/appconfig/hosted_configuration_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func ResourceHostedConfigurationVersion() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[a-z0-9]{4,7}`), ""),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[0-9a-z]{4,7}`), ""),
},
"arn": {
Type: schema.TypeString,
Expand All @@ -47,7 +47,7 @@ func ResourceHostedConfigurationVersion() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[a-z0-9]{4,7}`), ""),
ValidateFunc: validation.StringMatch(regexache.MustCompile(`[0-9a-z]{4,7}`), ""),
},
"content": {
Type: schema.TypeString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestAccAppConfigHostedConfigurationVersion_basic(t *testing.T) {
Config: testAccHostedConfigurationVersionConfig_basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckHostedConfigurationVersionExists(ctx, resourceName),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[a-z0-9]{4,7}/configurationprofile/[a-z0-9]{4,7}/hostedconfigurationversion/[0-9]+`)),
acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "appconfig", regexache.MustCompile(`application/[0-9a-z]{4,7}/configurationprofile/[0-9a-z]{4,7}/hostedconfigurationversion/[0-9]+`)),
resource.TestCheckResourceAttrPair(resourceName, "application_id", "aws_appconfig_application.test", "id"),
resource.TestCheckResourceAttrPair(resourceName, "configuration_profile_id", "aws_appconfig_configuration_profile.test", "configuration_profile_id"),
resource.TestCheckResourceAttr(resourceName, "content", "{\"foo\":\"bar\"}"),
Expand Down
2 changes: 1 addition & 1 deletion internal/service/appconfig/sweep.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func sweepDeploymentStrategies(region string) error {
id := aws.StringValue(item.Id)

// Deleting AppConfig Predefined Strategies is not supported; returns BadRequestException
if regexache.MustCompile(`^AppConfig\.[A-Za-z0-9]{9,40}$`).MatchString(id) {
if regexache.MustCompile(`^AppConfig\.[0-9A-Za-z]{9,40}$`).MatchString(id) {
log.Printf("[DEBUG] Skipping AppConfig Deployment Strategy (%s): predefined strategy cannot be deleted", id)
continue
}
Expand Down
Loading
Loading