diff --git a/.changelog/34716.txt b/.changelog/34716.txt new file mode 100644 index 00000000000..dff67cc970b --- /dev/null +++ b/.changelog/34716.txt @@ -0,0 +1,7 @@ +```release-note:bug +resource/aws_ecr_pull_through_cache_rule: Fix plan time validation for `ecr_repository_prefix` +``` + +```release-note:bug +data-source/aws_ecr_pull_through_cache_rule: Fix plan time validation for `ecr_repository_prefix` +``` diff --git a/internal/service/ecr/pull_through_cache_rule.go b/internal/service/ecr/pull_through_cache_rule.go index de356d55963..4e68b4339ab 100644 --- a/internal/service/ecr/pull_through_cache_rule.go +++ b/internal/service/ecr/pull_through_cache_rule.go @@ -35,10 +35,10 @@ func ResourcePullThroughCacheRule() *schema.Resource { Required: true, ForceNew: true, ValidateFunc: validation.All( - validation.StringLenBetween(2, 20), + validation.StringLenBetween(2, 30), validation.StringMatch( - regexache.MustCompile(`^[0-9a-z]+(?:[._-][0-9a-z]+)*$`), - "must only include alphanumeric, underscore, period, or hyphen characters"), + regexache.MustCompile(`(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*`), + "must only include alphanumeric, underscore, period, hyphen, or slash characters"), ), }, "registry_id": { diff --git a/internal/service/ecr/pull_through_cache_rule_data_source.go b/internal/service/ecr/pull_through_cache_rule_data_source.go index 65bd8491754..036e7ccba77 100644 --- a/internal/service/ecr/pull_through_cache_rule_data_source.go +++ b/internal/service/ecr/pull_through_cache_rule_data_source.go @@ -24,10 +24,10 @@ func DataSourcePullThroughCacheRule() *schema.Resource { Required: true, ForceNew: true, ValidateFunc: validation.All( - validation.StringLenBetween(2, 20), + validation.StringLenBetween(2, 30), validation.StringMatch( - regexache.MustCompile(`^[0-9a-z]+(?:[._-][0-9a-z]+)*$`), - "must only include alphanumeric, underscore, period, or hyphen characters"), + regexache.MustCompile(`(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*`), + "must only include alphanumeric, underscore, period, hyphen, or slash characters"), ), }, "registry_id": { diff --git a/internal/service/ecr/pull_through_cache_rule_data_source_test.go b/internal/service/ecr/pull_through_cache_rule_data_source_test.go index f0e1ef7b84a..2d349153da6 100644 --- a/internal/service/ecr/pull_through_cache_rule_data_source_test.go +++ b/internal/service/ecr/pull_through_cache_rule_data_source_test.go @@ -4,9 +4,11 @@ package ecr_test import ( + "fmt" "testing" "github.com/aws/aws-sdk-go/service/ecr" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) @@ -31,6 +33,28 @@ func TestAccECRPullThroughCacheRuleDataSource_basic(t *testing.T) { }) } +func TestAccECRPullThroughCacheRuleDataSource_repositoryPrefixWithSlash(t *testing.T) { + ctx := acctest.Context(t) + repositoryPrefix := "tf-test/" + sdkacctest.RandString(22) + dataSource := "data.aws_ecr_pull_through_cache_rule.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, ecr.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckPullThroughCacheRuleDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccPullThroughCacheRuleDataSourceConfig_repositoryPrefixWithSlash(repositoryPrefix), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSource, "upstream_registry_url", "public.ecr.aws"), + acctest.CheckResourceAttrAccountID(dataSource, "registry_id"), + ), + }, + }, + }) +} + func testAccPullThroughCacheRuleDataSourceConfig_basic() string { return ` resource "aws_ecr_pull_through_cache_rule" "test" { @@ -43,3 +67,16 @@ data "aws_ecr_pull_through_cache_rule" "test" { } ` } + +func testAccPullThroughCacheRuleDataSourceConfig_repositoryPrefixWithSlash(repositoryPrefix string) string { + return fmt.Sprintf(` +resource "aws_ecr_pull_through_cache_rule" "test" { + ecr_repository_prefix = %[1]q + upstream_registry_url = "public.ecr.aws" +} + +data "aws_ecr_pull_through_cache_rule" "test" { + ecr_repository_prefix = aws_ecr_pull_through_cache_rule.test.ecr_repository_prefix +} +`, repositoryPrefix) +} diff --git a/internal/service/ecr/pull_through_cache_rule_test.go b/internal/service/ecr/pull_through_cache_rule_test.go index a7afde6da90..9e4dcb48765 100644 --- a/internal/service/ecr/pull_through_cache_rule_test.go +++ b/internal/service/ecr/pull_through_cache_rule_test.go @@ -97,6 +97,30 @@ func TestAccECRPullThroughCacheRule_failWhenAlreadyExists(t *testing.T) { }) } +func TestAccECRPullThroughCacheRule_repositoryPrefixWithSlash(t *testing.T) { + ctx := acctest.Context(t) + repositoryPrefix := "tf-test/" + sdkacctest.RandString(22) + resourceName := "aws_ecr_pull_through_cache_rule.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, ecr.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckPullThroughCacheRuleDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccPullThroughCacheRuleConfig_basic(repositoryPrefix), + Check: resource.ComposeTestCheckFunc( + testAccCheckPullThroughCacheRuleExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "ecr_repository_prefix", repositoryPrefix), + testAccCheckPullThroughCacheRuleRegistryID(resourceName), + resource.TestCheckResourceAttr(resourceName, "upstream_registry_url", "public.ecr.aws"), + ), + }, + }, + }) +} + func testAccCheckPullThroughCacheRuleDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).ECRConn(ctx)