Skip to content

Commit ca35715

Browse files
committed
Add slice length check to deleteLingeringLambdaENIs to make Lambda Hyperplane ENI work-around conditional
Closes hashicorp#12394
1 parent 04d24f8 commit ca35715

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

aws/resource_aws_security_group.go

+17-9
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,11 @@ func resourceAwsSecurityGroupDelete(d *schema.ResourceData, meta interface{}) er
448448
conn := meta.(*AWSClient).ec2conn
449449

450450
log.Printf("[DEBUG] Security Group destroy: %v", d.Id())
451-
452-
if err := deleteLingeringLambdaENIs(conn, "group-id", d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil {
451+
lingeringLambdaExists := false
452+
if lambdaExists, err := deleteLingeringLambdaENIs(conn, "group-id", d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil {
453453
return fmt.Errorf("error deleting Lambda ENIs using Security Group (%s): %s", d.Id(), err)
454+
} else {
455+
lingeringLambdaExists = lambdaExists
454456
}
455457

456458
// conditionally revoke rules first before attempting to delete the group
@@ -468,7 +470,7 @@ func resourceAwsSecurityGroupDelete(d *schema.ResourceData, meta interface{}) er
468470
if isAWSErr(err, "InvalidGroup.NotFound", "") {
469471
return nil
470472
}
471-
if isAWSErr(err, "DependencyViolation", "") {
473+
if lingeringLambdaExists && isAWSErr(err, "DependencyViolation", "") {
472474
// If it is a dependency violation, we want to retry
473475
return resource.RetryableError(err)
474476
}
@@ -1403,12 +1405,14 @@ func sgProtocolIntegers() map[string]int {
14031405

14041406
// The AWS Lambda service creates ENIs behind the scenes and keeps these around for a while
14051407
// which would prevent SGs attached to such ENIs from being destroyed
1406-
func deleteLingeringLambdaENIs(conn *ec2.EC2, filterName, resourceId string, timeout time.Duration) error {
1408+
func deleteLingeringLambdaENIs(conn *ec2.EC2, filterName, resourceId string, timeout time.Duration) (bool, error) {
14071409
// AWS Lambda service team confirms P99 deletion time of ~35 minutes. Buffer for safety.
14081410
if minimumTimeout := 45 * time.Minute; timeout < minimumTimeout {
14091411
timeout = minimumTimeout
14101412
}
14111413

1414+
lambdaExists := false
1415+
14121416
resp, err := conn.DescribeNetworkInterfaces(&ec2.DescribeNetworkInterfacesInput{
14131417
Filters: buildEC2AttributeFilterList(map[string]string{
14141418
filterName: resourceId,
@@ -1417,7 +1421,11 @@ func deleteLingeringLambdaENIs(conn *ec2.EC2, filterName, resourceId string, tim
14171421
})
14181422

14191423
if err != nil {
1420-
return fmt.Errorf("error describing ENIs: %s", err)
1424+
return lambdaExists, fmt.Errorf("error describing ENIs: %s", err)
1425+
}
1426+
1427+
if len(resp.NetworkInterfaces) > 0 {
1428+
lambdaExists = true
14211429
}
14221430

14231431
for _, eni := range resp.NetworkInterfaces {
@@ -1449,7 +1457,7 @@ func deleteLingeringLambdaENIs(conn *ec2.EC2, filterName, resourceId string, tim
14491457
}
14501458

14511459
if err != nil {
1452-
return fmt.Errorf("error waiting for Lambda V2N ENI (%s) to become available for detachment: %s", eniId, err)
1460+
return lambdaExists, fmt.Errorf("error waiting for Lambda V2N ENI (%s) to become available for detachment: %s", eniId, err)
14531461
}
14541462

14551463
eni = eniRaw.(*ec2.NetworkInterface)
@@ -1458,17 +1466,17 @@ func deleteLingeringLambdaENIs(conn *ec2.EC2, filterName, resourceId string, tim
14581466
err = detachNetworkInterface(conn, eni, timeout)
14591467

14601468
if err != nil {
1461-
return fmt.Errorf("error detaching Lambda ENI (%s): %s", eniId, err)
1469+
return lambdaExists, fmt.Errorf("error detaching Lambda ENI (%s): %s", eniId, err)
14621470
}
14631471

14641472
err = deleteNetworkInterface(conn, eniId)
14651473

14661474
if err != nil {
1467-
return fmt.Errorf("error deleting Lambda ENI (%s): %s", eniId, err)
1475+
return lambdaExists, fmt.Errorf("error deleting Lambda ENI (%s): %s", eniId, err)
14681476
}
14691477
}
14701478

1471-
return nil
1479+
return lambdaExists, nil
14721480
}
14731481

14741482
func initSecurityGroupRule(ruleMap map[string]map[string]interface{}, perm *ec2.IpPermission, desc string) map[string]interface{} {

aws/resource_aws_subnet.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,12 @@ func resourceAwsSubnetDelete(d *schema.ResourceData, meta interface{}) error {
390390

391391
log.Printf("[INFO] Deleting subnet: %s", d.Id())
392392

393-
if err := deleteLingeringLambdaENIs(conn, "subnet-id", d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil {
393+
lingeringLambdaExists := false
394+
395+
if lambdaExists, err := deleteLingeringLambdaENIs(conn, "subnet-id", d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil {
394396
return fmt.Errorf("error deleting Lambda ENIs using subnet (%s): %s", d.Id(), err)
397+
} else {
398+
lingeringLambdaExists = lambdaExists
395399
}
396400

397401
req := &ec2.DeleteSubnetInput{
@@ -407,7 +411,7 @@ func resourceAwsSubnetDelete(d *schema.ResourceData, meta interface{}) error {
407411
_, err := conn.DeleteSubnet(req)
408412
if err != nil {
409413
if apiErr, ok := err.(awserr.Error); ok {
410-
if apiErr.Code() == "DependencyViolation" {
414+
if lingeringLambdaExists && apiErr.Code() == "DependencyViolation" {
411415
// There is some pending operation, so just retry
412416
// in a bit.
413417
return 42, "pending", nil

0 commit comments

Comments
 (0)