Skip to content

Commit

Permalink
resource/aws_cloudwatch_log_stream: Prevent early state removal
Browse files Browse the repository at this point in the history
References:
* hashicorp#11611

The AWS logs service has eventual consistency considerations. The
`aws_cloudwatch_log_stream` resource immediately tries to read a stream
after creation. If the stream is not found, the logs service returns a 200
OK with an empty list of streams. Since no streams are present, the
`aws_cloudwatch_log_stream` resource removes the created resource from
state, leading to a "produced an unexpected new value for was present,
but now absent" error.

With the changes in this commit, the empty list of streams in the response
for the newly created resource will result in a NotFoundError being returned
and a retry of the read request. A subsequent retry should hopefully be
successful, leading to the state being preserved.

Output from acceptance testing:

```
make testacc TEST=./aws TESTARGS='-run=TestAccAWSCloudWatchLogStream_'
...
--- PASS: TestAccAWSCloudWatchLogStream_disappears_LogGroup (16.77s)
--- PASS: TestAccAWSCloudWatchLogStream_disappears (19.55s)
--- PASS: TestAccAWSCloudWatchLogStream_basic (19.91s)
```
  • Loading branch information
camlow325 committed Jan 16, 2020
1 parent 42ce6e4 commit ca48e29
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion aws/resource_aws_cloudwatch_log_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"fmt"
"log"
"regexp"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

Expand Down Expand Up @@ -60,7 +62,24 @@ func resourceAwsCloudWatchLogStreamRead(d *schema.ResourceData, meta interface{}

group := d.Get("log_group_name").(string)

ls, exists, err := lookupCloudWatchLogStream(conn, d.Id(), group, nil)
var ls *cloudwatchlogs.LogStream
var exists bool

err := resource.Retry(2*time.Minute, func() *resource.RetryError {
var err error
ls, exists, err = lookupCloudWatchLogStream(conn, d.Id(), group, nil)
if err != nil {
return resource.NonRetryableError(err)
}
if d.IsNewResource() && !exists {
return resource.RetryableError(&resource.NotFoundError{})
}
return nil
})
if isResourceTimeoutError(err) {
ls, exists, err = lookupCloudWatchLogStream(conn, d.Id(), group, nil)
}

if err != nil {
if !isAWSErr(err, cloudwatchlogs.ErrCodeResourceNotFoundException, "") {
return err
Expand Down

0 comments on commit ca48e29

Please sign in to comment.