diff --git a/.changelog/35535.txt b/.changelog/35535.txt new file mode 100644 index 00000000000..15b65e6e9e4 --- /dev/null +++ b/.changelog/35535.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_eks_access_entry: Retry IAM eventual consistency errors on create +``` diff --git a/internal/service/eks/access_entry.go b/internal/service/eks/access_entry.go index 47c72204b37..a3c42ab8a26 100644 --- a/internal/service/eks/access_entry.go +++ b/internal/service/eks/access_entry.go @@ -120,7 +120,9 @@ func resourceAccessEntryCreate(ctx context.Context, d *schema.ResourceData, meta input.Username = aws.String(v.(string)) } - _, err := conn.CreateAccessEntry(ctx, input) + _, err := tfresource.RetryWhenIsAErrorMessageContains[*types.InvalidParameterException](ctx, propagationTimeout, func() (interface{}, error) { + return conn.CreateAccessEntry(ctx, input) + }, "The specified principalArn is invalid: invalid principal") if err != nil { return sdkdiag.AppendErrorf(diags, "creating EKS Access Entry (%s): %s", id, err) diff --git a/internal/service/eks/access_entry_test.go b/internal/service/eks/access_entry_test.go index f36bcd1f367..799e8b41dbb 100644 --- a/internal/service/eks/access_entry_test.go +++ b/internal/service/eks/access_entry_test.go @@ -257,6 +257,43 @@ func TestAccEKSAccessEntry_username(t *testing.T) { }) } +func TestAccEKSAccessEntry_eventualConsistency(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var accessentry types.AccessEntry + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_eks_access_entry.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.EKSEndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAccessEntryDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAccessEntryConfig_eventualConsistency(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAccessEntryExists(ctx, resourceName, &accessentry), + acctest.CheckResourceAttrGreaterThanOrEqualValue(resourceName, "kubernetes_groups.#", 1), + resource.TestCheckResourceAttr(resourceName, "type", "EC2_LINUX"), + resource.TestCheckResourceAttrSet(resourceName, "user_name"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAccessEntryDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).EKSClient(ctx) @@ -449,6 +486,36 @@ resource "aws_eks_access_entry" "test" { `, rName)) } +func testAccAccessEntryConfig_eventualConsistency(rName string) string { + return acctest.ConfigCompose(testAccAccessEntryConfig_base(rName), ` +resource "aws_iam_role" "test2" { + name = "${aws_eks_cluster.test.name}-2" + + assume_role_policy = <