Skip to content

Commit

Permalink
Merge pull request hashicorp#32865 from hashicorp/b-aws_cloudfront_di…
Browse files Browse the repository at this point in the history
…stribution-tags-only-update

r/aws_cloudfront_distribution: Speed up `tags`-only updates
  • Loading branch information
ewbankkit authored Aug 4, 2023
2 parents c6ccb75 + 0da0828 commit 1bd51ad
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 71 deletions.
3 changes: 3 additions & 0 deletions .changelog/32865.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_cloudfront_distribution: Don't call `UpdateDistribution` API if only tags are updated
```
111 changes: 40 additions & 71 deletions internal/service/cloudfront/distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -846,35 +846,17 @@ func resourceDistributionCreate(ctx context.Context, d *schema.ResourceData, met
input.DistributionConfigWithTags.Tags.Items = tags
}

var resp *cloudfront.CreateDistributionWithTagsOutput
// Handle eventual consistency issues
err := retry.RetryContext(ctx, 1*time.Minute, func() *retry.RetryError {
var err error
resp, err = conn.CreateDistributionWithTagsWithContext(ctx, input)

// ACM and IAM certificate eventual consistency
// InvalidViewerCertificate: The specified SSL certificate doesn't exist, isn't in us-east-1 region, isn't valid, or doesn't include a valid certificate chain.
if tfawserr.ErrCodeEquals(err, cloudfront.ErrCodeInvalidViewerCertificate) {
return retry.RetryableError(err)
}

if err != nil {
return retry.NonRetryableError(err)
}

return nil
})

// Propagate AWS Go SDK retried error, if any
if tfresource.TimedOut(err) {
resp, err = conn.CreateDistributionWithTagsWithContext(ctx, input)
}
// ACM and IAM certificate eventual consistency.
// InvalidViewerCertificate: The specified SSL certificate doesn't exist, isn't in us-east-1 region, isn't valid, or doesn't include a valid certificate chain.
outputRaw, err := tfresource.RetryWhenAWSErrCodeEquals(ctx, 1*time.Minute, func() (interface{}, error) {
return conn.CreateDistributionWithTagsWithContext(ctx, input)
}, cloudfront.ErrCodeInvalidViewerCertificate)

if err != nil {
return sdkdiag.AppendErrorf(diags, "creating CloudFront Distribution: %s", err)
}

d.SetId(aws.StringValue(resp.Distribution.Id))
d.SetId(aws.StringValue(outputRaw.(*cloudfront.CreateDistributionWithTagsOutput).Distribution.Id))

if d.Get("wait_for_deployment").(bool) {
log.Printf("[DEBUG] Waiting until CloudFront Distribution (%s) is deployed", d.Id())
Expand Down Expand Up @@ -929,65 +911,52 @@ func resourceDistributionRead(ctx context.Context, d *schema.ResourceData, meta
func resourceDistributionUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).CloudFrontConn(ctx)
params := &cloudfront.UpdateDistributionInput{
Id: aws.String(d.Id()),
DistributionConfig: expandDistributionConfig(d),
IfMatch: aws.String(d.Get("etag").(string)),
}

// Handle eventual consistency issues
err := retry.RetryContext(ctx, 1*time.Minute, func() *retry.RetryError {
_, err := conn.UpdateDistributionWithContext(ctx, params)
if d.HasChangesExcept("tags", "tags_all") {
input := &cloudfront.UpdateDistributionInput{
Id: aws.String(d.Id()),
DistributionConfig: expandDistributionConfig(d),
IfMatch: aws.String(d.Get("etag").(string)),
}

// ACM and IAM certificate eventual consistency
// ACM and IAM certificate eventual consistency.
// InvalidViewerCertificate: The specified SSL certificate doesn't exist, isn't in us-east-1 region, isn't valid, or doesn't include a valid certificate chain.
if tfawserr.ErrCodeEquals(err, cloudfront.ErrCodeInvalidViewerCertificate) {
return retry.RetryableError(err)
}
_, err := tfresource.RetryWhenAWSErrCodeEquals(ctx, 1*time.Minute, func() (interface{}, error) {
return conn.UpdateDistributionWithContext(ctx, input)
}, cloudfront.ErrCodeInvalidViewerCertificate)

if err != nil {
return retry.NonRetryableError(err)
}
// Refresh our ETag if it is out of date and attempt update again.
if tfawserr.ErrCodeEquals(err, cloudfront.ErrCodePreconditionFailed) {
getDistributionInput := &cloudfront.GetDistributionInput{
Id: aws.String(d.Id()),
}
var getDistributionOutput *cloudfront.GetDistributionOutput

return nil
})
log.Printf("[DEBUG] Refreshing CloudFront Distribution (%s) ETag", d.Id())
getDistributionOutput, err = conn.GetDistributionWithContext(ctx, getDistributionInput)

// Refresh our ETag if it is out of date and attempt update again
if tfawserr.ErrCodeEquals(err, cloudfront.ErrCodePreconditionFailed) {
getDistributionInput := &cloudfront.GetDistributionInput{
Id: aws.String(d.Id()),
}
var getDistributionOutput *cloudfront.GetDistributionOutput
if err != nil {
return sdkdiag.AppendErrorf(diags, "refreshing CloudFront Distribution (%s) ETag: %s", d.Id(), err)
}

log.Printf("[DEBUG] Refreshing CloudFront Distribution (%s) ETag", d.Id())
getDistributionOutput, err = conn.GetDistributionWithContext(ctx, getDistributionInput)
if getDistributionOutput == nil {
return sdkdiag.AppendErrorf(diags, "refreshing CloudFront Distribution (%s) ETag: empty response", d.Id())
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "refreshing CloudFront Distribution (%s) ETag: %s", d.Id(), err)
}
input.IfMatch = getDistributionOutput.ETag

if getDistributionOutput == nil {
return sdkdiag.AppendErrorf(diags, "refreshing CloudFront Distribution (%s) ETag: empty response", d.Id())
_, err = conn.UpdateDistributionWithContext(ctx, input)
}

params.IfMatch = getDistributionOutput.ETag

_, err = conn.UpdateDistributionWithContext(ctx, params)
}

// Propagate AWS Go SDK retried error, if any
if tfresource.TimedOut(err) {
_, err = conn.UpdateDistributionWithContext(ctx, params)
}

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating CloudFront Distribution (%s): %s", d.Id(), err)
}
if err != nil {
return sdkdiag.AppendErrorf(diags, "updating CloudFront Distribution (%s): %s", d.Id(), err)
}

if d.Get("wait_for_deployment").(bool) {
log.Printf("[DEBUG] Waiting until CloudFront Distribution (%s) is deployed", d.Id())
if err := DistributionWaitUntilDeployed(ctx, d.Id(), meta); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting until CloudFront Distribution (%s) is deployed: %s", d.Id(), err)
if d.Get("wait_for_deployment").(bool) {
log.Printf("[DEBUG] Waiting until CloudFront Distribution (%s) is deployed", d.Id())
if err := DistributionWaitUntilDeployed(ctx, d.Id(), meta); err != nil {
return sdkdiag.AppendErrorf(diags, "waiting until CloudFront Distribution (%s) is deployed: %s", d.Id(), err)
}
}
}

Expand Down

0 comments on commit 1bd51ad

Please sign in to comment.