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

resource/aws_ec2_transit_gateway_route_table_propagation: Wait for enable and disable operations to complete #18470

Merged
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/18470.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_ec2_transit_gateway_route_table_propagation: Wait for enable and disable operations to complete
```
35 changes: 35 additions & 0 deletions aws/internal/service/ec2/finder/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,41 @@ func TransitGatewayPrefixListReferenceByID(conn *ec2.EC2, resourceID string) (*e
return TransitGatewayPrefixListReference(conn, transitGatewayRouteTableID, prefixListID)
}

func TransitGatewayRouteTablePropagation(conn *ec2.EC2, transitGatewayRouteTableID string, transitGatewayAttachmentID string) (*ec2.TransitGatewayRouteTablePropagation, error) {
input := &ec2.GetTransitGatewayRouteTablePropagationsInput{
Filters: []*ec2.Filter{
{
Name: aws.String("transit-gateway-attachment-id"),
Values: aws.StringSlice([]string{transitGatewayAttachmentID}),
},
},
TransitGatewayRouteTableId: aws.String(transitGatewayRouteTableID),
}

var result *ec2.TransitGatewayRouteTablePropagation

err := conn.GetTransitGatewayRouteTablePropagationsPages(input, func(page *ec2.GetTransitGatewayRouteTablePropagationsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, transitGatewayRouteTablePropagation := range page.TransitGatewayRouteTablePropagations {
if transitGatewayRouteTablePropagation == nil {
continue
}

if aws.StringValue(transitGatewayRouteTablePropagation.TransitGatewayAttachmentId) == transitGatewayAttachmentID {
result = transitGatewayRouteTablePropagation
return false
}
}

return !lastPage
})

return result, err
}

// VpcAttribute looks up a VPC attribute.
func VpcAttribute(conn *ec2.EC2, vpcID string, attribute string) (*bool, error) {
input := &ec2.DescribeVpcAttributeInput{
Expand Down
16 changes: 16 additions & 0 deletions aws/internal/service/ec2/waiter/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,22 @@ func TransitGatewayPrefixListReferenceState(conn *ec2.EC2, transitGatewayRouteTa
}
}

func TransitGatewayRouteTablePropagationState(conn *ec2.EC2, transitGatewayRouteTableID string, transitGatewayAttachmentID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
transitGatewayRouteTablePropagation, err := finder.TransitGatewayRouteTablePropagation(conn, transitGatewayRouteTableID, transitGatewayAttachmentID)

if err != nil {
return nil, "", err
}

if transitGatewayRouteTablePropagation == nil {
return nil, "", nil
}

return transitGatewayRouteTablePropagation, aws.StringValue(transitGatewayRouteTablePropagation.State), nil
}
}

// VpcAttribute fetches the Vpc and its attribute value
func VpcAttribute(conn *ec2.EC2, id string, attribute string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
Expand Down
42 changes: 42 additions & 0 deletions aws/internal/service/ec2/waiter/waiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,48 @@ func TransitGatewayPrefixListReferenceStateUpdated(conn *ec2.EC2, transitGateway
return nil, err
}

const (
TransitGatewayRouteTablePropagationTimeout = 5 * time.Minute
)

func TransitGatewayRouteTablePropagationStateEnabled(conn *ec2.EC2, transitGatewayRouteTableID string, transitGatewayAttachmentID string) (*ec2.TransitGatewayRouteTablePropagation, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{ec2.TransitGatewayPropagationStateEnabling},
Target: []string{ec2.TransitGatewayPropagationStateEnabled},
Timeout: TransitGatewayRouteTablePropagationTimeout,
Refresh: TransitGatewayRouteTablePropagationState(conn, transitGatewayRouteTableID, transitGatewayAttachmentID),
}

outputRaw, err := stateConf.WaitForState()

if output, ok := outputRaw.(*ec2.TransitGatewayRouteTablePropagation); ok {
return output, err
}

return nil, err
}

func TransitGatewayRouteTablePropagationStateDisabled(conn *ec2.EC2, transitGatewayRouteTableID string, transitGatewayAttachmentID string) (*ec2.TransitGatewayRouteTablePropagation, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{ec2.TransitGatewayPropagationStateDisabling},
Target: []string{},
Timeout: TransitGatewayRouteTablePropagationTimeout,
Refresh: TransitGatewayRouteTablePropagationState(conn, transitGatewayRouteTableID, transitGatewayAttachmentID),
}

outputRaw, err := stateConf.WaitForState()

if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidRouteTableIDNotFound) {
return nil, nil
}

if output, ok := outputRaw.(*ec2.TransitGatewayRouteTablePropagation); ok {
return output, err
}

return nil, err
}

const (
VpcPropagationTimeout = 2 * time.Minute
VpcAttributePropagationTimeout = 5 * time.Minute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/waiter"
)

func resourceAwsEc2TransitGatewayRouteTablePropagation() *schema.Resource {
Expand Down Expand Up @@ -62,6 +65,10 @@ func resourceAwsEc2TransitGatewayRouteTablePropagationCreate(d *schema.ResourceD

d.SetId(fmt.Sprintf("%s_%s", transitGatewayRouteTableID, transitGatewayAttachmentID))

if _, err := waiter.TransitGatewayRouteTablePropagationStateEnabled(conn, transitGatewayRouteTableID, transitGatewayAttachmentID); err != nil {
return fmt.Errorf("error waiting for EC2 Transit Gateway Route Table (%s) propagation (%s) to enable: %w", transitGatewayRouteTableID, transitGatewayAttachmentID, err)
}

return resourceAwsEc2TransitGatewayRouteTablePropagationRead(d, meta)
}

Expand All @@ -75,7 +82,7 @@ func resourceAwsEc2TransitGatewayRouteTablePropagationRead(d *schema.ResourceDat

transitGatewayPropagation, err := ec2DescribeTransitGatewayRouteTablePropagation(conn, transitGatewayRouteTableID, transitGatewayAttachmentID)

if isAWSErr(err, "InvalidRouteTableID.NotFound", "") {
if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidRouteTableIDNotFound) {
log.Printf("[WARN] EC2 Transit Gateway Route Table (%s) not found, removing from state", transitGatewayRouteTableID)
d.SetId("")
return nil
Expand All @@ -86,6 +93,10 @@ func resourceAwsEc2TransitGatewayRouteTablePropagationRead(d *schema.ResourceDat
}

if transitGatewayPropagation == nil {
if d.IsNewResource() {
return fmt.Errorf("error reading EC2 Transit Gateway Route Table (%s) Propagation (%s): not found after creation", transitGatewayRouteTableID, transitGatewayAttachmentID)
}

log.Printf("[WARN] EC2 Transit Gateway Route Table (%s) Propagation (%s) not found, removing from state", transitGatewayRouteTableID, transitGatewayAttachmentID)
d.SetId("")
return nil
Expand Down Expand Up @@ -123,5 +134,9 @@ func resourceAwsEc2TransitGatewayRouteTablePropagationDelete(d *schema.ResourceD
return fmt.Errorf("error disabling EC2 Transit Gateway Route Table (%s) Propagation (%s): %s", transitGatewayRouteTableID, transitGatewayAttachmentID, err)
}

if _, err := waiter.TransitGatewayRouteTablePropagationStateDisabled(conn, transitGatewayRouteTableID, transitGatewayAttachmentID); err != nil {
return fmt.Errorf("error waiting for EC2 Transit Gateway Route Table (%s) propagation (%s) to disable: %w", transitGatewayRouteTableID, transitGatewayAttachmentID, err)
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
Expand Down Expand Up @@ -69,6 +70,10 @@ func testAccCheckAWSEc2TransitGatewayRouteTablePropagationExists(resourceName st
return fmt.Errorf("EC2 Transit Gateway Route Table Propagation not found")
}

if aws.StringValue(propagation.State) != ec2.TransitGatewayPropagationStateEnabled {
return fmt.Errorf("EC2 Transit Gateway Route Table Propagation not in enabled state: %s", aws.StringValue(propagation.State))
}

*transitGatewayRouteTablePropagation = *propagation

return nil
Expand Down