Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/synthetics_canary - fix canary update #17704

Merged
merged 5 commits into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/17704.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_synthetics_canary: Fix Canary Update when in running state
```
115 changes: 60 additions & 55 deletions aws/resource_aws_synthetics_canary.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,61 +341,52 @@ func resourceAwsSyntheticsCanaryRead(d *schema.ResourceData, meta interface{}) e
func resourceAwsSyntheticsCanaryUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).syntheticsconn

input := &synthetics.UpdateCanaryInput{
Name: aws.String(d.Id()),
}

updateFlag := false
if d.HasChangesExcept("tags", "start_canary") {
input := &synthetics.UpdateCanaryInput{
Name: aws.String(d.Id()),
}

if d.HasChange("vpc_config") {
input.VpcConfig = expandAwsSyntheticsCanaryVpcConfig(d.Get("vpc_config").([]interface{}))
updateFlag = true
}
if d.HasChange("vpc_config") {
input.VpcConfig = expandAwsSyntheticsCanaryVpcConfig(d.Get("vpc_config").([]interface{}))
}

if d.HasChange("runtime_version") {
input.RuntimeVersion = aws.String(d.Get("runtime_version").(string))
updateFlag = true
}
if d.HasChange("runtime_version") {
input.RuntimeVersion = aws.String(d.Get("runtime_version").(string))
}

if d.HasChanges("handler", "zip_file", "s3_bucket", "s3_key", "s3_version") {
code, err := expandAwsSyntheticsCanaryCode(d)
if err != nil {
return err
if d.HasChanges("handler", "zip_file", "s3_bucket", "s3_key", "s3_version") {
code, err := expandAwsSyntheticsCanaryCode(d)
if err != nil {
return err
}
input.Code = code
}
input.Code = code
updateFlag = true
}

if d.HasChange("run_config") {
input.RunConfig = expandAwsSyntheticsCanaryRunConfig(d.Get("run_config").([]interface{}))
updateFlag = true
}
if d.HasChange("run_config") {
input.RunConfig = expandAwsSyntheticsCanaryRunConfig(d.Get("run_config").([]interface{}))
}

if d.HasChange("schedule") {
input.Schedule = expandAwsSyntheticsCanarySchedule(d.Get("schedule").([]interface{}))
updateFlag = true
}
if d.HasChange("schedule") {
input.Schedule = expandAwsSyntheticsCanarySchedule(d.Get("schedule").([]interface{}))
}

if d.HasChange("success_retention_period") {
_, n := d.GetChange("success_retention_period")
input.SuccessRetentionPeriodInDays = aws.Int64(int64(n.(int)))
updateFlag = true
}
if d.HasChange("success_retention_period") {
_, n := d.GetChange("success_retention_period")
input.SuccessRetentionPeriodInDays = aws.Int64(int64(n.(int)))
}

if d.HasChange("failure_retention_period") {
_, n := d.GetChange("failure_retention_period")
input.FailureRetentionPeriodInDays = aws.Int64(int64(n.(int)))
updateFlag = true
}
if d.HasChange("failure_retention_period") {
_, n := d.GetChange("failure_retention_period")
input.FailureRetentionPeriodInDays = aws.Int64(int64(n.(int)))
}

if d.HasChange("execution_role_arn") {
_, n := d.GetChange("execution_role_arn")
input.ExecutionRoleArn = aws.String(n.(string))
updateFlag = true
}
if d.HasChange("execution_role_arn") {
_, n := d.GetChange("execution_role_arn")
input.ExecutionRoleArn = aws.String(n.(string))
}

if updateFlag {
if status := d.Get("status"); status.(string) == synthetics.CanaryStateRunning {
status := d.Get("status").(string)
if status == synthetics.CanaryStateRunning {
if err := syntheticsStopCanary(d.Id(), conn); err != nil {
return err
}
Expand All @@ -406,22 +397,36 @@ func resourceAwsSyntheticsCanaryUpdate(d *schema.ResourceData, meta interface{})
return fmt.Errorf("error updating Synthetics Canary: %w", err)
}

if _, err := waiter.CanaryReady(conn, d.Id()); err != nil {
return fmt.Errorf("error waiting for Synthetics Canary (%s) updating: %w", d.Id(), err)
if status != synthetics.CanaryStateReady {
if _, err := waiter.CanaryStopped(conn, d.Id()); err != nil {
return fmt.Errorf("error waiting for Synthetics Canary (%s) to be stopped: %w", d.Id(), err)
}
} else {
if _, err := waiter.CanaryReady(conn, d.Id()); err != nil {
return fmt.Errorf("error waiting for Synthetics Canary (%s) updating: %w", d.Id(), err)
}
}
}

status := d.Get("status")
if v := d.Get("start_canary"); v.(bool) {
if status.(string) != synthetics.CanaryStateRunning {
if v := d.Get("start_canary"); v.(bool) {
if err := syntheticsStartCanary(d.Id(), conn); err != nil {
return err
}
}
} else {
if status.(string) == synthetics.CanaryStateRunning {
if err := syntheticsStopCanary(d.Id(), conn); err != nil {
return err
}

if d.HasChange("start_canary") {
status := d.Get("status").(string)
if v := d.Get("start_canary"); v.(bool) {
if status != synthetics.CanaryStateRunning {
if err := syntheticsStartCanary(d.Id(), conn); err != nil {
return err
}
}
} else {
if status == synthetics.CanaryStateRunning {
if err := syntheticsStopCanary(d.Id(), conn); err != nil {
return err
}
}
}
}
Expand Down
63 changes: 63 additions & 0 deletions aws/resource_aws_synthetics_canary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func TestAccAWSSyntheticsCanary_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "artifact_s3_location", fmt.Sprintf("%s/", rName)),
resource.TestCheckResourceAttr(resourceName, "timeline.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.created"),
resource.TestCheckResourceAttr(resourceName, "status", "READY"),
),
},
{
Expand Down Expand Up @@ -139,6 +140,7 @@ func TestAccAWSSyntheticsCanary_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "timeline.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.created"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.last_modified"),
resource.TestCheckResourceAttr(resourceName, "status", "READY"),
testAccCheckAwsSyntheticsCanaryIsUpdated(&conf1, &conf2),
),
},
Expand Down Expand Up @@ -221,13 +223,56 @@ func TestAccAWSSyntheticsCanary_startCanary(t *testing.T) {
testAccCheckAwsSyntheticsCanaryExists(resourceName, &conf3),
resource.TestCheckResourceAttr(resourceName, "timeline.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.last_started"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.last_stopped"),
testAccCheckAwsSyntheticsCanaryIsStartedAfter(&conf2, &conf3),
),
},
},
})
}

func TestAccAWSSyntheticsCanary_startCanary_codeChanges(t *testing.T) {
var conf1, conf2 synthetics.Canary
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
resourceName := "aws_synthetics_canary.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsSyntheticsCanaryDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSSyntheticsCanaryStartCanaryConfig(rName, true),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAwsSyntheticsCanaryExists(resourceName, &conf1),
resource.TestCheckResourceAttr(resourceName, "status", "RUNNING"),
resource.TestCheckResourceAttr(resourceName, "timeline.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.last_started"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"zip_file", "start_canary"},
},
{
Config: testAccAWSSyntheticsCanaryStartCanaryZipUpdatedConfig(rName, true),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckAwsSyntheticsCanaryExists(resourceName, &conf2),
resource.TestCheckResourceAttr(resourceName, "status", "RUNNING"),
resource.TestCheckResourceAttr(resourceName, "timeline.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.last_started"),
resource.TestCheckResourceAttrSet(resourceName, "timeline.0.last_stopped"),
testAccCheckAwsSyntheticsCanaryIsStartedAfter(&conf1, &conf2),
),
},
},
})
}

func TestAccAWSSyntheticsCanary_s3(t *testing.T) {
var conf synthetics.Canary
rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(8))
Expand Down Expand Up @@ -831,6 +876,24 @@ resource "aws_synthetics_canary" "test" {
`, rName, state))
}

func testAccAWSSyntheticsCanaryStartCanaryZipUpdatedConfig(rName string, state bool) string {
return composeConfig(testAccAWSSyntheticsCanaryConfigBase(rName), fmt.Sprintf(`
resource "aws_synthetics_canary" "test" {
name = %[1]q
artifact_s3_location = "s3://${aws_s3_bucket.test.bucket}/"
execution_role_arn = aws_iam_role.test.arn
handler = "exports.handler"
zip_file = "test-fixtures/lambdatest_modified.zip"
start_canary = %[2]t
runtime_version = "syn-1.0"

schedule {
expression = "rate(0 minute)"
}
}
`, rName, state))
}

func testAccAWSSyntheticsCanaryBasicS3CodeConfig(rName string) string {
return composeConfig(testAccAWSSyntheticsCanaryConfigBase(rName), fmt.Sprintf(`
resource "aws_synthetics_canary" "test" {
Expand Down