Skip to content

Commit 5930faa

Browse files
authored
Merge pull request #24730 from sbutler/b-aws_servicecatalog_portfolio_share-sequential-processing
aws_servicecatalog_portfolio_share sequential processing
2 parents 74fa574 + a416c23 commit 5930faa

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

.changelog/24730.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
resource/aws_servicecatalog_portfolio_share: Add global mutex lock around create and delete operations to prevent `ThrottlingException` errors
3+
```

internal/service/servicecatalog/portfolio_share.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,13 @@ func resourcePortfolioShare() *schema.Resource {
101101
}
102102
}
103103

104+
const portfolioShareMutexKey = "aws_servicecatalog_portfolio_share"
105+
104106
func resourcePortfolioShareCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
105107
var diags diag.Diagnostics
106108
conn := meta.(*conns.AWSClient).ServiceCatalogClient(ctx)
107109

108-
input := &servicecatalog.CreatePortfolioShareInput{
110+
input := servicecatalog.CreatePortfolioShareInput{
109111
PortfolioId: aws.String(d.Get("portfolio_id").(string)),
110112
SharePrincipals: d.Get("share_principals").(bool),
111113
AcceptLanguage: aws.String(d.Get("accept_language").(string)),
@@ -131,11 +133,14 @@ func resourcePortfolioShareCreate(ctx context.Context, d *schema.ResourceData, m
131133
input.ShareTagOptions = v.(bool)
132134
}
133135

136+
conns.GlobalMutexKV.Lock(portfolioShareMutexKey)
137+
defer conns.GlobalMutexKV.Unlock(portfolioShareMutexKey)
138+
134139
var output *servicecatalog.CreatePortfolioShareOutput
135140
err := tfresource.Retry(ctx, d.Timeout(schema.TimeoutCreate), func(ctx context.Context) *tfresource.RetryError {
136141
var err error
137142

138-
output, err = conn.CreatePortfolioShare(ctx, input)
143+
output, err = conn.CreatePortfolioShare(ctx, &input)
139144

140145
if errs.IsAErrorMessageContains[*awstypes.InvalidParametersException](err, "profile does not exist") {
141146
return tfresource.RetryableError(err)
@@ -219,7 +224,7 @@ func resourcePortfolioShareUpdate(ctx context.Context, d *schema.ResourceData, m
219224
var diags diag.Diagnostics
220225
conn := meta.(*conns.AWSClient).ServiceCatalogClient(ctx)
221226

222-
input := &servicecatalog.UpdatePortfolioShareInput{
227+
input := servicecatalog.UpdatePortfolioShareInput{
223228
PortfolioId: aws.String(d.Get("portfolio_id").(string)),
224229
AcceptLanguage: aws.String(d.Get("accept_language").(string)),
225230
}
@@ -249,7 +254,7 @@ func resourcePortfolioShareUpdate(ctx context.Context, d *schema.ResourceData, m
249254
}
250255

251256
err := tfresource.Retry(ctx, d.Timeout(schema.TimeoutUpdate), func(ctx context.Context) *tfresource.RetryError {
252-
_, err := conn.UpdatePortfolioShare(ctx, input)
257+
_, err := conn.UpdatePortfolioShare(ctx, &input)
253258

254259
if errs.IsAErrorMessageContains[*awstypes.InvalidParametersException](err, "profile does not exist") {
255260
return tfresource.RetryableError(err)
@@ -273,7 +278,7 @@ func resourcePortfolioShareDelete(ctx context.Context, d *schema.ResourceData, m
273278
var diags diag.Diagnostics
274279
conn := meta.(*conns.AWSClient).ServiceCatalogClient(ctx)
275280

276-
input := &servicecatalog.DeletePortfolioShareInput{
281+
input := servicecatalog.DeletePortfolioShareInput{
277282
PortfolioId: aws.String(d.Get("portfolio_id").(string)),
278283
}
279284

@@ -297,7 +302,10 @@ func resourcePortfolioShareDelete(ctx context.Context, d *schema.ResourceData, m
297302
input.OrganizationNode = orgNode
298303
}
299304

300-
output, err := conn.DeletePortfolioShare(ctx, input)
305+
conns.GlobalMutexKV.Lock(portfolioShareMutexKey)
306+
defer conns.GlobalMutexKV.Unlock(portfolioShareMutexKey)
307+
308+
output, err := conn.DeletePortfolioShare(ctx, &input)
301309

302310
if errs.IsA[*awstypes.ResourceNotFoundException](err) {
303311
return diags

internal/service/servicecatalog/status.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,13 @@ func statusPortfolioShareWithToken(ctx context.Context, conn *servicecatalog.Cli
9090
return nil, statusUnavailable, fmt.Errorf("describing portfolio share status: empty response")
9191
}
9292

93-
return output, string(output.Status), err
93+
status := output.Status
94+
if (status == awstypes.ShareStatusCompletedWithErrors || status == awstypes.ShareStatusError) &&
95+
output.ShareDetails != nil && output.ShareDetails.ShareErrors != nil && len(output.ShareDetails.ShareErrors) > 0 {
96+
return output, string(status), fmt.Errorf("portfolio share status: %+v", output.ShareDetails.ShareErrors)
97+
}
98+
99+
return output, string(status), err
94100
}
95101
}
96102

internal/service/servicecatalog/wait.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,10 @@ func waitPortfolioShareReady(ctx context.Context, conn *servicecatalog.Client, p
167167
return nil, err
168168
}
169169

170-
func waitPortfolioShareCreatedWithToken(ctx context.Context, conn *servicecatalog.Client, token string, acceptRequired bool, timeout time.Duration) (*servicecatalog.DescribePortfolioShareStatusOutput, error) {
170+
func waitPortfolioShareCreatedWithToken(ctx context.Context, conn *servicecatalog.Client, token string, waitForAcceptance bool, timeout time.Duration) (*servicecatalog.DescribePortfolioShareStatusOutput, error) {
171171
targets := enum.Slice(awstypes.ShareStatusCompleted)
172172

173-
if !acceptRequired {
173+
if !waitForAcceptance {
174174
targets = append(targets, string(awstypes.ShareStatusInProgress))
175175
}
176176

0 commit comments

Comments
 (0)