diff --git a/.changelog/36383.txt b/.changelog/36383.txt new file mode 100644 index 00000000000..f1474cb2b42 --- /dev/null +++ b/.changelog/36383.txt @@ -0,0 +1,3 @@ +```release-note:bug +data-source/aws_iam_policy_document: Fix `Failed to marshal state to json: unsupported attribute "override_json"` and `Failed to marshal state to json: unsupported attribute "source_json"` errors when running `terraform show -json` or `terraform state rm` +``` \ No newline at end of file diff --git a/internal/service/iam/access_key.go b/internal/service/iam/access_key.go index d79ef18dac6..9238c4cb845 100644 --- a/internal/service/iam/access_key.go +++ b/internal/service/iam/access_key.go @@ -14,16 +14,19 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/iam" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "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/sdkdiag" + tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_iam_access_key") -func ResourceAccessKey() *schema.Resource { +// @SDKResource("aws_iam_access_key", name="Access Key") +func resourceAccessKey() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceAccessKeyCreate, ReadWithoutTimeout: resourceAccessKeyRead, @@ -187,8 +190,8 @@ func resourceAccessKeyRead(ctx context.Context, d *schema.ResourceData, meta int conn := meta.(*conns.AWSClient).IAMConn(ctx) username := d.Get("user").(string) + key, err := findAccessKeyByTwoPartKey(ctx, conn, username, d.Id()) - key, err := FindAccessKey(ctx, conn, username, d.Id()) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] IAM Access Key (%s) for User (%s) not found, removing from state", d.Id(), username) d.SetId("") @@ -242,14 +245,20 @@ func resourceAccessKeyDelete(ctx context.Context, d *schema.ResourceData, meta i var diags diag.Diagnostics conn := meta.(*conns.AWSClient).IAMConn(ctx) - request := &iam.DeleteAccessKeyInput{ + log.Printf("[DEBUG] Deleting IAM Access Key: %s", d.Id()) + _, err := conn.DeleteAccessKeyWithContext(ctx, &iam.DeleteAccessKeyInput{ AccessKeyId: aws.String(d.Id()), UserName: aws.String(d.Get("user").(string)), + }) + + if tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) { + return diags } - if _, err := conn.DeleteAccessKeyWithContext(ctx, request); err != nil { + if err != nil { return sdkdiag.AppendErrorf(diags, "deleting IAM Access Key (%s): %s", d.Id(), err) } + return diags } @@ -264,6 +273,61 @@ func resourceAccessKeyStatusUpdate(ctx context.Context, conn *iam.IAM, d *schema return err } +func findAccessKeyByTwoPartKey(ctx context.Context, conn *iam.IAM, username, id string) (*iam.AccessKeyMetadata, error) { + input := &iam.ListAccessKeysInput{ + UserName: aws.String(username), + } + + return findAccessKey(ctx, conn, input, func(v *iam.AccessKeyMetadata) bool { + return aws.StringValue(v.AccessKeyId) == id + }) +} + +func findAccessKeysByUser(ctx context.Context, conn *iam.IAM, username string) ([]*iam.AccessKeyMetadata, error) { + input := &iam.ListAccessKeysInput{ + UserName: aws.String(username), + } + + return findAccessKeys(ctx, conn, input, tfslices.PredicateTrue[*iam.AccessKeyMetadata]()) +} + +func findAccessKey(ctx context.Context, conn *iam.IAM, input *iam.ListAccessKeysInput, filter tfslices.Predicate[*iam.AccessKeyMetadata]) (*iam.AccessKeyMetadata, error) { + output, err := findAccessKeys(ctx, conn, input, filter) + + if err != nil { + return nil, err + } + + return tfresource.AssertSinglePtrResult(output) +} + +func findAccessKeys(ctx context.Context, conn *iam.IAM, input *iam.ListAccessKeysInput, filter tfslices.Predicate[*iam.AccessKeyMetadata]) ([]*iam.AccessKeyMetadata, error) { + var output []*iam.AccessKeyMetadata + + err := conn.ListAccessKeysPagesWithContext(ctx, input, func(page *iam.ListAccessKeysOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.AccessKeyMetadata { + if v != nil && filter(v) { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + return output, err +} + func hmacSignature(key []byte, value []byte) ([]byte, error) { h := hmac.New(sha256.New, key) if _, err := h.Write(value); err != nil { diff --git a/internal/service/iam/access_key_test.go b/internal/service/iam/access_key_test.go index 7efb291d798..b27be71e75b 100644 --- a/internal/service/iam/access_key_test.go +++ b/internal/service/iam/access_key_test.go @@ -58,6 +58,30 @@ func TestAccIAMAccessKey_basic(t *testing.T) { }) } +func TestAccIAMAccessKey_disappears(t *testing.T) { + ctx := acctest.Context(t) + var conf iam.AccessKeyMetadata + resourceName := "aws_iam_access_key.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.IAMServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAccessKeyDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAccessKeyConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAccessKeyExists(ctx, resourceName, &conf), + acctest.CheckResourceDisappears(ctx, acctest.Provider, tfiam.ResourceAccessKey(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func TestAccIAMAccessKey_encrypted(t *testing.T) { ctx := acctest.Context(t) var conf iam.AccessKeyMetadata @@ -145,13 +169,16 @@ func testAccCheckAccessKeyDestroy(ctx context.Context) resource.TestCheckFunc { continue } - _, err := tfiam.FindAccessKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID) + _, err := tfiam.FindAccessKeyByTwoPartKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID) + if tfresource.NotFound(err) { return nil } + if err != nil { return err } + return fmt.Errorf("IAM Access Key (%s) still exists", rs.Primary.ID) } @@ -159,25 +186,22 @@ func testAccCheckAccessKeyDestroy(ctx context.Context) resource.TestCheckFunc { } } -func testAccCheckAccessKeyExists(ctx context.Context, n string, res *iam.AccessKeyMetadata) resource.TestCheckFunc { +func testAccCheckAccessKeyExists(ctx context.Context, n string, v *iam.AccessKeyMetadata) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { return fmt.Errorf("Not found: %s", n) } - if rs.Primary.ID == "" { - return fmt.Errorf("No Access Key ID is set") - } - conn := acctest.Provider.Meta().(*conns.AWSClient).IAMConn(ctx) - accessKey, err := tfiam.FindAccessKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID) + output, err := tfiam.FindAccessKeyByTwoPartKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID) + if err != nil { return err } - *res = *accessKey + *v = *output return nil } diff --git a/internal/service/iam/access_keys_data_source.go b/internal/service/iam/access_keys_data_source.go index 3652163d805..da5d826007f 100644 --- a/internal/service/iam/access_keys_data_source.go +++ b/internal/service/iam/access_keys_data_source.go @@ -12,12 +12,11 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" - "github.com/hashicorp/terraform-provider-aws/internal/create" - "github.com/hashicorp/terraform-provider-aws/names" + "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_access_keys") -func DataSourceAccessKeys() *schema.Resource { +// @SDKDataSource("aws_iam_access_keys", name="Access Keys") +func dataSourceAccessKeys() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceAccessKeysRead, Schema: map[string]*schema.Schema{ @@ -49,26 +48,21 @@ func DataSourceAccessKeys() *schema.Resource { } } -const ( - DSNameAccessKeys = "Access Keys Data Source" -) - func dataSourceAccessKeysRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { var diags diag.Diagnostics conn := meta.(*conns.AWSClient).IAMConn(ctx) username := d.Get("user").(string) - out, err := FindAccessKeys(ctx, conn, username) + output, err := findAccessKeysByUser(ctx, conn, username) if err != nil { - return create.AppendDiagError(diags, names.IAM, create.ErrActionReading, DSNameAccessKeys, username, err) + return sdkdiag.AppendErrorf(diags, "reading IAM Access Keys (%s): %s", username, err) } d.SetId(username) - - if err := d.Set("access_keys", flattenAccessKeys(out)); err != nil { - return create.AppendDiagError(diags, names.IAM, create.ErrActionSetting, DSNameAccessKeys, d.Id(), err) + if err := d.Set("access_keys", flattenAccessKeys(output)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting access_keys: %s", err) } return diags diff --git a/internal/service/iam/account_alias.go b/internal/service/iam/account_alias.go index de591236fa6..564f24b1051 100644 --- a/internal/service/iam/account_alias.go +++ b/internal/service/iam/account_alias.go @@ -14,8 +14,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKResource("aws_iam_account_alias") -func ResourceAccountAlias() *schema.Resource { +// @SDKResource("aws_iam_account_alias", name="Account Alias") +func resourceAccountAlias() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceAccountAliasCreate, ReadWithoutTimeout: resourceAccountAliasRead, diff --git a/internal/service/iam/account_alias_data_source.go b/internal/service/iam/account_alias_data_source.go index 413079f0491..6838f335b3b 100644 --- a/internal/service/iam/account_alias_data_source.go +++ b/internal/service/iam/account_alias_data_source.go @@ -15,8 +15,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_account_alias") -func DataSourceAccountAlias() *schema.Resource { +// @SDKDataSource("aws_iam_account_alias", name="Account Alias") +func dataSourceAccountAlias() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceAccountAliasRead, diff --git a/internal/service/iam/exports_test.go b/internal/service/iam/exports_test.go index 9887ca21493..47be0c257fa 100644 --- a/internal/service/iam/exports_test.go +++ b/internal/service/iam/exports_test.go @@ -5,23 +5,33 @@ package iam // Exports for use in tests only. var ( + ResourceAccessKey = resourceAccessKey + // ResourceAccountAlias = resourceAccountAlias ResourceAccountPasswordPolicy = resourceAccountPasswordPolicy ResourceGroup = resourceGroup - ResourceGroupPolicyAttachment = resourceGroupPolicyAttachment - ResourceInstanceProfile = resourceInstanceProfile - ResourceOpenIDConnectProvider = resourceOpenIDConnectProvider - ResourcePolicy = resourcePolicy - ResourcePolicyAttachment = resourcePolicyAttachment - ResourceRolePolicyAttachment = resourceRolePolicyAttachment - ResourceSAMLProvider = resourceSAMLProvider - ResourceServerCertificate = resourceServerCertificate - ResourceServiceLinkedRole = resourceServiceLinkedRole - ResourceUser = resourceUser - ResourceUserLoginProfile = resourceUserLoginProfile - ResourceUserPolicyAttachment = resourceUserPolicyAttachment - ResourceUserSSHKey = resourceUserSSHKey - ResourceVirtualMFADevice = resourceVirtualMFADevice + // ResourceGroupMembership = resourceGroupMembership + ResourceGroupPolicy = resourceGroupPolicy + ResourceGroupPolicyAttachment = resourceGroupPolicyAttachment + ResourceInstanceProfile = resourceInstanceProfile + ResourceOpenIDConnectProvider = resourceOpenIDConnectProvider + ResourcePolicy = resourcePolicy + ResourcePolicyAttachment = resourcePolicyAttachment + ResourceRolePolicy = resourceRolePolicy + ResourceRolePolicyAttachment = resourceRolePolicyAttachment + ResourceSAMLProvider = resourceSAMLProvider + ResourceServerCertificate = resourceServerCertificate + ResourceServiceLinkedRole = resourceServiceLinkedRole + ResourceServiceSpecificCredential = resourceServiceSpecificCredential + ResourceSigningCertificate = resourceSigningCertificate + ResourceUser = resourceUser + ResourceUserGroupMembership = resourceUserGroupMembership + ResourceUserLoginProfile = resourceUserLoginProfile + ResourceUserPolicy = resourceUserPolicy + ResourceUserPolicyAttachment = resourceUserPolicyAttachment + ResourceUserSSHKey = resourceUserSSHKey + ResourceVirtualMFADevice = resourceVirtualMFADevice + FindAccessKeyByTwoPartKey = findAccessKeyByTwoPartKey FindAccountPasswordPolicy = findAccountPasswordPolicy FindAttachedGroupPolicies = findAttachedGroupPolicies FindAttachedGroupPolicyByTwoPartKey = findAttachedGroupPolicyByTwoPartKey diff --git a/internal/service/iam/find.go b/internal/service/iam/find.go index b84b59a7a6d..0cb18c2d4b3 100644 --- a/internal/service/iam/find.go +++ b/internal/service/iam/find.go @@ -125,44 +125,3 @@ func FindSigningCertificate(ctx context.Context, conn *iam.IAM, userName, certId return cert, nil } - -func FindAccessKey(ctx context.Context, conn *iam.IAM, username, id string) (*iam.AccessKeyMetadata, error) { - accessKeys, err := FindAccessKeys(ctx, conn, username) - if err != nil { - return nil, err - } - - for _, accessKey := range accessKeys { - if aws.StringValue(accessKey.AccessKeyId) == id { - return accessKey, nil - } - } - - return nil, &retry.NotFoundError{} -} - -func FindAccessKeys(ctx context.Context, conn *iam.IAM, username string) ([]*iam.AccessKeyMetadata, error) { - input := &iam.ListAccessKeysInput{ - UserName: aws.String(username), - } - var output []*iam.AccessKeyMetadata - - err := conn.ListAccessKeysPagesWithContext(ctx, input, func(page *iam.ListAccessKeysOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - output = append(output, page.AccessKeyMetadata...) - - return !lastPage - }) - - if tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: input, - } - } - - return output, err -} diff --git a/internal/service/iam/group_data_source.go b/internal/service/iam/group_data_source.go index c1f3d94bb06..dfb299dd61d 100644 --- a/internal/service/iam/group_data_source.go +++ b/internal/service/iam/group_data_source.go @@ -15,8 +15,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_group") -func DataSourceGroup() *schema.Resource { +// @SDKDataSource("aws_iam_group", name="Group") +func dataSourceGroup() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceGroupRead, diff --git a/internal/service/iam/group_membership.go b/internal/service/iam/group_membership.go index ee29f6f3f47..546e1c96f96 100644 --- a/internal/service/iam/group_membership.go +++ b/internal/service/iam/group_membership.go @@ -19,8 +19,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_iam_group_membership") -func ResourceGroupMembership() *schema.Resource { +// @SDKResource("aws_iam_group_membership", name="Group Membership") +func resourceGroupMembership() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceGroupMembershipCreate, ReadWithoutTimeout: resourceGroupMembershipRead, diff --git a/internal/service/iam/group_policy.go b/internal/service/iam/group_policy.go index 4e31f9ab7bd..0451af8451f 100644 --- a/internal/service/iam/group_policy.go +++ b/internal/service/iam/group_policy.go @@ -23,8 +23,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKResource("aws_iam_group_policy") -func ResourceGroupPolicy() *schema.Resource { +// @SDKResource("aws_iam_group_policy", name="Group Policy") +func resourceGroupPolicy() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceGroupPolicyPut, ReadWithoutTimeout: resourceGroupPolicyRead, diff --git a/internal/service/iam/instance_profile_data_source.go b/internal/service/iam/instance_profile_data_source.go index 79df1cb0dd7..6ae5c006dae 100644 --- a/internal/service/iam/instance_profile_data_source.go +++ b/internal/service/iam/instance_profile_data_source.go @@ -14,8 +14,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_instance_profile") -func DataSourceInstanceProfile() *schema.Resource { +// @SDKDataSource("aws_iam_instance_profile", name="Instance Profile") +func dataSourceInstanceProfile() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceInstanceProfileRead, diff --git a/internal/service/iam/instance_profiles_data_source.go b/internal/service/iam/instance_profiles_data_source.go index a0661717672..ac9ccb958ad 100644 --- a/internal/service/iam/instance_profiles_data_source.go +++ b/internal/service/iam/instance_profiles_data_source.go @@ -16,8 +16,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_instance_profiles") -func DataSourceInstanceProfiles() *schema.Resource { +// @SDKDataSource("aws_iam_instance_profiles", name="Instance Profiles") +func dataSourceInstanceProfiles() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceInstanceProfilesRead, diff --git a/internal/service/iam/openid_connect_provider_data_source.go b/internal/service/iam/openid_connect_provider_data_source.go index 9acf76ac67f..c2f5aa598aa 100644 --- a/internal/service/iam/openid_connect_provider_data_source.go +++ b/internal/service/iam/openid_connect_provider_data_source.go @@ -19,8 +19,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKDataSource("aws_iam_openid_connect_provider") -func DataSourceOpenIDConnectProvider() *schema.Resource { +// @SDKDataSource("aws_iam_openid_connect_provider", name="OIDC Provider") +func dataSourceOpenIDConnectProvider() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceOpenIDConnectProviderRead, diff --git a/internal/service/iam/policy_data_source.go b/internal/service/iam/policy_data_source.go index dbc8644dc9d..613e19d92f1 100644 --- a/internal/service/iam/policy_data_source.go +++ b/internal/service/iam/policy_data_source.go @@ -18,8 +18,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKDataSource("aws_iam_policy") -func DataSourcePolicy() *schema.Resource { +// @SDKDataSource("aws_iam_policy", name="Policy") +func dataSourcePolicy() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourcePolicyRead, diff --git a/internal/service/iam/policy_document_data_source.go b/internal/service/iam/policy_document_data_source.go index 0797c79fc2b..6df1e3cc974 100644 --- a/internal/service/iam/policy_document_data_source.go +++ b/internal/service/iam/policy_document_data_source.go @@ -21,100 +21,139 @@ import ( var dataSourcePolicyDocumentVarReplacer = strings.NewReplacer("&{", "${") -// @SDKDataSource("aws_iam_policy_document") -func DataSourcePolicyDocument() *schema.Resource { - setOfString := &schema.Schema{ - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - } - +// @SDKDataSource("aws_iam_policy_document", name="Policy Document") +func dataSourcePolicyDocument() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourcePolicyDocumentRead, - Schema: map[string]*schema.Schema{ - "json": { - Type: schema.TypeString, - Computed: true, - }, - "override_policy_documents": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ + SchemaFunc: func() map[string]*schema.Schema { + principalsSchema := func() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "identifiers": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "type": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + } + } + setOfStringSchema := func() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + } + } + + return map[string]*schema.Schema{ + "json": { + Type: schema.TypeString, + Computed: true, + }, + // https://github.com/hashicorp/terraform-provider-aws/issues/31637. + "override_json": { Type: schema.TypeString, - ValidateFunc: validation.StringIsJSON, + Optional: true, + ValidateFunc: validation.StringIsEmpty, + Deprecated: "Not used", + }, + "override_policy_documents": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringIsJSON, + }, + }, + "policy_id": { + Type: schema.TypeString, + Optional: true, }, - }, - "policy_id": { - Type: schema.TypeString, - Optional: true, - }, - "source_policy_documents": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ + // https://github.com/hashicorp/terraform-provider-aws/issues/31637. + "source_json": { Type: schema.TypeString, - ValidateFunc: validation.StringIsJSON, + Optional: true, + ValidateFunc: validation.StringIsEmpty, + Deprecated: "Not used", }, - }, - "statement": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "actions": setOfString, - "condition": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "test": { - Type: schema.TypeString, - Required: true, - }, - "values": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Schema{ - Type: schema.TypeString, + "source_policy_documents": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringIsJSON, + }, + }, + "statement": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actions": setOfStringSchema(), + "condition": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "test": { + Type: schema.TypeString, + Required: true, + }, + "values": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "variable": { + Type: schema.TypeString, + Required: true, }, - }, - "variable": { - Type: schema.TypeString, - Required: true, }, }, }, - }, - "effect": { - Type: schema.TypeString, - Optional: true, - Default: "Allow", - ValidateFunc: validation.StringInSlice([]string{"Allow", "Deny"}, false), - }, - "not_actions": setOfString, - "not_principals": dataSourcePolicyPrincipalSchema(), - "not_resources": setOfString, - "principals": dataSourcePolicyPrincipalSchema(), - "resources": setOfString, - "sid": { - Type: schema.TypeString, - Optional: true, + "effect": { + Type: schema.TypeString, + Optional: true, + Default: "Allow", + ValidateFunc: validation.StringInSlice([]string{"Allow", "Deny"}, false), + }, + "not_actions": setOfStringSchema(), + "not_principals": principalsSchema(), + "not_resources": setOfStringSchema(), + "principals": principalsSchema(), + "resources": setOfStringSchema(), + "sid": { + Type: schema.TypeString, + Optional: true, + }, }, }, }, - }, - "version": { - Type: schema.TypeString, - Optional: true, - Default: "2012-10-17", - ValidateFunc: validation.StringInSlice([]string{ - "2008-10-17", - "2012-10-17", - }, false), - }, + "version": { + Type: schema.TypeString, + Optional: true, + Default: "2012-10-17", + ValidateFunc: validation.StringInSlice([]string{ + "2008-10-17", + "2012-10-17", + }, false), + }, + } }, } } @@ -338,25 +377,3 @@ func dataSourcePolicyDocumentMakePrincipals(in []interface{}, version string) (I } return IAMPolicyStatementPrincipalSet(out), nil } - -func dataSourcePolicyPrincipalSchema() *schema.Schema { - return &schema.Schema{ - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - }, - "identifiers": { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - }, - } -} diff --git a/internal/service/iam/principal_policy_simulation_data_source.go b/internal/service/iam/principal_policy_simulation_data_source.go index dbdd14d958f..9f199b0b80d 100644 --- a/internal/service/iam/principal_policy_simulation_data_source.go +++ b/internal/service/iam/principal_policy_simulation_data_source.go @@ -17,8 +17,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKDataSource("aws_iam_principal_policy_simulation") -func DataSourcePrincipalPolicySimulation() *schema.Resource { +// @SDKDataSource("aws_iam_principal_policy_simulation", name="Principal Policy Simulation") +func dataSourcePrincipalPolicySimulation() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourcePrincipalPolicySimulationRead, diff --git a/internal/service/iam/role_data_source.go b/internal/service/iam/role_data_source.go index 18468e722ff..2345b10c5e9 100644 --- a/internal/service/iam/role_data_source.go +++ b/internal/service/iam/role_data_source.go @@ -17,8 +17,8 @@ import ( tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" ) -// @SDKDataSource("aws_iam_role") -func DataSourceRole() *schema.Resource { +// @SDKDataSource("aws_iam_role", name="Role") +func dataSourceRole() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceRoleRead, diff --git a/internal/service/iam/role_policy.go b/internal/service/iam/role_policy.go index 42673b28e92..ff7708a10f6 100644 --- a/internal/service/iam/role_policy.go +++ b/internal/service/iam/role_policy.go @@ -29,8 +29,8 @@ const ( rolePolicyNamePrefixMaxLen = rolePolicyNameMaxLen - id.UniqueIDSuffixLength ) -// @SDKResource("aws_iam_role_policy") -func ResourceRolePolicy() *schema.Resource { +// @SDKResource("aws_iam_role_policy", name="Role Policy") +func resourceRolePolicy() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceRolePolicyPut, ReadWithoutTimeout: resourceRolePolicyRead, diff --git a/internal/service/iam/roles_data_source.go b/internal/service/iam/roles_data_source.go index a8e08a8c623..1734c5610e5 100644 --- a/internal/service/iam/roles_data_source.go +++ b/internal/service/iam/roles_data_source.go @@ -16,8 +16,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_roles") -func DataSourceRoles() *schema.Resource { +// @SDKDataSource("aws_iam_roles", name="Roles") +func dataSourceRoles() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceRolesRead, diff --git a/internal/service/iam/saml_provider_data_source.go b/internal/service/iam/saml_provider_data_source.go index cb428aedbc7..0cb4cfbfb47 100644 --- a/internal/service/iam/saml_provider_data_source.go +++ b/internal/service/iam/saml_provider_data_source.go @@ -16,8 +16,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKDataSource("aws_iam_saml_provider") -func DataSourceSAMLProvider() *schema.Resource { +// @SDKDataSource("aws_iam_saml_provider", name="SAML Provider") +func dataSourceSAMLProvider() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceSAMLProviderRead, diff --git a/internal/service/iam/security_token_service_preferences.go b/internal/service/iam/security_token_service_preferences.go index ec93e81ab1d..fc70c181769 100644 --- a/internal/service/iam/security_token_service_preferences.go +++ b/internal/service/iam/security_token_service_preferences.go @@ -17,7 +17,7 @@ import ( ) // @SDKResource("aws_iam_security_token_service_preferences", name="Security Token Service Preferences") -func ResourceSecurityTokenServicePreferences() *schema.Resource { +func resourceSecurityTokenServicePreferences() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceSecurityTokenServicePreferencesUpsert, ReadWithoutTimeout: resourceSecurityTokenServicePreferencesRead, diff --git a/internal/service/iam/server_certificate_data_source.go b/internal/service/iam/server_certificate_data_source.go index 1387821a64f..430f8f64863 100644 --- a/internal/service/iam/server_certificate_data_source.go +++ b/internal/service/iam/server_certificate_data_source.go @@ -20,8 +20,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_server_certificate") -func DataSourceServerCertificate() *schema.Resource { +// @SDKDataSource("aws_iam_server_certificate", name="Server Certificate") +func dataSourceServerCertificate() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceServerCertificateRead, diff --git a/internal/service/iam/service_package_gen.go b/internal/service/iam/service_package_gen.go index 0b895157f61..a4f3b63e720 100644 --- a/internal/service/iam/service_package_gen.go +++ b/internal/service/iam/service_package_gen.go @@ -26,72 +26,89 @@ func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.Servic func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePackageSDKDataSource { return []*types.ServicePackageSDKDataSource{ { - Factory: DataSourceAccessKeys, + Factory: dataSourceAccessKeys, TypeName: "aws_iam_access_keys", + Name: "Access Keys", }, { - Factory: DataSourceAccountAlias, + Factory: dataSourceAccountAlias, TypeName: "aws_iam_account_alias", + Name: "Account Alias", }, { - Factory: DataSourceGroup, + Factory: dataSourceGroup, TypeName: "aws_iam_group", + Name: "Group", }, { - Factory: DataSourceInstanceProfile, + Factory: dataSourceInstanceProfile, TypeName: "aws_iam_instance_profile", + Name: "Instance Profile", }, { - Factory: DataSourceInstanceProfiles, + Factory: dataSourceInstanceProfiles, TypeName: "aws_iam_instance_profiles", + Name: "Instance Profiles", }, { - Factory: DataSourceOpenIDConnectProvider, + Factory: dataSourceOpenIDConnectProvider, TypeName: "aws_iam_openid_connect_provider", + Name: "OIDC Provider", }, { - Factory: DataSourcePolicy, + Factory: dataSourcePolicy, TypeName: "aws_iam_policy", + Name: "Policy", }, { - Factory: DataSourcePolicyDocument, + Factory: dataSourcePolicyDocument, TypeName: "aws_iam_policy_document", + Name: "Policy Document", }, { - Factory: DataSourcePrincipalPolicySimulation, + Factory: dataSourcePrincipalPolicySimulation, TypeName: "aws_iam_principal_policy_simulation", + Name: "Principal Policy Simulation", }, { - Factory: DataSourceRole, + Factory: dataSourceRole, TypeName: "aws_iam_role", + Name: "Role", }, { - Factory: DataSourceRoles, + Factory: dataSourceRoles, TypeName: "aws_iam_roles", + Name: "Roles", }, { - Factory: DataSourceSAMLProvider, + Factory: dataSourceSAMLProvider, TypeName: "aws_iam_saml_provider", + Name: "SAML Provider", }, { - Factory: DataSourceServerCertificate, + Factory: dataSourceServerCertificate, TypeName: "aws_iam_server_certificate", + Name: "Server Certificate", }, { - Factory: DataSourceSessionContext, + Factory: dataSourceSessionContext, TypeName: "aws_iam_session_context", + Name: "Session Context", }, { - Factory: DataSourceUser, + Factory: dataSourceUser, TypeName: "aws_iam_user", + Name: "User", }, { - Factory: DataSourceUserSSHKey, + Factory: dataSourceUserSSHKey, TypeName: "aws_iam_user_ssh_key", + Name: "User SSH Key", }, { - Factory: DataSourceUsers, + Factory: dataSourceUsers, TypeName: "aws_iam_users", + Name: "Users", }, } } @@ -99,12 +116,14 @@ func (p *servicePackage) SDKDataSources(ctx context.Context) []*types.ServicePac func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePackageSDKResource { return []*types.ServicePackageSDKResource{ { - Factory: ResourceAccessKey, + Factory: resourceAccessKey, TypeName: "aws_iam_access_key", + Name: "Access Key", }, { - Factory: ResourceAccountAlias, + Factory: resourceAccountAlias, TypeName: "aws_iam_account_alias", + Name: "Account Alias", }, { Factory: resourceAccountPasswordPolicy, @@ -117,12 +136,14 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "Group", }, { - Factory: ResourceGroupMembership, + Factory: resourceGroupMembership, TypeName: "aws_iam_group_membership", + Name: "Group Membership", }, { - Factory: ResourceGroupPolicy, + Factory: resourceGroupPolicy, TypeName: "aws_iam_group_policy", + Name: "Group Policy", }, { Factory: resourceGroupPolicyAttachment, @@ -171,8 +192,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourceRolePolicy, + Factory: resourceRolePolicy, TypeName: "aws_iam_role_policy", + Name: "Role Policy", }, { Factory: resourceRolePolicyAttachment, @@ -189,7 +211,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourceSecurityTokenServicePreferences, + Factory: resourceSecurityTokenServicePreferences, TypeName: "aws_iam_security_token_service_preferences", Name: "Security Token Service Preferences", }, @@ -212,12 +234,14 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourceServiceSpecificCredential, + Factory: resourceServiceSpecificCredential, TypeName: "aws_iam_service_specific_credential", + Name: "Service Specific Credential", }, { - Factory: ResourceSigningCertificate, + Factory: resourceSigningCertificate, TypeName: "aws_iam_signing_certificate", + Name: "Signing Certificate", }, { Factory: resourceUser, @@ -229,8 +253,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka }, }, { - Factory: ResourceUserGroupMembership, + Factory: resourceUserGroupMembership, TypeName: "aws_iam_user_group_membership", + Name: "User Group Membership", }, { Factory: resourceUserLoginProfile, @@ -238,8 +263,9 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka Name: "User Login Profile", }, { - Factory: ResourceUserPolicy, + Factory: resourceUserPolicy, TypeName: "aws_iam_user_policy", + Name: "User Policy", }, { Factory: resourceUserPolicyAttachment, diff --git a/internal/service/iam/service_specific_credential.go b/internal/service/iam/service_specific_credential.go index 0ef9533bf62..be589aaf782 100644 --- a/internal/service/iam/service_specific_credential.go +++ b/internal/service/iam/service_specific_credential.go @@ -20,8 +20,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_iam_service_specific_credential") -func ResourceServiceSpecificCredential() *schema.Resource { +// @SDKResource("aws_iam_service_specific_credential", name="Service Specific Credential") +func resourceServiceSpecificCredential() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceServiceSpecificCredentialCreate, ReadWithoutTimeout: resourceServiceSpecificCredentialRead, diff --git a/internal/service/iam/session_context_data_source.go b/internal/service/iam/session_context_data_source.go index 3d3f83a776d..3a8e7655d87 100644 --- a/internal/service/iam/session_context_data_source.go +++ b/internal/service/iam/session_context_data_source.go @@ -19,8 +19,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKDataSource("aws_iam_session_context") -func DataSourceSessionContext() *schema.Resource { +// @SDKDataSource("aws_iam_session_context", name="Session Context") +func dataSourceSessionContext() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceSessionContextRead, diff --git a/internal/service/iam/signing_certificate.go b/internal/service/iam/signing_certificate.go index ee0c0a7b950..b2d47dcf379 100644 --- a/internal/service/iam/signing_certificate.go +++ b/internal/service/iam/signing_certificate.go @@ -21,8 +21,8 @@ import ( // nosemgrep:ci.semgrep.aws.multiple-service-imports "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_iam_signing_certificate") -func ResourceSigningCertificate() *schema.Resource { +// @SDKResource("aws_iam_signing_certificate", name="Signing Certificate") +func resourceSigningCertificate() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceSigningCertificateCreate, ReadWithoutTimeout: resourceSigningCertificateRead, diff --git a/internal/service/iam/sweep.go b/internal/service/iam/sweep.go index 28ce24c39b8..7696e2176aa 100644 --- a/internal/service/iam/sweep.go +++ b/internal/service/iam/sweep.go @@ -336,7 +336,7 @@ func sweepServiceSpecificCredentials(ctx context.Context, client *conns.AWSClien for _, cred := range out.ServiceSpecificCredentials { id := fmt.Sprintf("%s:%s:%s", aws.StringValue(cred.ServiceName), aws.StringValue(cred.UserName), aws.StringValue(cred.ServiceSpecificCredentialId)) - r := ResourceServiceSpecificCredential() + r := resourceServiceSpecificCredential() d := r.Data(nil) d.SetId(id) @@ -900,7 +900,7 @@ func sweepSigningCertificates(ctx context.Context, client *conns.AWSClient) ([]s for _, cert := range out.Certificates { id := fmt.Sprintf("%s:%s", aws.StringValue(cert.CertificateId), aws.StringValue(cert.UserName)) - r := ResourceSigningCertificate() + r := resourceSigningCertificate() d := r.Data(nil) d.SetId(id) diff --git a/internal/service/iam/user.go b/internal/service/iam/user.go index f343703ab73..3598f4bb92b 100644 --- a/internal/service/iam/user.go +++ b/internal/service/iam/user.go @@ -454,7 +454,7 @@ func deleteUserLoginProfile(ctx context.Context, conn *iam.IAM, username string) } func deleteUserAccessKeys(ctx context.Context, conn *iam.IAM, username string) error { - accessKeys, err := FindAccessKeys(ctx, conn, username) + accessKeys, err := findAccessKeysByUser(ctx, conn, username) if err != nil && !tfresource.NotFound(err) { return fmt.Errorf("listing access keys for IAM User (%s): %w", username, err) diff --git a/internal/service/iam/user_data_source.go b/internal/service/iam/user_data_source.go index 91f5820e42d..b1b297da5a8 100644 --- a/internal/service/iam/user_data_source.go +++ b/internal/service/iam/user_data_source.go @@ -16,8 +16,8 @@ import ( tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" ) -// @SDKDataSource("aws_iam_user") -func DataSourceUser() *schema.Resource { +// @SDKDataSource("aws_iam_user", name="User") +func dataSourceUser() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceUserRead, diff --git a/internal/service/iam/user_group_membership.go b/internal/service/iam/user_group_membership.go index 9eb59adae4a..8c539b87324 100644 --- a/internal/service/iam/user_group_membership.go +++ b/internal/service/iam/user_group_membership.go @@ -22,13 +22,14 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_iam_user_group_membership") -func ResourceUserGroupMembership() *schema.Resource { +// @SDKResource("aws_iam_user_group_membership", name="User Group Membership") +func resourceUserGroupMembership() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceUserGroupMembershipCreate, ReadWithoutTimeout: resourceUserGroupMembershipRead, UpdateWithoutTimeout: resourceUserGroupMembershipUpdate, DeleteWithoutTimeout: resourceUserGroupMembershipDelete, + Importer: &schema.ResourceImporter{ StateContext: resourceUserGroupMembershipImport, }, diff --git a/internal/service/iam/user_policy.go b/internal/service/iam/user_policy.go index 47c2f6ff235..3ad3f8ad9da 100644 --- a/internal/service/iam/user_policy.go +++ b/internal/service/iam/user_policy.go @@ -23,8 +23,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKResource("aws_iam_user_policy") -func ResourceUserPolicy() *schema.Resource { +// @SDKResource("aws_iam_user_policy", name="User Policy") +func resourceUserPolicy() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceUserPolicyPut, ReadWithoutTimeout: resourceUserPolicyRead, diff --git a/internal/service/iam/user_ssh_key_data_source.go b/internal/service/iam/user_ssh_key_data_source.go index 64e4ece8bc2..c494ed582f8 100644 --- a/internal/service/iam/user_ssh_key_data_source.go +++ b/internal/service/iam/user_ssh_key_data_source.go @@ -15,8 +15,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_user_ssh_key") -func DataSourceUserSSHKey() *schema.Resource { +// @SDKDataSource("aws_iam_user_ssh_key", name="User SSH Key") +func dataSourceUserSSHKey() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceUserSSHKeyRead, Schema: map[string]*schema.Schema{ diff --git a/internal/service/iam/users_data_source.go b/internal/service/iam/users_data_source.go index 4b29191fbed..6e1591efcd7 100644 --- a/internal/service/iam/users_data_source.go +++ b/internal/service/iam/users_data_source.go @@ -14,8 +14,8 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" ) -// @SDKDataSource("aws_iam_users") -func DataSourceUsers() *schema.Resource { +// @SDKDataSource("aws_iam_users", name="Users") +func dataSourceUsers() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceUsersRead, Schema: map[string]*schema.Schema{