diff --git a/aws/resource_aws_eks_addon.go b/aws/resource_aws_eks_addon.go index f628cc56115b..446cf4621990 100644 --- a/aws/resource_aws_eks_addon.go +++ b/aws/resource_aws_eks_addon.go @@ -29,6 +29,8 @@ func resourceAwsEksAddon() *schema.Resource { StateContext: schema.ImportStatePassthroughContext, }, + CustomizeDiff: SetTagsDiff, + Schema: map[string]*schema.Schema{ "addon_name": { Type: schema.TypeString, @@ -73,13 +75,16 @@ func resourceAwsEksAddon() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchemaComputed(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, } } func resourceAwsEksAddonCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*AWSClient).eksconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) clusterName := d.Get("cluster_name").(string) addonName := d.Get("addon_name").(string) @@ -102,8 +107,8 @@ func resourceAwsEksAddonCreate(ctx context.Context, d *schema.ResourceData, meta input.ServiceAccountRoleArn = aws.String(v.(string)) } - if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { - input.Tags = keyvaluetags.New(v).IgnoreAws().EksTags() + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().EksTags() } err := resource.RetryContext(ctx, 1*time.Minute, func() *resource.RetryError { @@ -148,6 +153,7 @@ func resourceAwsEksAddonCreate(ctx context.Context, d *schema.ResourceData, meta func resourceAwsEksAddonRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*AWSClient).eksconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig clusterName, addonName, err := resourceAwsEksAddonParseId(d.Id()) @@ -186,8 +192,15 @@ func resourceAwsEksAddonRead(ctx context.Context, d *schema.ResourceData, meta i d.Set("created_at", aws.TimeValue(addon.CreatedAt).Format(time.RFC3339)) d.Set("modified_at", aws.TimeValue(addon.ModifiedAt).Format(time.RFC3339)) - if err := d.Set("tags", keyvaluetags.EksKeyValueTags(addon.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { - return diag.FromErr(fmt.Errorf("error setting tags attribute: %w", err)) + tags := keyvaluetags.EksKeyValueTags(addon.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return diag.FromErr(fmt.Errorf("error setting tags: %w", err)) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return diag.FromErr(fmt.Errorf("error setting tags_all: %w", err)) } return nil @@ -217,8 +230,8 @@ func resourceAwsEksAddonUpdate(ctx context.Context, d *schema.ResourceData, meta input.ResolveConflicts = aws.String(v.(string)) } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.EksUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { return diag.FromErr(fmt.Errorf("error updating tags: %w", err)) } diff --git a/aws/resource_aws_eks_addon_test.go b/aws/resource_aws_eks_addon_test.go index b4e5593bd2e3..ce403ac430b9 100644 --- a/aws/resource_aws_eks_addon_test.go +++ b/aws/resource_aws_eks_addon_test.go @@ -14,7 +14,9 @@ import ( "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/eks/waiter" ) @@ -319,6 +321,397 @@ func TestAccAWSEksAddon_Tags(t *testing.T) { }) } +func TestAccAWSEksAddon_defaultTags_providerOnly(t *testing.T) { + var providers []*schema.Provider + var addon eks.Addon + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_addon.test" + addonName := "vpc-cni" + ctx := context.TODO() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: testAccCheckAWSEksAddonDestroy, + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("providerkey1", "providervalue1"), + testAccAWSEksAddon_Basic(rName, addonName), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.providerkey1", "providervalue1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags2("providerkey1", "providervalue1", "providerkey2", "providervalue2"), + testAccAWSEksAddon_Basic(rName, addonName), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags_all.providerkey1", "providervalue1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.providerkey2", "providervalue2"), + ), + }, + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("providerkey1", "value1"), + testAccAWSEksAddon_Basic(rName, addonName), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.providerkey1", "value1"), + ), + }, + }, + }) +} + +func TestAccAWSEksAddon_defaultTags_updateToProviderOnly(t *testing.T) { + var providers []*schema.Provider + var addon eks.Addon + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_addon.test" + addonName := "vpc-cni" + ctx := context.TODO() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: testAccCheckAWSEksAddonDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.key1", "value1"), + ), + }, + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("key1", "value1"), + testAccAWSEksAddon_Basic(rName, addonName), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSEksAddon_defaultTags_updateToResourceOnly(t *testing.T) { + var providers []*schema.Provider + var addon eks.Addon + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_addon.test" + addonName := "vpc-cni" + ctx := context.TODO() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: testAccCheckAWSEksAddonDestroy, + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("key1", "value1"), + testAccAWSEksAddon_Basic(rName, addonName), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.key1", "value1"), + ), + }, + { + Config: testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSEksAddon_defaultTags_providerAndResource_nonOverlappingTag(t *testing.T) { + var providers []*schema.Provider + var addon eks.Addon + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_addon.test" + addonName := "vpc-cni" + ctx := context.TODO() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: testAccCheckAWSEksAddonDestroy, + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("providerkey1", "providervalue1"), + testAccAWSEksAddonConfigTags1(rName, addonName, "resourcekey1", "resourcevalue1"), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.resourcekey1", "resourcevalue1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.providerkey1", "providervalue1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.resourcekey1", "resourcevalue1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("providerkey1", "providervalue1"), + testAccAWSEksAddonConfigTags2(rName, addonName, "resourcekey1", "resourcevalue1", "resourcekey2", "resourcevalue2"), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "3"), + resource.TestCheckResourceAttr(resourceName, "tags.resourcekey1", "resourcevalue1"), + resource.TestCheckResourceAttr(resourceName, "tags.resourcekey2", "resourcevalue2"), + resource.TestCheckResourceAttr(resourceName, "tags_all.providerkey1", "providervalue1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.resourcekey1", "resourcevalue1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.resourcekey2", "resourcevalue2"), + ), + }, + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("providerkey2", "providervalue2"), + testAccAWSEksAddonConfigTags1(rName, addonName, "resourcekey3", "resourcevalue3"), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.resourcekey3", "resourcevalue3"), + resource.TestCheckResourceAttr(resourceName, "tags_all.providerkey2", "providervalue2"), + resource.TestCheckResourceAttr(resourceName, "tags_all.resourcekey3", "resourcevalue3"), + ), + }, + }, + }) +} + +func TestAccAWSEksAddon_defaultTags_providerAndResource_overlappingTag(t *testing.T) { + var providers []*schema.Provider + var addon eks.Addon + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_addon.test" + addonName := "vpc-cni" + ctx := context.TODO() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: testAccCheckAWSEksAddonDestroy, + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("overlapkey1", "providervalue1"), + testAccAWSEksAddonConfigTags1(rName, addonName, "overlapkey1", "resourcevalue1"), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.overlapkey1", "resourcevalue1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags2("overlapkey1", "providervalue1", "overlapkey2", "providervalue2"), + testAccAWSEksAddonConfigTags2(rName, addonName, "overlapkey1", "resourcevalue1", "overlapkey2", "resourcevalue2"), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.overlapkey1", "resourcevalue1"), + resource.TestCheckResourceAttr(resourceName, "tags.overlapkey2", "resourcevalue2"), + resource.TestCheckResourceAttr(resourceName, "tags_all.overlapkey1", "resourcevalue1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.overlapkey2", "resourcevalue2"), + ), + }, + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("overlapkey1", "providervalue1"), + testAccAWSEksAddonConfigTags1(rName, addonName, "overlapkey1", "resourcevalue2"), + ), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags_all.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.overlapkey1", "resourcevalue2"), + resource.TestCheckResourceAttr(resourceName, "tags_all.overlapkey1", "resourcevalue2"), + ), + }, + }, + }) +} + +func TestAccAWSEksAddon_defaultTags_providerAndResource_duplicateTag(t *testing.T) { + var providers []*schema.Provider + + rName := acctest.RandomWithPrefix("tf-acc-test") + addonName := "vpc-cni" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: composeConfig( + testAccAWSProviderConfigDefaultTags_Tags1("overlapkey", "overlapvalue"), + testAccAWSEksAddonConfigTags1(rName, addonName, "overlapkey", "overlapvalue"), + ), + PlanOnly: true, + ExpectError: regexp.MustCompile(`"tags" are identical to those in the "default_tags" configuration block`), + }, + }, + }) +} + +func TestAccAWSEksAddon_defaultAndIgnoreTags(t *testing.T) { + var providers []*schema.Provider + var addon eks.Addon + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_addon.test" + addonName := "vpc-cni" + ctx := context.TODO() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: testAccCheckAWSEksAddonDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + testAccCheckEksAddonUpdateTags(&addon, nil, map[string]string{"defaultkey1": "defaultvalue1"}), + ), + ExpectNonEmptyPlan: true, + }, + { + Config: composeConfig( + testAccProviderConfigDefaultAndIgnoreTagsKeyPrefixes1("defaultkey1", "defaultvalue1", "defaultkey"), + testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + ), + PlanOnly: true, + }, + { + Config: composeConfig( + testAccProviderConfigDefaultAndIgnoreTagsKeys1("defaultkey1", "defaultvalue1"), + testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + ), + PlanOnly: true, + }, + }, + }) +} + +func TestAccAWSEksAddon_ignoreTags(t *testing.T) { + var providers []*schema.Provider + var addon eks.Addon + + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_eks_addon.test" + addonName := "vpc-cni" + ctx := context.TODO() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, eks.EndpointsID), + ProviderFactories: testAccProviderFactoriesInternal(&providers), + CheckDestroy: testAccCheckAWSEksAddonDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEksAddonExists(ctx, resourceName, &addon), + testAccCheckEksAddonUpdateTags(&addon, nil, map[string]string{"ignorekey1": "ignorevalue1"}), + ), + ExpectNonEmptyPlan: true, + }, + { + Config: composeConfig( + testAccProviderConfigIgnoreTagsKeyPrefixes1("ignorekey"), + testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + ), + PlanOnly: true, + }, + { + Config: composeConfig( + testAccProviderConfigIgnoreTagsKeys1("ignorekey1"), + testAccAWSEksAddonConfigTags1(rName, addonName, "key1", "value1"), + ), + PlanOnly: true, + }, + }, + }) +} + func testAccCheckAWSEksAddonExists(ctx context.Context, resourceName string, addon *eks.Addon) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] @@ -348,13 +741,13 @@ func testAccCheckAWSEksAddonExists(ctx context.Context, resourceName string, add return fmt.Errorf("EKS Addon (%s) not found", rs.Primary.ID) } - // if aws.StringValue(output.Addon.AddonName) != addonName { - // return fmt.Errorf("EKS Addon (%s) not found", rs.Primary.ID) - // } + if aws.StringValue(output.Addon.AddonName) != addonName { + return fmt.Errorf("EKS Addon (%s) not found", rs.Primary.ID) + } - // if aws.StringValue(output.Addon.ClusterName) != clusterName { - // return fmt.Errorf("EKS Addon (%s) not found", rs.Primary.ID) - // } + if aws.StringValue(output.Addon.ClusterName) != clusterName { + return fmt.Errorf("EKS Addon (%s) not found", rs.Primary.ID) + } *addon = *output.Addon @@ -441,6 +834,14 @@ func testAccPreCheckAWSEksAddon(t *testing.T) { } } +func testAccCheckEksAddonUpdateTags(addon *eks.Addon, oldTags, newTags map[string]string) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).eksconn + + return keyvaluetags.EksUpdateTags(conn, aws.StringValue(addon.AddonArn), oldTags, newTags) + } +} + func testAccAWSEksAddonConfig_Base(rName string) string { return fmt.Sprintf(` data "aws_availability_zones" "available" { diff --git a/website/docs/r/eks_addon.html.markdown b/website/docs/r/eks_addon.html.markdown index 07707af69b35..83c2d20eb972 100644 --- a/website/docs/r/eks_addon.html.markdown +++ b/website/docs/r/eks_addon.html.markdown @@ -85,7 +85,7 @@ The following arguments are optional: * `resolve_conflicts` - (Optional) Define how to resolve parameter value conflicts when migrating an existing add-on to an Amazon EKS add-on or when applying version updates to the add-on. Valid values are `NONE` and `OVERWRITE`. -* `tags` - (Optional) Key-value map of resource tags. +* `tags` - (Optional) Key-value map of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `service_account_role_arn` - (Optional) The Amazon Resource Name (ARN) of an existing IAM role to bind to the add-on's service account. The role must be assigned the IAM permissions required by the add-on. If you don't specify @@ -107,6 +107,7 @@ In addition to all arguments above, the following attributes are exported: * `status` - Status of the EKS add-on. * `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. +* `tags_all` - (Optional) Key-value map of resource tags, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import