Skip to content

Commit 7dcf701

Browse files
authored
Merge pull request #36383 from hashicorp/b-d/aws_iam_policy_document-override_json
[WIP] d/aws_iam_policy_document: Fix `Failed to marshal plan to json, unsupported attribute "override_json"`
2 parents 31891a2 + 503da31 commit 7dcf701

34 files changed

+358
-260
lines changed

.changelog/36383.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
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`
3+
```

internal/service/iam/access_key.go

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@ import (
1414

1515
"github.com/aws/aws-sdk-go/aws"
1616
"github.com/aws/aws-sdk-go/service/iam"
17+
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
1718
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
19+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1820
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1921
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
2022
"github.com/hashicorp/terraform-provider-aws/internal/conns"
2123
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
24+
tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
2225
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
2326
)
2427

25-
// @SDKResource("aws_iam_access_key")
26-
func ResourceAccessKey() *schema.Resource {
28+
// @SDKResource("aws_iam_access_key", name="Access Key")
29+
func resourceAccessKey() *schema.Resource {
2730
return &schema.Resource{
2831
CreateWithoutTimeout: resourceAccessKeyCreate,
2932
ReadWithoutTimeout: resourceAccessKeyRead,
@@ -187,8 +190,8 @@ func resourceAccessKeyRead(ctx context.Context, d *schema.ResourceData, meta int
187190
conn := meta.(*conns.AWSClient).IAMConn(ctx)
188191

189192
username := d.Get("user").(string)
193+
key, err := findAccessKeyByTwoPartKey(ctx, conn, username, d.Id())
190194

191-
key, err := FindAccessKey(ctx, conn, username, d.Id())
192195
if !d.IsNewResource() && tfresource.NotFound(err) {
193196
log.Printf("[WARN] IAM Access Key (%s) for User (%s) not found, removing from state", d.Id(), username)
194197
d.SetId("")
@@ -242,14 +245,20 @@ func resourceAccessKeyDelete(ctx context.Context, d *schema.ResourceData, meta i
242245
var diags diag.Diagnostics
243246
conn := meta.(*conns.AWSClient).IAMConn(ctx)
244247

245-
request := &iam.DeleteAccessKeyInput{
248+
log.Printf("[DEBUG] Deleting IAM Access Key: %s", d.Id())
249+
_, err := conn.DeleteAccessKeyWithContext(ctx, &iam.DeleteAccessKeyInput{
246250
AccessKeyId: aws.String(d.Id()),
247251
UserName: aws.String(d.Get("user").(string)),
252+
})
253+
254+
if tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) {
255+
return diags
248256
}
249257

250-
if _, err := conn.DeleteAccessKeyWithContext(ctx, request); err != nil {
258+
if err != nil {
251259
return sdkdiag.AppendErrorf(diags, "deleting IAM Access Key (%s): %s", d.Id(), err)
252260
}
261+
253262
return diags
254263
}
255264

@@ -264,6 +273,61 @@ func resourceAccessKeyStatusUpdate(ctx context.Context, conn *iam.IAM, d *schema
264273
return err
265274
}
266275

276+
func findAccessKeyByTwoPartKey(ctx context.Context, conn *iam.IAM, username, id string) (*iam.AccessKeyMetadata, error) {
277+
input := &iam.ListAccessKeysInput{
278+
UserName: aws.String(username),
279+
}
280+
281+
return findAccessKey(ctx, conn, input, func(v *iam.AccessKeyMetadata) bool {
282+
return aws.StringValue(v.AccessKeyId) == id
283+
})
284+
}
285+
286+
func findAccessKeysByUser(ctx context.Context, conn *iam.IAM, username string) ([]*iam.AccessKeyMetadata, error) {
287+
input := &iam.ListAccessKeysInput{
288+
UserName: aws.String(username),
289+
}
290+
291+
return findAccessKeys(ctx, conn, input, tfslices.PredicateTrue[*iam.AccessKeyMetadata]())
292+
}
293+
294+
func findAccessKey(ctx context.Context, conn *iam.IAM, input *iam.ListAccessKeysInput, filter tfslices.Predicate[*iam.AccessKeyMetadata]) (*iam.AccessKeyMetadata, error) {
295+
output, err := findAccessKeys(ctx, conn, input, filter)
296+
297+
if err != nil {
298+
return nil, err
299+
}
300+
301+
return tfresource.AssertSinglePtrResult(output)
302+
}
303+
304+
func findAccessKeys(ctx context.Context, conn *iam.IAM, input *iam.ListAccessKeysInput, filter tfslices.Predicate[*iam.AccessKeyMetadata]) ([]*iam.AccessKeyMetadata, error) {
305+
var output []*iam.AccessKeyMetadata
306+
307+
err := conn.ListAccessKeysPagesWithContext(ctx, input, func(page *iam.ListAccessKeysOutput, lastPage bool) bool {
308+
if page == nil {
309+
return !lastPage
310+
}
311+
312+
for _, v := range page.AccessKeyMetadata {
313+
if v != nil && filter(v) {
314+
output = append(output, v)
315+
}
316+
}
317+
318+
return !lastPage
319+
})
320+
321+
if tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) {
322+
return nil, &retry.NotFoundError{
323+
LastError: err,
324+
LastRequest: input,
325+
}
326+
}
327+
328+
return output, err
329+
}
330+
267331
func hmacSignature(key []byte, value []byte) ([]byte, error) {
268332
h := hmac.New(sha256.New, key)
269333
if _, err := h.Write(value); err != nil {

internal/service/iam/access_key_test.go

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ func TestAccIAMAccessKey_basic(t *testing.T) {
5858
})
5959
}
6060

61+
func TestAccIAMAccessKey_disappears(t *testing.T) {
62+
ctx := acctest.Context(t)
63+
var conf iam.AccessKeyMetadata
64+
resourceName := "aws_iam_access_key.test"
65+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
66+
67+
resource.ParallelTest(t, resource.TestCase{
68+
PreCheck: func() { acctest.PreCheck(ctx, t) },
69+
ErrorCheck: acctest.ErrorCheck(t, names.IAMServiceID),
70+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
71+
CheckDestroy: testAccCheckAccessKeyDestroy(ctx),
72+
Steps: []resource.TestStep{
73+
{
74+
Config: testAccAccessKeyConfig_basic(rName),
75+
Check: resource.ComposeTestCheckFunc(
76+
testAccCheckAccessKeyExists(ctx, resourceName, &conf),
77+
acctest.CheckResourceDisappears(ctx, acctest.Provider, tfiam.ResourceAccessKey(), resourceName),
78+
),
79+
ExpectNonEmptyPlan: true,
80+
},
81+
},
82+
})
83+
}
84+
6185
func TestAccIAMAccessKey_encrypted(t *testing.T) {
6286
ctx := acctest.Context(t)
6387
var conf iam.AccessKeyMetadata
@@ -145,39 +169,39 @@ func testAccCheckAccessKeyDestroy(ctx context.Context) resource.TestCheckFunc {
145169
continue
146170
}
147171

148-
_, err := tfiam.FindAccessKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID)
172+
_, err := tfiam.FindAccessKeyByTwoPartKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID)
173+
149174
if tfresource.NotFound(err) {
150175
return nil
151176
}
177+
152178
if err != nil {
153179
return err
154180
}
181+
155182
return fmt.Errorf("IAM Access Key (%s) still exists", rs.Primary.ID)
156183
}
157184

158185
return nil
159186
}
160187
}
161188

162-
func testAccCheckAccessKeyExists(ctx context.Context, n string, res *iam.AccessKeyMetadata) resource.TestCheckFunc {
189+
func testAccCheckAccessKeyExists(ctx context.Context, n string, v *iam.AccessKeyMetadata) resource.TestCheckFunc {
163190
return func(s *terraform.State) error {
164191
rs, ok := s.RootModule().Resources[n]
165192
if !ok {
166193
return fmt.Errorf("Not found: %s", n)
167194
}
168195

169-
if rs.Primary.ID == "" {
170-
return fmt.Errorf("No Access Key ID is set")
171-
}
172-
173196
conn := acctest.Provider.Meta().(*conns.AWSClient).IAMConn(ctx)
174197

175-
accessKey, err := tfiam.FindAccessKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID)
198+
output, err := tfiam.FindAccessKeyByTwoPartKey(ctx, conn, rs.Primary.Attributes["user"], rs.Primary.ID)
199+
176200
if err != nil {
177201
return err
178202
}
179203

180-
*res = *accessKey
204+
*v = *output
181205

182206
return nil
183207
}

internal/service/iam/access_keys_data_source.go

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ import (
1212
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1313
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1414
"github.com/hashicorp/terraform-provider-aws/internal/conns"
15-
"github.com/hashicorp/terraform-provider-aws/internal/create"
16-
"github.com/hashicorp/terraform-provider-aws/names"
15+
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
1716
)
1817

19-
// @SDKDataSource("aws_iam_access_keys")
20-
func DataSourceAccessKeys() *schema.Resource {
18+
// @SDKDataSource("aws_iam_access_keys", name="Access Keys")
19+
func dataSourceAccessKeys() *schema.Resource {
2120
return &schema.Resource{
2221
ReadWithoutTimeout: dataSourceAccessKeysRead,
2322
Schema: map[string]*schema.Schema{
@@ -49,26 +48,21 @@ func DataSourceAccessKeys() *schema.Resource {
4948
}
5049
}
5150

52-
const (
53-
DSNameAccessKeys = "Access Keys Data Source"
54-
)
55-
5651
func dataSourceAccessKeysRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
5752
var diags diag.Diagnostics
5853

5954
conn := meta.(*conns.AWSClient).IAMConn(ctx)
6055

6156
username := d.Get("user").(string)
62-
out, err := FindAccessKeys(ctx, conn, username)
57+
output, err := findAccessKeysByUser(ctx, conn, username)
6358

6459
if err != nil {
65-
return create.AppendDiagError(diags, names.IAM, create.ErrActionReading, DSNameAccessKeys, username, err)
60+
return sdkdiag.AppendErrorf(diags, "reading IAM Access Keys (%s): %s", username, err)
6661
}
6762

6863
d.SetId(username)
69-
70-
if err := d.Set("access_keys", flattenAccessKeys(out)); err != nil {
71-
return create.AppendDiagError(diags, names.IAM, create.ErrActionSetting, DSNameAccessKeys, d.Id(), err)
64+
if err := d.Set("access_keys", flattenAccessKeys(output)); err != nil {
65+
return sdkdiag.AppendErrorf(diags, "setting access_keys: %s", err)
7266
}
7367

7468
return diags

internal/service/iam/account_alias.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import (
1414
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
1515
)
1616

17-
// @SDKResource("aws_iam_account_alias")
18-
func ResourceAccountAlias() *schema.Resource {
17+
// @SDKResource("aws_iam_account_alias", name="Account Alias")
18+
func resourceAccountAlias() *schema.Resource {
1919
return &schema.Resource{
2020
CreateWithoutTimeout: resourceAccountAliasCreate,
2121
ReadWithoutTimeout: resourceAccountAliasRead,

internal/service/iam/account_alias_data_source.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
1616
)
1717

18-
// @SDKDataSource("aws_iam_account_alias")
19-
func DataSourceAccountAlias() *schema.Resource {
18+
// @SDKDataSource("aws_iam_account_alias", name="Account Alias")
19+
func dataSourceAccountAlias() *schema.Resource {
2020
return &schema.Resource{
2121
ReadWithoutTimeout: dataSourceAccountAliasRead,
2222

internal/service/iam/exports_test.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,33 @@ package iam
55

66
// Exports for use in tests only.
77
var (
8+
ResourceAccessKey = resourceAccessKey
9+
// ResourceAccountAlias = resourceAccountAlias
810
ResourceAccountPasswordPolicy = resourceAccountPasswordPolicy
911
ResourceGroup = resourceGroup
10-
ResourceGroupPolicyAttachment = resourceGroupPolicyAttachment
11-
ResourceInstanceProfile = resourceInstanceProfile
12-
ResourceOpenIDConnectProvider = resourceOpenIDConnectProvider
13-
ResourcePolicy = resourcePolicy
14-
ResourcePolicyAttachment = resourcePolicyAttachment
15-
ResourceRolePolicyAttachment = resourceRolePolicyAttachment
16-
ResourceSAMLProvider = resourceSAMLProvider
17-
ResourceServerCertificate = resourceServerCertificate
18-
ResourceServiceLinkedRole = resourceServiceLinkedRole
19-
ResourceUser = resourceUser
20-
ResourceUserLoginProfile = resourceUserLoginProfile
21-
ResourceUserPolicyAttachment = resourceUserPolicyAttachment
22-
ResourceUserSSHKey = resourceUserSSHKey
23-
ResourceVirtualMFADevice = resourceVirtualMFADevice
12+
// ResourceGroupMembership = resourceGroupMembership
13+
ResourceGroupPolicy = resourceGroupPolicy
14+
ResourceGroupPolicyAttachment = resourceGroupPolicyAttachment
15+
ResourceInstanceProfile = resourceInstanceProfile
16+
ResourceOpenIDConnectProvider = resourceOpenIDConnectProvider
17+
ResourcePolicy = resourcePolicy
18+
ResourcePolicyAttachment = resourcePolicyAttachment
19+
ResourceRolePolicy = resourceRolePolicy
20+
ResourceRolePolicyAttachment = resourceRolePolicyAttachment
21+
ResourceSAMLProvider = resourceSAMLProvider
22+
ResourceServerCertificate = resourceServerCertificate
23+
ResourceServiceLinkedRole = resourceServiceLinkedRole
24+
ResourceServiceSpecificCredential = resourceServiceSpecificCredential
25+
ResourceSigningCertificate = resourceSigningCertificate
26+
ResourceUser = resourceUser
27+
ResourceUserGroupMembership = resourceUserGroupMembership
28+
ResourceUserLoginProfile = resourceUserLoginProfile
29+
ResourceUserPolicy = resourceUserPolicy
30+
ResourceUserPolicyAttachment = resourceUserPolicyAttachment
31+
ResourceUserSSHKey = resourceUserSSHKey
32+
ResourceVirtualMFADevice = resourceVirtualMFADevice
2433

34+
FindAccessKeyByTwoPartKey = findAccessKeyByTwoPartKey
2535
FindAccountPasswordPolicy = findAccountPasswordPolicy
2636
FindAttachedGroupPolicies = findAttachedGroupPolicies
2737
FindAttachedGroupPolicyByTwoPartKey = findAttachedGroupPolicyByTwoPartKey

internal/service/iam/find.go

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -125,44 +125,3 @@ func FindSigningCertificate(ctx context.Context, conn *iam.IAM, userName, certId
125125

126126
return cert, nil
127127
}
128-
129-
func FindAccessKey(ctx context.Context, conn *iam.IAM, username, id string) (*iam.AccessKeyMetadata, error) {
130-
accessKeys, err := FindAccessKeys(ctx, conn, username)
131-
if err != nil {
132-
return nil, err
133-
}
134-
135-
for _, accessKey := range accessKeys {
136-
if aws.StringValue(accessKey.AccessKeyId) == id {
137-
return accessKey, nil
138-
}
139-
}
140-
141-
return nil, &retry.NotFoundError{}
142-
}
143-
144-
func FindAccessKeys(ctx context.Context, conn *iam.IAM, username string) ([]*iam.AccessKeyMetadata, error) {
145-
input := &iam.ListAccessKeysInput{
146-
UserName: aws.String(username),
147-
}
148-
var output []*iam.AccessKeyMetadata
149-
150-
err := conn.ListAccessKeysPagesWithContext(ctx, input, func(page *iam.ListAccessKeysOutput, lastPage bool) bool {
151-
if page == nil {
152-
return !lastPage
153-
}
154-
155-
output = append(output, page.AccessKeyMetadata...)
156-
157-
return !lastPage
158-
})
159-
160-
if tfawserr.ErrCodeEquals(err, iam.ErrCodeNoSuchEntityException) {
161-
return nil, &retry.NotFoundError{
162-
LastError: err,
163-
LastRequest: input,
164-
}
165-
}
166-
167-
return output, err
168-
}

internal/service/iam/group_data_source.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
1616
)
1717

18-
// @SDKDataSource("aws_iam_group")
19-
func DataSourceGroup() *schema.Resource {
18+
// @SDKDataSource("aws_iam_group", name="Group")
19+
func dataSourceGroup() *schema.Resource {
2020
return &schema.Resource{
2121
ReadWithoutTimeout: dataSourceGroupRead,
2222

internal/service/iam/group_membership.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import (
1919
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
2020
)
2121

22-
// @SDKResource("aws_iam_group_membership")
23-
func ResourceGroupMembership() *schema.Resource {
22+
// @SDKResource("aws_iam_group_membership", name="Group Membership")
23+
func resourceGroupMembership() *schema.Resource {
2424
return &schema.Resource{
2525
CreateWithoutTimeout: resourceGroupMembershipCreate,
2626
ReadWithoutTimeout: resourceGroupMembershipRead,

internal/service/iam/group_policy.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import (
2323
"github.com/hashicorp/terraform-provider-aws/internal/verify"
2424
)
2525

26-
// @SDKResource("aws_iam_group_policy")
27-
func ResourceGroupPolicy() *schema.Resource {
26+
// @SDKResource("aws_iam_group_policy", name="Group Policy")
27+
func resourceGroupPolicy() *schema.Resource {
2828
return &schema.Resource{
2929
CreateWithoutTimeout: resourceGroupPolicyPut,
3030
ReadWithoutTimeout: resourceGroupPolicyRead,

0 commit comments

Comments
 (0)