From ba3672799edf6c7d73dd99fcfa8fe3e836f88471 Mon Sep 17 00:00:00 2001 From: jammerful Date: Thu, 22 Mar 2018 15:08:30 -0400 Subject: [PATCH 1/2] resource/aws_security_group: Fix Missing Id Error Make security groups more resilient to eventual consistency errors by adding retries on the existence function in read and update. See: https://github.com/hashicorp/terraform/issues/6991 --- aws/resource_aws_security_group.go | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/aws/resource_aws_security_group.go b/aws/resource_aws_security_group.go index 346bc725d04e..f487e5fc3945 100644 --- a/aws/resource_aws_security_group.go +++ b/aws/resource_aws_security_group.go @@ -257,17 +257,7 @@ func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] Security Group ID: %s", d.Id()) // Wait for the security group to truly exist - log.Printf( - "[DEBUG] Waiting for Security Group (%s) to exist", - d.Id()) - stateConf := &resource.StateChangeConf{ - Pending: []string{""}, - Target: []string{"exists"}, - Refresh: SGStateRefreshFunc(conn, d.Id()), - Timeout: d.Timeout(schema.TimeoutCreate), - } - - resp, err := stateConf.WaitForState() + resp, err := waitForSgToExist(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf( "Error waiting for Security Group (%s) to become available: %s", @@ -342,11 +332,12 @@ func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) er func resourceAwsSecurityGroupRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - sgRaw, _, err := SGStateRefreshFunc(conn, d.Id())() + sgRaw, err := waitForSgToExist(conn, d.Id(), d.Timeout(schema.TimeoutRead)) if err != nil { return err } if sgRaw == nil { + log.Printf("[WARN] Security group (%s) not found, removing from state", d.Id()) d.SetId("") return nil } @@ -393,11 +384,12 @@ func resourceAwsSecurityGroupRead(d *schema.ResourceData, meta interface{}) erro func resourceAwsSecurityGroupUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - sgRaw, _, err := SGStateRefreshFunc(conn, d.Id())() + sgRaw, err := waitForSgToExist(conn, d.Id(), d.Timeout(schema.TimeoutRead)) if err != nil { return err } if sgRaw == nil { + log.Printf("[WARN] Security group (%s) not found, removing from state", d.Id()) d.SetId("") return nil } @@ -840,6 +832,18 @@ func SGStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { } } +func waitForSgToExist(conn *ec2.EC2, id string, timeout time.Duration) (interface{}, error) { + log.Printf("[DEBUG] Waiting for Security Group (%s) to exist", id) + stateConf := &resource.StateChangeConf{ + Pending: []string{""}, + Target: []string{"exists"}, + Refresh: SGStateRefreshFunc(conn, id), + Timeout: timeout, + } + + return stateConf.WaitForState() +} + // matchRules receives the group id, type of rules, and the local / remote maps // of rules. We iterate through the local set of rules trying to find a matching // remote rule, which may be structured differently because of how AWS From 2e41ac6c589befcaf299892ce70392097751884e Mon Sep 17 00:00:00 2001 From: jammerful Date: Fri, 23 Mar 2018 11:17:44 -0400 Subject: [PATCH 2/2] aws/resource_aws_security_group: Only Use waitForSgToExist if Resource is New --- aws/resource_aws_security_group.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_security_group.go b/aws/resource_aws_security_group.go index f487e5fc3945..70fe956045de 100644 --- a/aws/resource_aws_security_group.go +++ b/aws/resource_aws_security_group.go @@ -332,10 +332,18 @@ func resourceAwsSecurityGroupCreate(d *schema.ResourceData, meta interface{}) er func resourceAwsSecurityGroupRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - sgRaw, err := waitForSgToExist(conn, d.Id(), d.Timeout(schema.TimeoutRead)) + var sgRaw interface{} + var err error + if d.IsNewResource() { + sgRaw, err = waitForSgToExist(conn, d.Id(), d.Timeout(schema.TimeoutRead)) + } else { + sgRaw, _, err = SGStateRefreshFunc(conn, d.Id())() + } + if err != nil { return err } + if sgRaw == nil { log.Printf("[WARN] Security group (%s) not found, removing from state", d.Id()) d.SetId("") @@ -384,7 +392,14 @@ func resourceAwsSecurityGroupRead(d *schema.ResourceData, meta interface{}) erro func resourceAwsSecurityGroupUpdate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - sgRaw, err := waitForSgToExist(conn, d.Id(), d.Timeout(schema.TimeoutRead)) + var sgRaw interface{} + var err error + if d.IsNewResource() { + sgRaw, err = waitForSgToExist(conn, d.Id(), d.Timeout(schema.TimeoutRead)) + } else { + sgRaw, _, err = SGStateRefreshFunc(conn, d.Id())() + } + if err != nil { return err }