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

Add peer_region to vpc peering connection #2508

Merged
merged 10 commits into from
Jan 8, 2018
12 changes: 12 additions & 0 deletions aws/data_source_aws_vpc_peering_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ func dataSourceAwsVpcPeeringConnection() *schema.Resource {
Optional: true,
Computed: true,
},
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"peer_vpc_id": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -54,6 +59,11 @@ func dataSourceAwsVpcPeeringConnection() *schema.Resource {
Optional: true,
Computed: true,
},
"peer_region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"accepter": {
Type: schema.TypeMap,
Computed: true,
Expand Down Expand Up @@ -121,9 +131,11 @@ func dataSourceAwsVpcPeeringConnectionRead(d *schema.ResourceData, meta interfac
d.Set("vpc_id", pcx.RequesterVpcInfo.VpcId)
d.Set("owner_id", pcx.RequesterVpcInfo.OwnerId)
d.Set("cidr_block", pcx.RequesterVpcInfo.CidrBlock)
d.Set("region", pcx.RequesterVpcInfo.Region)
d.Set("peer_vpc_id", pcx.AccepterVpcInfo.VpcId)
d.Set("peer_owner_id", pcx.AccepterVpcInfo.OwnerId)
d.Set("peer_cidr_block", pcx.AccepterVpcInfo.CidrBlock)
d.Set("peer_region", pcx.AccepterVpcInfo.Region)
d.Set("tags", tagsToMap(pcx.Tags))

if pcx.AccepterVpcInfo.PeeringOptions != nil {
Expand Down
65 changes: 53 additions & 12 deletions aws/resource_aws_vpc_peering_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ func resourceAwsVpcPeeringConnection() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"peer_region": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"accepter": vpcPeeringConnectionOptionsSchema(),
"requester": vpcPeeringConnectionOptionsSchema(),
"tags": tagsSchema(),
Expand All @@ -69,6 +75,13 @@ func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error
createOpts.PeerOwnerId = aws.String(v.(string))
}

if v, ok := d.GetOk("peer_region"); ok {
if _, ok := d.GetOk("auto_accept"); ok {
return fmt.Errorf("peer_region cannot be set whilst auto_accept is true when creating a vpc peering connection")
}
createOpts.PeerRegion = aws.String(v.(string))
}

log.Printf("[DEBUG] VPC Peering Create options: %#v", createOpts)

resp, err := conn.CreateVpcPeeringConnection(createOpts)
Expand All @@ -81,18 +94,9 @@ func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error
d.SetId(*rt.VpcPeeringConnectionId)
log.Printf("[INFO] VPC Peering Connection ID: %s", d.Id())

// Wait for the vpc peering connection to become available
log.Printf("[DEBUG] Waiting for VPC Peering Connection (%s) to become available.", d.Id())
stateConf := &resource.StateChangeConf{
Pending: []string{"initiating-request", "provisioning", "pending"},
Target: []string{"pending-acceptance", "active"},
Refresh: resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id()),
Timeout: 1 * time.Minute,
}
if _, err := stateConf.WaitForState(); err != nil {
return errwrap.Wrapf(fmt.Sprintf(
"Error waiting for VPC Peering Connection (%s) to become available: {{err}}",
d.Id()), err)
vpcAvailableErr := checkVpcPeeringConnectionAvailable(conn, d.Id())
if vpcAvailableErr != nil {
return errwrap.Wrapf("Error waiting for VPC Peering Connection to become available: {{err}}", vpcAvailableErr)
}

return resourceAwsVPCPeeringUpdate(d, meta)
Expand Down Expand Up @@ -151,6 +155,7 @@ func resourceAwsVPCPeeringRead(d *schema.ResourceData, meta interface{}) error {
d.Set("vpc_id", pc.RequesterVpcInfo.VpcId)
}

d.Set("peer_region", pc.AccepterVpcInfo.Region)
d.Set("accept_status", pc.Status.Code)

// When the VPC Peering Connection is pending acceptance,
Expand Down Expand Up @@ -266,6 +271,11 @@ func resourceAwsVPCPeeringUpdate(d *schema.ResourceData, meta interface{}) error
}
}

vpcAvailableErr := checkVpcPeeringConnectionAvailable(conn, d.Id())
if vpcAvailableErr != nil {
return errwrap.Wrapf("Error waiting for VPC Peering Connection to become available: {{err}}", vpcAvailableErr)
}

return resourceAwsVPCPeeringRead(d, meta)
}

Expand All @@ -277,6 +287,20 @@ func resourceAwsVPCPeeringDelete(d *schema.ResourceData, meta interface{}) error
VpcPeeringConnectionId: aws.String(d.Id()),
})

// Wait for the vpc peering connection to become available
log.Printf("[DEBUG] Waiting for VPC Peering Connection (%s) to delete.", d.Id())
stateConf := &resource.StateChangeConf{
Pending: []string{"deleting"},
Target: []string{"rejecting", "deleted"},
Refresh: resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id()),
Timeout: 1 * time.Minute,
}
if _, err := stateConf.WaitForState(); err != nil {
return errwrap.Wrapf(fmt.Sprintf(
"Error waiting for VPC Peering Connection (%s) to be deleted: {{err}}",
d.Id()), err)
}

return err
}

Expand Down Expand Up @@ -379,3 +403,20 @@ func expandPeeringOptions(m map[string]interface{}) *ec2.PeeringConnectionOption

return r
}

func checkVpcPeeringConnectionAvailable(conn *ec2.EC2, id string) error {
// Wait for the vpc peering connection to become available
log.Printf("[DEBUG] Waiting for VPC Peering Connection (%s) to become available.", id)
stateConf := &resource.StateChangeConf{
Pending: []string{"initiating-request", "provisioning", "pending"},
Target: []string{"pending-acceptance", "active"},
Refresh: resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, id),
Timeout: 1 * time.Minute,
}
if _, err := stateConf.WaitForState(); err != nil {
return errwrap.Wrapf(fmt.Sprintf(
"Error waiting for VPC Peering Connection (%s) to become available: {{err}}",
id), err)
}
return nil
}
10 changes: 4 additions & 6 deletions aws/resource_aws_vpc_peering_connection_accepter.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package aws

import (
"errors"
"log"

"fmt"
Expand Down Expand Up @@ -43,6 +42,10 @@ func resourceAwsVpcPeeringConnectionAccepter() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"peer_region": {
Type: schema.TypeString,
Computed: true,
},
"accepter": vpcPeeringConnectionOptionsSchema(),
"requester": vpcPeeringConnectionOptionsSchema(),
"tags": tagsSchema(),
Expand All @@ -61,11 +64,6 @@ func resourceAwsVPCPeeringAccepterCreate(d *schema.ResourceData, meta interface{
return fmt.Errorf("VPC Peering Connection %q not found", id)
}

// Ensure that this IS as cross-account VPC peering connection.
if d.Get("peer_owner_id").(string) == meta.(*AWSClient).accountid {
return errors.New("aws_vpc_peering_connection_accepter can only adopt into management cross-account VPC peering connections")
}

return resourceAwsVPCPeeringUpdate(d, meta)
}

Expand Down
130 changes: 98 additions & 32 deletions aws/resource_aws_vpc_peering_connection_accepter_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,64 @@
package aws

import (
"regexp"
"testing"

"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsVPCPeeringConnectionAccepter_sameAccount(t *testing.T) {
func TestAccAWSVPCPeeringConnectionAccepter_sameRegion(t *testing.T) {
var connection ec2.VpcPeeringConnection

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccAwsVPCPeeringConnectionAccepterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAwsVPCPeeringConnectionAccepterSameAccountConfig,
ExpectError: regexp.MustCompile(`aws_vpc_peering_connection_accepter can only adopt into management cross-account VPC peering connections`),
Config: testAccAwsVPCPeeringConnectionAccepterSameRegion,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSVpcPeeringConnectionExists(
"aws_vpc_peering_connection_accepter.peer",
&connection),
resource.TestCheckResourceAttr(
"aws_vpc_peering_connection_accepter.peer",
"accept_status", "active"),
),
},
},
})
}

func TestAccAWSVPCPeeringConnectionAccepter_differentRegion(t *testing.T) {
var connection ec2.VpcPeeringConnection

var providers []*schema.Provider
providerFactories := map[string]terraform.ResourceProviderFactory{
"aws": func() (terraform.ResourceProvider, error) {
p := Provider()
providers = append(providers, p.(*schema.Provider))
return p, nil
},
}

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
CheckDestroy: testAccAwsVPCPeeringConnectionAccepterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAwsVPCPeeringConnectionAccepterDifferentRegion,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSVpcPeeringConnectionExists(
"aws_vpc_peering_connection_accepter.peer",
&connection),
resource.TestCheckResourceAttr(
"aws_vpc_peering_connection_accepter.peer",
"accept_status", "active"),
),
},
},
})
Expand All @@ -27,51 +69,75 @@ func testAccAwsVPCPeeringConnectionAccepterDestroy(s *terraform.State) error {
return nil
}

const testAccAwsVPCPeeringConnectionAccepterSameAccountConfig = `
const testAccAwsVPCPeeringConnectionAccepterSameRegion = `
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags {
Name = "tf-acc-revoke-vpc-peering-connection-accepter-same-region"
}
}

resource "aws_vpc" "peer" {
cidr_block = "10.1.0.0/16"
tags {
Name = "tf-acc-revoke-vpc-peering-connection-accepter-same-region"
}
}

// Requester's side of the connection.
resource "aws_vpc_peering_connection" "peer" {
vpc_id = "${aws_vpc.main.id}"
peer_vpc_id = "${aws_vpc.peer.id}"
auto_accept = false
}

// Accepter's side of the connection.
resource "aws_vpc_peering_connection_accepter" "peer" {
vpc_peering_connection_id = "${aws_vpc_peering_connection.peer.id}"
auto_accept = true
}
`

const testAccAwsVPCPeeringConnectionAccepterDifferentRegion = `
provider "aws" {
region = "us-west-2"
// Requester's credentials.
alias = "main"
region = "us-west-2"
}

provider "aws" {
alias = "peer"
region = "us-west-2"
// Accepter's credentials.
alias = "peer"
region = "us-east-1"
}

resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
provider = "aws.main"
cidr_block = "10.0.0.0/16"
tags {
Name = "tf-acc-revoke-vpc-peering-connection-accepter-different-region"
}
}

resource "aws_vpc" "peer" {
provider = "aws.peer"
cidr_block = "10.1.0.0/16"
}

data "aws_caller_identity" "peer" {
provider = "aws.peer"
provider = "aws.peer"
cidr_block = "10.1.0.0/16"
tags {
Name = "tf-acc-revoke-vpc-peering-connection-accepter-different-region"
}
}

// Requester's side of the connection.
resource "aws_vpc_peering_connection" "peer" {
vpc_id = "${aws_vpc.main.id}"
peer_vpc_id = "${aws_vpc.peer.id}"
peer_owner_id = "${data.aws_caller_identity.peer.account_id}"
auto_accept = false

tags {
Side = "Requester"
}
provider = "aws.main"
vpc_id = "${aws_vpc.main.id}"
peer_vpc_id = "${aws_vpc.peer.id}"
peer_region = "us-east-1"
auto_accept = false
}

// Accepter's side of the connection.
resource "aws_vpc_peering_connection_accepter" "peer" {
provider = "aws.peer"
vpc_peering_connection_id = "${aws_vpc_peering_connection.peer.id}"
auto_accept = true

tags {
Side = "Accepter"
}
provider = "aws.peer"
vpc_peering_connection_id = "${aws_vpc_peering_connection.peer.id}"
auto_accept = true
}
`
Loading