Skip to content

Commit

Permalink
resource/aws_security_group: Fix Missing Id Error
Browse files Browse the repository at this point in the history
Make security groups more resilient to eventual consistency errors
by adding retries on the existence function in read and update.

See: hashicorp/terraform#6991
  • Loading branch information
jammerful committed Mar 22, 2018
1 parent d3d7ce4 commit ba36727
Showing 1 changed file with 17 additions and 13 deletions.
30 changes: 17 additions & 13 deletions aws/resource_aws_security_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit ba36727

Please sign in to comment.