From 7fe8e03edcbd6ed0de3fb97633662ac90c41806b Mon Sep 17 00:00:00 2001 From: Andrew Chubatiuk Date: Fri, 19 Jan 2024 15:27:34 +0200 Subject: [PATCH 1/8] make EKS access entry user_name and type configurable --- .changelog/35391.txt | 3 +++ internal/service/eks/access_entry.go | 22 ++++++++++++++++++- website/docs/r/eks_access_entry.html.markdown | 5 +++-- 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 .changelog/35391.txt diff --git a/.changelog/35391.txt b/.changelog/35391.txt new file mode 100644 index 00000000000..a953d220b15 --- /dev/null +++ b/.changelog/35391.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_eks_access_entry: Support `type` and `user_name` configuration +``` diff --git a/internal/service/eks/access_entry.go b/internal/service/eks/access_entry.go index 5cc817b8848..f4e8b6528be 100644 --- a/internal/service/eks/access_entry.go +++ b/internal/service/eks/access_entry.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/errs" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" @@ -82,11 +83,20 @@ func resourceAccessEntry() *schema.Resource { names.AttrTagsAll: tftags.TagsSchemaComputed(), "type": { Type: schema.TypeString, - Computed: true, + Optional: true, + Default: "STANDARD", + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + "EC2_LINUX", + "EC2_WINDOWS", + "STANDARD", + "FARGATE_LINUX", + }, false), }, "user_name": { Type: schema.TypeString, Computed: true, + Optional: true, }, }, } @@ -98,13 +108,19 @@ func resourceAccessEntryCreate(ctx context.Context, d *schema.ResourceData, meta clusterName := d.Get("cluster_name").(string) principalARN := d.Get("principal_arn").(string) + entryType := d.Get("type").(string) id := accessEntryCreateResourceID(clusterName, principalARN) input := &eks.CreateAccessEntryInput{ ClusterName: aws.String(clusterName), PrincipalArn: aws.String(principalARN), + Type: aws.String(entryType), Tags: getTagsIn(ctx), } + if v, ok := d.GetOk("user_name"); ok { + input.Username = aws.String(v.(string)) + } + if v, ok := d.GetOk("kubernetes_groups"); ok { input.KubernetesGroups = flex.ExpandStringValueSet(v.(*schema.Set)) } @@ -170,6 +186,10 @@ func resourceAccessEntryUpdate(ctx context.Context, d *schema.ResourceData, meta PrincipalArn: aws.String(principalARN), } + if d.HasChange("user_name") { + input.Username = aws.String(d.Get("user_name").(string)) + } + if d.HasChange("kubernetes_groups") { input.KubernetesGroups = flex.ExpandStringValueSet(d.Get("kubernetes_groups").(*schema.Set)) } diff --git a/website/docs/r/eks_access_entry.html.markdown b/website/docs/r/eks_access_entry.html.markdown index 259802f174b..fa956f81795 100644 --- a/website/docs/r/eks_access_entry.html.markdown +++ b/website/docs/r/eks_access_entry.html.markdown @@ -17,6 +17,7 @@ resource "aws_eks_access_entry" "example" { cluster_name = aws_eks_cluster.example.name principal_arn = aws_iam_role.example.arn kubernetes_groups = ["group-1", "group-2"] + type = "STANDARD" } ``` @@ -31,6 +32,8 @@ The following arguments are optional: * `kubernetes_groups` – (Optional) List of string which can optionally specify the Kubernetes groups the user would belong to when creating an access entry. * `tags` - (Optional) Key-value map of resource tags. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. +* `type` - (Optional) Defaults to STANDARD which provides the standard workflow. EC2_LINUX, EC2_WINDOWS, FARGATE_LINUX types disallow users to input a username or groups, and prevent associations. +* `user_name` - (Optional) Defaults to principal ARN if user is principal else defaults to assume-role/session-name is role is used. ## Attribute Reference @@ -39,8 +42,6 @@ This resource exports the following attributes in addition to the arguments abov * `access_entry_arn` - Amazon Resource Name (ARN) of the Access Entry. * `created_at` - Date and time in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8) that the EKS add-on was created. * `modified_at` - Date and time in [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8) that the EKS add-on was updated. -* `user_name` - Defaults to principal ARN if user is principal else defaults to assume-role/session-name is role is used. -* `type` - Defaults to STANDARD which provides the standard workflow. EC2_LINUX, EC2_WINDOWS, FARGATE_LINUX types disallow users to input a username or groups, and prevent associations. * `tags_all` - (Optional) Key-value map of resource tags, including those inherited from the provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block). ## Timeouts From 443f4bd9740d111ccc1f21f9317d5609a19500d7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Jan 2024 09:27:06 -0500 Subject: [PATCH 2/8] Tweak CHANGELOG entry. --- .changelog/35391.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/35391.txt b/.changelog/35391.txt index a953d220b15..b8d59ea6aac 100644 --- a/.changelog/35391.txt +++ b/.changelog/35391.txt @@ -1,3 +1,3 @@ ```release-note:bug -resource/aws_eks_access_entry: Support `type` and `user_name` configuration +resource/aws_eks_access_entry: Mark `type` and `user_name` as Optional, allowing values to be configured ``` From 739b92117e103130f3165b0ea21d70c9e3434556 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Jan 2024 09:32:50 -0500 Subject: [PATCH 3/8] eks: Define constants for access entry types. --- internal/service/eks/access_entry.go | 15 ++++-------- internal/service/eks/cluster.go | 2 +- internal/service/eks/consts.go | 24 +++++++++++++++---- internal/service/eks/find.go | 2 +- .../service/eks/identity_provider_config.go | 4 ++-- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/internal/service/eks/access_entry.go b/internal/service/eks/access_entry.go index f4e8b6528be..f0b421d8564 100644 --- a/internal/service/eks/access_entry.go +++ b/internal/service/eks/access_entry.go @@ -82,16 +82,11 @@ func resourceAccessEntry() *schema.Resource { names.AttrTags: tftags.TagsSchema(), names.AttrTagsAll: tftags.TagsSchemaComputed(), "type": { - Type: schema.TypeString, - Optional: true, - Default: "STANDARD", - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{ - "EC2_LINUX", - "EC2_WINDOWS", - "STANDARD", - "FARGATE_LINUX", - }, false), + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: accessEntryTypeStandard, + ValidateFunc: validation.StringInSlice(accessEntryType_Values(), false), }, "user_name": { Type: schema.TypeString, diff --git a/internal/service/eks/cluster.go b/internal/service/eks/cluster.go index 78dc48f8177..518deaaef20 100644 --- a/internal/service/eks/cluster.go +++ b/internal/service/eks/cluster.go @@ -136,7 +136,7 @@ func resourceCluster() *schema.Resource { Required: true, Elem: &schema.Schema{ Type: schema.TypeString, - ValidateFunc: validation.StringInSlice(Resources_Values(), false), + ValidateFunc: validation.StringInSlice(resources_Values(), false), }, }, }, diff --git a/internal/service/eks/consts.go b/internal/service/eks/consts.go index 4bf92304f5c..60829b0de32 100644 --- a/internal/service/eks/consts.go +++ b/internal/service/eks/consts.go @@ -8,19 +8,35 @@ import ( ) const ( - IdentityProviderConfigTypeOIDC = "oidc" + identityProviderConfigTypeOIDC = "oidc" ) const ( - ResourcesSecrets = "secrets" + resourcesSecrets = "secrets" ) -func Resources_Values() []string { +func resources_Values() []string { return []string{ - ResourcesSecrets, + resourcesSecrets, } } const ( propagationTimeout = 2 * time.Minute ) + +const ( + accessEntryTypeEC2Linux = "EC2_LINUX" + accessEntryTypeEC2Windows = "EC2_WINDOWS" + accessEntryTypeFargateLinux = "FARGATE_LINUX" + accessEntryTypeStandard = "STANDARD" +) + +func accessEntryType_Values() []string { + return []string{ + accessEntryTypeEC2Linux, + accessEntryTypeEC2Windows, + accessEntryTypeFargateLinux, + accessEntryTypeStandard, + } +} diff --git a/internal/service/eks/find.go b/internal/service/eks/find.go index 719f410ddb5..ea85e18fa7c 100644 --- a/internal/service/eks/find.go +++ b/internal/service/eks/find.go @@ -195,7 +195,7 @@ func FindOIDCIdentityProviderConfigByClusterNameAndConfigName(ctx context.Contex ClusterName: aws.String(clusterName), IdentityProviderConfig: &types.IdentityProviderConfig{ Name: aws.String(configName), - Type: aws.String(IdentityProviderConfigTypeOIDC), + Type: aws.String(identityProviderConfigTypeOIDC), }, } diff --git a/internal/service/eks/identity_provider_config.go b/internal/service/eks/identity_provider_config.go index 4277bbc02cd..7c304b6399e 100644 --- a/internal/service/eks/identity_provider_config.go +++ b/internal/service/eks/identity_provider_config.go @@ -214,7 +214,7 @@ func resourceIdentityProviderConfigDelete(ctx context.Context, d *schema.Resourc ClusterName: aws.String(clusterName), IdentityProviderConfig: &types.IdentityProviderConfig{ Name: aws.String(configName), - Type: aws.String(IdentityProviderConfigTypeOIDC), + Type: aws.String(identityProviderConfigTypeOIDC), }, }) @@ -242,7 +242,7 @@ func findOIDCIdentityProviderConfigByTwoPartKey(ctx context.Context, conn *eks.C ClusterName: aws.String(clusterName), IdentityProviderConfig: &types.IdentityProviderConfig{ Name: aws.String(configName), - Type: aws.String(IdentityProviderConfigTypeOIDC), + Type: aws.String(identityProviderConfigTypeOIDC), }, } From 91fbcf6f95f76cc427ffc199c594c9efb0e86928 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Jan 2024 09:34:53 -0500 Subject: [PATCH 4/8] r/aws_eks_access_entry: Cosmetics. --- internal/service/eks/access_entry.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/internal/service/eks/access_entry.go b/internal/service/eks/access_entry.go index f0b421d8564..cdb69aaa12c 100644 --- a/internal/service/eks/access_entry.go +++ b/internal/service/eks/access_entry.go @@ -103,23 +103,22 @@ func resourceAccessEntryCreate(ctx context.Context, d *schema.ResourceData, meta clusterName := d.Get("cluster_name").(string) principalARN := d.Get("principal_arn").(string) - entryType := d.Get("type").(string) id := accessEntryCreateResourceID(clusterName, principalARN) input := &eks.CreateAccessEntryInput{ ClusterName: aws.String(clusterName), PrincipalArn: aws.String(principalARN), - Type: aws.String(entryType), Tags: getTagsIn(ctx), - } - - if v, ok := d.GetOk("user_name"); ok { - input.Username = aws.String(v.(string)) + Type: aws.String(d.Get("type").(string)), } if v, ok := d.GetOk("kubernetes_groups"); ok { input.KubernetesGroups = flex.ExpandStringValueSet(v.(*schema.Set)) } + if v, ok := d.GetOk("user_name"); ok { + input.Username = aws.String(v.(string)) + } + _, err := conn.CreateAccessEntry(ctx, input) if err != nil { @@ -181,14 +180,14 @@ func resourceAccessEntryUpdate(ctx context.Context, d *schema.ResourceData, meta PrincipalArn: aws.String(principalARN), } - if d.HasChange("user_name") { - input.Username = aws.String(d.Get("user_name").(string)) - } - if d.HasChange("kubernetes_groups") { input.KubernetesGroups = flex.ExpandStringValueSet(d.Get("kubernetes_groups").(*schema.Set)) } + if d.HasChange("user_name") { + input.Username = aws.String(d.Get("user_name").(string)) + } + _, err = conn.UpdateAccessEntry(ctx, input) if err != nil { From 14717dd291d64e9fd5dc6c08e2091a2505bc30ae Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Jan 2024 09:40:51 -0500 Subject: [PATCH 5/8] Add 'TestAccEKSAccessEntry_username'. --- internal/service/eks/access_entry_test.go | 62 ++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/internal/service/eks/access_entry_test.go b/internal/service/eks/access_entry_test.go index 3e9508733ae..14792fb16d7 100644 --- a/internal/service/eks/access_entry_test.go +++ b/internal/service/eks/access_entry_test.go @@ -47,7 +47,7 @@ func TestAccEKSAccessEntry_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "kubernetes_groups.#", "0"), acctest.CheckResourceAttrRFC3339(resourceName, "modified_at"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - resource.TestCheckResourceAttrSet(resourceName, "type"), + resource.TestCheckResourceAttr(resourceName, "type", "STANDARD"), resource.TestCheckResourceAttrSet(resourceName, "user_name"), ), }, @@ -176,6 +176,50 @@ func TestAccEKSAccessEntry_tags(t *testing.T) { }) } +func TestAccEKSAccessEntry_username(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_username(rName, "user1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAccessEntryExists(ctx, resourceName, &accessentry), + resource.TestCheckResourceAttr(resourceName, "type", "STANDARD"), + resource.TestCheckResourceAttr(resourceName, "user_name", "user1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAccessEntryConfig_username(rName, "user2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAccessEntryExists(ctx, resourceName, &accessentry), + resource.TestCheckResourceAttr(resourceName, "type", "STANDARD"), + resource.TestCheckResourceAttr(resourceName, "user_name", "user2"), + ), + }, + }, + }) +} + func testAccCheckAccessEntryDestroy(ctx context.Context) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).EKSClient(ctx) @@ -337,3 +381,19 @@ resource "aws_eks_access_entry" "test" { } `, rName, tagKey1, tagValue1, tagKey2, tagValue2)) } + +func testAccAccessEntryConfig_username(rName, username string) string { + return acctest.ConfigCompose(testAccAccessEntryConfig_base(rName), fmt.Sprintf(` +resource "aws_iam_user" "test" { + name = %[1]q +} + +resource "aws_eks_access_entry" "test" { + cluster_name = aws_eks_cluster.test.name + principal_arn = aws_iam_user.test.arn + + type = "EC2_LINUX" + user_name = %[2]q +} +`, rName, username)) +} From 4a635c988be75cd3b284c8156eaedb121accd5bc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Jan 2024 11:22:09 -0500 Subject: [PATCH 6/8] r/aws_eks_access_entry: 'type' must be 'STANDARD' to specify 'user_name'. --- internal/service/eks/access_entry_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/eks/access_entry_test.go b/internal/service/eks/access_entry_test.go index 14792fb16d7..b2494384252 100644 --- a/internal/service/eks/access_entry_test.go +++ b/internal/service/eks/access_entry_test.go @@ -392,7 +392,7 @@ resource "aws_eks_access_entry" "test" { cluster_name = aws_eks_cluster.test.name principal_arn = aws_iam_user.test.arn - type = "EC2_LINUX" + type = "STANDARD" user_name = %[2]q } `, rName, username)) From 6763564d114e301904aae0ff1ff9e4edfef12c76 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Jan 2024 11:24:39 -0500 Subject: [PATCH 7/8] Add 'TestAccEKSAccessEntry_type'. --- internal/service/eks/access_entry_test.go | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/internal/service/eks/access_entry_test.go b/internal/service/eks/access_entry_test.go index b2494384252..281644bcef4 100644 --- a/internal/service/eks/access_entry_test.go +++ b/internal/service/eks/access_entry_test.go @@ -176,6 +176,42 @@ func TestAccEKSAccessEntry_tags(t *testing.T) { }) } +func TestAccEKSAccessEntry_type(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_type(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAccessEntryExists(ctx, resourceName, &accessentry), + resource.TestCheckResourceAttr(resourceName, "type", "EC2_LINUX"), + resource.TestCheckResourceAttrSet(resourceName, "user_name"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccEKSAccessEntry_username(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { @@ -382,6 +418,36 @@ resource "aws_eks_access_entry" "test" { `, rName, tagKey1, tagValue1, tagKey2, tagValue2)) } +func testAccAccessEntryConfig_type(rName string) string { + return acctest.ConfigCompose(testAccAccessEntryConfig_base(rName), fmt.Sprintf(` +resource "aws_iam_role" "test2" { + name = "%[1]s-2" + + assume_role_policy = < Date: Fri, 19 Jan 2024 11:39:06 -0500 Subject: [PATCH 8/8] r/aws_eks_access_entry: Mark `kubernetes_groups` as Computed. --- .changelog/35391.txt | 4 ++++ internal/service/eks/access_entry.go | 1 + internal/service/eks/access_entry_test.go | 1 + 3 files changed, 6 insertions(+) diff --git a/.changelog/35391.txt b/.changelog/35391.txt index b8d59ea6aac..524a6a6fdc6 100644 --- a/.changelog/35391.txt +++ b/.changelog/35391.txt @@ -1,3 +1,7 @@ ```release-note:bug resource/aws_eks_access_entry: Mark `type` and `user_name` as Optional, allowing values to be configured ``` + +```release-note:bug +resource/aws_eks_access_entry: Mark `kubernetes_groups` as Computed +``` \ No newline at end of file diff --git a/internal/service/eks/access_entry.go b/internal/service/eks/access_entry.go index cdb69aaa12c..47c72204b37 100644 --- a/internal/service/eks/access_entry.go +++ b/internal/service/eks/access_entry.go @@ -65,6 +65,7 @@ func resourceAccessEntry() *schema.Resource { "kubernetes_groups": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, diff --git a/internal/service/eks/access_entry_test.go b/internal/service/eks/access_entry_test.go index 281644bcef4..f36bcd1f367 100644 --- a/internal/service/eks/access_entry_test.go +++ b/internal/service/eks/access_entry_test.go @@ -199,6 +199,7 @@ func TestAccEKSAccessEntry_type(t *testing.T) { Config: testAccAccessEntryConfig_type(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"), ),