From 02cd3f5137f2516b38a44560e79644a70856e614 Mon Sep 17 00:00:00 2001 From: Roko Romic Date: Mon, 20 May 2024 10:02:22 +0200 Subject: [PATCH] feat: modify update method to use api to add or remove client ids without destroying openid connect provider --- .../service/iam/openid_connect_provider.go | 34 +++++++- .../iam/openid_connect_provider_test.go | 82 +++++++++++++++++++ 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/internal/service/iam/openid_connect_provider.go b/internal/service/iam/openid_connect_provider.go index 01ecafe69f4a..4edeb91e1340 100644 --- a/internal/service/iam/openid_connect_provider.go +++ b/internal/service/iam/openid_connect_provider.go @@ -46,7 +46,6 @@ func resourceOpenIDConnectProvider() *schema.Resource { "client_id_list": { Type: schema.TypeSet, Required: true, - ForceNew: true, Elem: &schema.Schema{ Type: schema.TypeString, ValidateFunc: validation.StringLenBetween(1, 255), @@ -162,6 +161,39 @@ func resourceOpenIDConnectProviderUpdate(ctx context.Context, d *schema.Resource } } + if d.HasChange("client_id_list") { + o, n := d.GetChange("client_id_list") + oldSet, newSet := o.(*schema.Set), n.(*schema.Set) + + for _, v := range newSet.Difference(oldSet).List() { + clientIdToAdd := v.(string) + input := &iam.AddClientIDToOpenIDConnectProviderInput{ + OpenIDConnectProviderArn: aws.String(d.Id()), + ClientID: aws.String(clientIdToAdd), + } + + _, err := conn.AddClientIDToOpenIDConnectProvider(ctx, input) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "adding clientID (%s) to IAM OIDC Provider: %s", clientIdToAdd, err) + } + } + + for _, v := range oldSet.Difference(newSet).List() { + clientIdToRemove := v.(string) + input := &iam.RemoveClientIDFromOpenIDConnectProviderInput{ + OpenIDConnectProviderArn: aws.String(d.Id()), + ClientID: aws.String(clientIdToRemove), + } + + _, err := conn.RemoveClientIDFromOpenIDConnectProvider(ctx, input) + + if err != nil { + return sdkdiag.AppendErrorf(diags, "removing clientID (%s) from IAM OIDC Provider: %s", clientIdToRemove, err) + } + } + } + return append(diags, resourceOpenIDConnectProviderRead(ctx, d, meta)...) } diff --git a/internal/service/iam/openid_connect_provider_test.go b/internal/service/iam/openid_connect_provider_test.go index 20d8b59e7f7a..48c9f682356f 100644 --- a/internal/service/iam/openid_connect_provider_test.go +++ b/internal/service/iam/openid_connect_provider_test.go @@ -118,6 +118,55 @@ func TestAccIAMOpenIDConnectProvider_clientIDListOrder(t *testing.T) { }) } +func TestAccIAMOpenIDConnectProvider_clientIDModification(t *testing.T) { + ctx := acctest.Context(t) + rString := sdkacctest.RandString(5) + resourceName := "aws_iam_openid_connect_provider.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.IAMServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOpenIDConnectProviderDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccOpenIDConnectProviderConfig_clientIDList_first(rString), + Check: resource.ComposeTestCheckFunc( + testAccCheckOpenIDConnectProviderExists(ctx, resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccOpenIDConnectProviderConfig_clientIDList_add(rString), + Check: resource.ComposeTestCheckFunc( + testAccCheckOpenIDConnectProviderExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "client_id_list.#", acctest.Ct4), + resource.TestCheckResourceAttr(resourceName, "client_id_list.0", "abc.testle.com"), + resource.TestCheckResourceAttr(resourceName, "client_id_list.3", "xyz.testle.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccOpenIDConnectProviderConfig_clientIDList_remove(rString), + Check: resource.ComposeTestCheckFunc( + testAccCheckOpenIDConnectProviderExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "client_id_list.#", acctest.Ct3), + resource.TestCheckResourceAttr(resourceName, "client_id_list.0", "def.testle.com"), + resource.TestCheckResourceAttr(resourceName, "client_id_list.2", "xyz.testle.com"), + ), + }, + }, + }) +} + func testAccCheckOpenIDConnectProviderDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).IAMClient(ctx) @@ -222,3 +271,36 @@ resource "aws_iam_openid_connect_provider" "test" { } `, rName) } + +func testAccOpenIDConnectProviderConfig_clientIDList_add(rName string) string { + return fmt.Sprintf(` +resource "aws_iam_openid_connect_provider" "test" { + url = "https://accounts.testle.com/%[1]s" + + client_id_list = [ + "abc.testle.com", + "def.testle.com", + "ghi.testle.com", + "xyz.testle.com", + ] + + thumbprint_list = ["oif8192f189fa2178f-testle.thumbprint.com"] +} +`, rName) +} + +func testAccOpenIDConnectProviderConfig_clientIDList_remove(rName string) string { + return fmt.Sprintf(` +resource "aws_iam_openid_connect_provider" "test" { + url = "https://accounts.testle.com/%[1]s" + + client_id_list = [ + "def.testle.com", + "ghi.testle.com", + "xyz.testle.com", + ] + + thumbprint_list = ["oif8192f189fa2178f-testle.thumbprint.com"] +} +`, rName) +}