Merge pull request #9038 from kwilczynski/feature/error-reporting-aws_vpc_peering_connection

provider/aws: Make sure that VPC Peering Connection in a failed state returns an error.
This commit is contained in:
Paul Stack 2016-09-27 17:56:54 +01:00 committed by GitHub
commit 1cf9f41510
2 changed files with 65 additions and 21 deletions

View File

@ -1,6 +1,7 @@
package aws
import (
"errors"
"fmt"
"log"
"time"
@ -24,27 +25,27 @@ func resourceAwsVpcPeeringConnection() *schema.Resource {
},
Schema: map[string]*schema.Schema{
"peer_owner_id": &schema.Schema{
"peer_owner_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"peer_vpc_id": &schema.Schema{
"peer_vpc_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"vpc_id": &schema.Schema{
"vpc_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"auto_accept": &schema.Schema{
"auto_accept": {
Type: schema.TypeBool,
Optional: true,
},
"accept_status": &schema.Schema{
"accept_status": {
Type: schema.TypeString,
Computed: true,
},
@ -89,9 +90,9 @@ func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error
Timeout: 1 * time.Minute,
}
if _, err := stateConf.WaitForState(); err != nil {
return fmt.Errorf(
"Error waiting for VPC Peering Connection (%s) to become available: %s",
d.Id(), err)
return errwrap.Wrapf(fmt.Sprintf(
"Error waiting for VPC Peering Connection (%s) to become available: {{err}}",
d.Id()), err)
}
return resourceAwsVPCPeeringUpdate(d, meta)
@ -99,8 +100,10 @@ func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error
func resourceAwsVPCPeeringRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ec2conn
pcRaw, _, err := resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id())()
if err != nil {
pcRaw, status, err := resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id())()
// Allow a failed VPC Peering Connection to fallthrough,
// to allow rest of the logic below to do its work.
if err != nil && status != "failed" {
return err
}
@ -139,23 +142,23 @@ func resourceAwsVPCPeeringRead(d *schema.ResourceData, meta interface{}) error {
// When the VPC Peering Connection is pending acceptance,
// the details about accepter and/or requester peering
// options would not be included in the response.
if pc.AccepterVpcInfo != nil && pc.AccepterVpcInfo.PeeringOptions != nil {
if pc.AccepterVpcInfo.PeeringOptions != nil {
err := d.Set("accepter", flattenPeeringOptions(pc.AccepterVpcInfo.PeeringOptions))
if err != nil {
log.Printf("[ERR] Error setting VPC Peering connection accepter information: %s", err)
return errwrap.Wrapf("Error setting VPC Peering Connection accepter information: {{err}}", err)
}
}
if pc.RequesterVpcInfo != nil && pc.RequesterVpcInfo.PeeringOptions != nil {
if pc.RequesterVpcInfo.PeeringOptions != nil {
err := d.Set("requester", flattenPeeringOptions(pc.RequesterVpcInfo.PeeringOptions))
if err != nil {
log.Printf("[ERR] Error setting VPC Peering connection requester information: %s", err)
return errwrap.Wrapf("Error setting VPC Peering Connection requester information: {{err}}", err)
}
}
err = d.Set("tags", tagsToMap(pc.Tags))
if err != nil {
return err
return errwrap.Wrapf("Error setting VPC Peering Connection tags: {{err}}", err)
}
return nil
@ -219,6 +222,7 @@ func resourceAwsVPCPeeringUpdate(d *schema.ResourceData, meta interface{}) error
if err != nil {
return err
}
if pcRaw == nil {
d.SetId("")
return nil
@ -229,7 +233,7 @@ func resourceAwsVPCPeeringUpdate(d *schema.ResourceData, meta interface{}) error
if pc.Status != nil && *pc.Status.Code == "pending-acceptance" {
status, err := resourceVPCPeeringConnectionAccept(conn, d.Id())
if err != nil {
return err
return errwrap.Wrapf("Unable to accept VPC Peering Connection: {{err}}", err)
}
log.Printf("[DEBUG] VPC Peering Connection accept status: %s", status)
}
@ -266,7 +270,6 @@ func resourceAwsVPCPeeringDelete(d *schema.ResourceData, meta interface{}) error
// a VPCPeeringConnection.
func resourceAwsVPCPeeringConnectionStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
resp, err := conn.DescribeVpcPeeringConnections(&ec2.DescribeVpcPeeringConnectionsInput{
VpcPeeringConnectionIds: []*string{aws.String(id)},
})
@ -275,7 +278,7 @@ func resourceAwsVPCPeeringConnectionStateRefreshFunc(conn *ec2.EC2, id string) r
resp = nil
} else {
log.Printf("Error reading VPC Peering Connection details: %s", err)
return nil, "", err
return nil, "error", err
}
}
@ -287,6 +290,13 @@ func resourceAwsVPCPeeringConnectionStateRefreshFunc(conn *ec2.EC2, id string) r
pc := resp.VpcPeeringConnections[0]
// A VPC Peering Connection can exist in a failed state due to
// incorrect VPC ID, account ID, or overlapping IP address range,
// thus we short circuit before the time out would occur.
if pc != nil && *pc.Status.Code == "failed" {
return nil, "failed", errors.New(*pc.Status.Message)
}
return pc, *pc.Status.Code, nil
}
}
@ -299,17 +309,17 @@ func vpcPeeringConnectionOptionsSchema() *schema.Schema {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"allow_remote_vpc_dns_resolution": &schema.Schema{
"allow_remote_vpc_dns_resolution": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"allow_classic_link_to_remote_vpc": &schema.Schema{
"allow_classic_link_to_remote_vpc": {
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"allow_vpc_to_remote_classic_link": &schema.Schema{
"allow_vpc_to_remote_classic_link": {
Type: schema.TypeBool,
Optional: true,
Default: false,

View File

@ -4,6 +4,7 @@ import (
"fmt"
"log"
"reflect"
"regexp"
"testing"
"github.com/aws/aws-sdk-go/aws"
@ -190,6 +191,21 @@ func TestAccAWSVPCPeeringConnection_options(t *testing.T) {
})
}
func TestAccAWSVPCPeeringConnection_failedState(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshIgnore: []string{"auto_accept"},
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSVpcPeeringConnectionDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccVpcPeeringConfigFailedState,
ExpectError: regexp.MustCompile(`.*Error waiting.*\(pcx-\w+\).*incorrect.*VPC-ID.*`),
},
},
})
}
func testAccCheckAWSVpcPeeringConnectionDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ec2conn
@ -368,3 +384,21 @@ resource "aws_vpc_peering_connection" "foo" {
}
}
`
const testAccVpcPeeringConfigFailedState = `
resource "aws_vpc" "foo" {
cidr_block = "10.0.0.0/16"
tags {
Name = "TestAccAWSVPCPeeringConnection_failedState"
}
}
resource "aws_vpc" "bar" {
cidr_block = "10.0.0.0/16"
}
resource "aws_vpc_peering_connection" "foo" {
vpc_id = "${aws_vpc.foo.id}"
peer_vpc_id = "${aws_vpc.bar.id}"
}
`