diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 0ac123351208..4a26060ecab1 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -385,20 +385,21 @@ func Provider() terraform.ResourceProvider { "aws_vpc_dhcp_options_association": resourceAwsVpcDhcpOptionsAssociation(), "aws_vpc_dhcp_options": resourceAwsVpcDhcpOptions(), "aws_vpc_peering_connection": resourceAwsVpcPeeringConnection(), - "aws_vpc": resourceAwsVpc(), - "aws_vpc_endpoint": resourceAwsVpcEndpoint(), - "aws_vpc_endpoint_route_table_association": resourceAwsVpcEndpointRouteTableAssociation(), - "aws_vpn_connection": resourceAwsVpnConnection(), - "aws_vpn_connection_route": resourceAwsVpnConnectionRoute(), - "aws_vpn_gateway": resourceAwsVpnGateway(), - "aws_vpn_gateway_attachment": resourceAwsVpnGatewayAttachment(), - "aws_waf_byte_match_set": resourceAwsWafByteMatchSet(), - "aws_waf_ipset": resourceAwsWafIPSet(), - "aws_waf_rule": resourceAwsWafRule(), - "aws_waf_size_constraint_set": resourceAwsWafSizeConstraintSet(), - "aws_waf_web_acl": resourceAwsWafWebAcl(), - "aws_waf_xss_match_set": resourceAwsWafXssMatchSet(), - "aws_waf_sql_injection_match_set": resourceAwsWafSqlInjectionMatchSet(), + "aws_vpc_peering_connection_accepter": resourceAwsVpcPeeringConnectionAccepter(), + "aws_vpc": resourceAwsVpc(), + "aws_vpc_endpoint": resourceAwsVpcEndpoint(), + "aws_vpc_endpoint_route_table_association": resourceAwsVpcEndpointRouteTableAssociation(), + "aws_vpn_connection": resourceAwsVpnConnection(), + "aws_vpn_connection_route": resourceAwsVpnConnectionRoute(), + "aws_vpn_gateway": resourceAwsVpnGateway(), + "aws_vpn_gateway_attachment": resourceAwsVpnGatewayAttachment(), + "aws_waf_byte_match_set": resourceAwsWafByteMatchSet(), + "aws_waf_ipset": resourceAwsWafIPSet(), + "aws_waf_rule": resourceAwsWafRule(), + "aws_waf_size_constraint_set": resourceAwsWafSizeConstraintSet(), + "aws_waf_web_acl": resourceAwsWafWebAcl(), + "aws_waf_xss_match_set": resourceAwsWafXssMatchSet(), + "aws_waf_sql_injection_match_set": resourceAwsWafSqlInjectionMatchSet(), }, ConfigureFunc: providerConfigure, } diff --git a/builtin/providers/aws/resource_aws_vpc_peering_connection_accepter.go b/builtin/providers/aws/resource_aws_vpc_peering_connection_accepter.go new file mode 100644 index 000000000000..8b1efff50c35 --- /dev/null +++ b/builtin/providers/aws/resource_aws_vpc_peering_connection_accepter.go @@ -0,0 +1,76 @@ +package aws + +import ( + "errors" + "log" + + "fmt" + + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsVpcPeeringConnectionAccepter() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsVPCPeeringAccepterCreate, + Read: resourceAwsVPCPeeringRead, + Update: resourceAwsVPCPeeringUpdate, + Delete: resourceAwsVPCPeeringAccepterDelete, + + Schema: map[string]*schema.Schema{ + "vpc_peering_connection_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + Computed: false, + }, + "auto_accept": { + Type: schema.TypeBool, + Optional: true, + }, + "accept_status": { + Type: schema.TypeString, + Computed: true, + }, + "vpc_id": { + Type: schema.TypeString, + Computed: true, + }, + "peer_vpc_id": { + Type: schema.TypeString, + Computed: true, + }, + "peer_owner_id": { + Type: schema.TypeString, + Computed: true, + }, + "accepter": vpcPeeringConnectionOptionsSchema(), + "requester": vpcPeeringConnectionOptionsSchema(), + "tags": tagsSchema(), + }, + } +} + +func resourceAwsVPCPeeringAccepterCreate(d *schema.ResourceData, meta interface{}) error { + id := d.Get("vpc_peering_connection_id").(string) + d.SetId(id) + + if err := resourceAwsVPCPeeringRead(d, meta); err != nil { + return err + } + if d.Id() == "" { + 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) +} + +func resourceAwsVPCPeeringAccepterDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARN] Will not delete VPC peering connection. Terraform will remove this resource from the state file, however resources may remain.") + d.SetId("") + return nil +} diff --git a/builtin/providers/aws/resource_aws_vpc_peering_connection_accepter_test.go b/builtin/providers/aws/resource_aws_vpc_peering_connection_accepter_test.go new file mode 100644 index 000000000000..74b899c4ebaa --- /dev/null +++ b/builtin/providers/aws/resource_aws_vpc_peering_connection_accepter_test.go @@ -0,0 +1,78 @@ +// make testacc TEST=./builtin/providers/aws/ TESTARGS='-run=TestAccAwsVPCPeeringConnectionAccepter_' +package aws + +import ( + "regexp" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAwsVPCPeeringConnectionAccepter_sameAccount(t *testing.T) { + 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`), + }, + }, + }) +} + +func testAccAwsVPCPeeringConnectionAccepterDestroy(s *terraform.State) error { + // We don't destroy the underlying VPC Peering Connection. + return nil +} + +const testAccAwsVPCPeeringConnectionAccepterSameAccountConfig = ` +provider "aws" { + region = "us-west-2" + // Requester's credentials. +} + +provider "aws" { + alias = "peer" + region = "us-west-2" + // Accepter's credentials. +} + +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_vpc" "peer" { + provider = "aws.peer" + cidr_block = "10.1.0.0/16" +} + +data "aws_caller_identity" "peer" { + provider = "aws.peer" +} + +// 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" + } +} + +// 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" + } +} +` diff --git a/website/source/docs/providers/aws/r/vpc_peering.html.markdown b/website/source/docs/providers/aws/r/vpc_peering.html.markdown index a74a0ceec17b..3a0dd9310dba 100644 --- a/website/source/docs/providers/aws/r/vpc_peering.html.markdown +++ b/website/source/docs/providers/aws/r/vpc_peering.html.markdown @@ -3,12 +3,16 @@ layout: "aws" page_title: "AWS: aws_vpc_peering_connection" sidebar_current: "docs-aws-resource-vpc-peering" description: |- - Provides an VPC Peering Connection resource. + Manage a VPC Peering Connection resource. --- # aws\_vpc\_peering\_connection -Provides an VPC Peering Connection resource. +Provides a resource to manage a VPC Peering Connection resource. + +-> **Note:** For cross-account (requester's AWS account differs from the accepter's AWS account) VPC Peering Connections +use the `aws_vpc_peering_connection` resource to manage the requester's side of the connection and +use the `aws_vpc_peering_connection_accepter` resource to manage the accepter's side of the connection. ## Example Usage @@ -112,9 +116,9 @@ The following attributes are exported: AWS only supports VPC peering within the same AWS region. -If both VPCs are not in the same AWS account do not enable the `auto_accept` attribute. You will still -have to accept the VPC Peering Connection request manually using the AWS Management Console, AWS CLI, -through SDKs, etc. +If both VPCs are not in the same AWS account do not enable the `auto_accept` attribute. +The accepter can manage its side of the connection using the `aws_vpc_peering_connection_accepter` resource +or accept the connection manually using the AWS Management Console, AWS CLI, through SDKs, etc. ## Import diff --git a/website/source/docs/providers/aws/r/vpc_peering_accepter.html.markdown b/website/source/docs/providers/aws/r/vpc_peering_accepter.html.markdown new file mode 100644 index 000000000000..a2739b73b19f --- /dev/null +++ b/website/source/docs/providers/aws/r/vpc_peering_accepter.html.markdown @@ -0,0 +1,105 @@ +--- +layout: "aws" +page_title: "AWS: aws_vpc_peering_connection_accepter" +sidebar_current: "docs-aws-resource-vpc-peering-accepter" +description: |- + Manage the accepter's side of a cross-account VPC Peering Connection. +--- + +# aws\_vpc\_peering\_connection\_accepter + +Provides a resource to manage the accepter's side of a cross-account VPC Peering Connection. + +When a cross-account (requester's AWS account differs from the accepter's AWS account) VPC Peering Connection +is created, a VPC Peering Connection resource is automatically created in the accepter's account. +The requester can use the `aws_vpc_peering_connection` resource to manage its side of the connection +and the accepter can use the `aws_vpc_peering_connection_accepter` resource to "adopt" its side of the +connection into management. + +## Example Usage + +``` +provider "aws" { + // Requester's credentials. +} + +provider "aws" { + alias = "peer" + // Accepter's credentials. +} + +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_vpc" "peer" { + provider = "aws.peer" + cidr_block = "10.1.0.0/16" +} + +data "aws_caller_identity" "peer" { + provider = "aws.peer" +} + +// 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" + } +} + +// 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" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `vpc_peering_connection_id` - (Required) The VPC Peering Connection ID to manage. +* `auto_accept` - (Optional) Whether or not to accept the peering request. Defaults to `false`. +* `tags` - (Optional) A mapping of tags to assign to the resource. + +### Removing `aws_vpc_peering_connection_accepter` from your configuration + +AWS allows a cross-account VPC Peering Connection to be deleted from either the requester's or accepter's side. +However, Terraform only allows the VPC Peering Connection to be deleted from the requester's side +by removing the corresponding `aws_vpc_peering_connection` resource from your configuration. +Removing a `aws_vpc_peering_connection_accepter` resource from your configuration will remove it +from your statefile and management, **but will not destroy the VPC Peering Connection.** + +## Attributes Reference + +All of the argument attributes except `auto_accept` are also exported as result attributes. + +* `id` - The ID of the VPC Peering Connection. +* `accept_status` - The status of the VPC Peering Connection request. +* `vpc_id` - The ID of the accepter VPC. +* `peer_vpc_id` - The ID of the requester VPC. +* `peer_owner_id` - The AWS account ID of the owner of the requester VPC. +* `accepter` - A configuration block that describes [VPC Peering Connection] +(http://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide) options set for the accepter VPC. +* `requester` - A configuration block that describes [VPC Peering Connection] +(http://docs.aws.amazon.com/AmazonVPC/latest/PeeringGuide) options set for the requester VPC. + +#### Accepter and Requester Attributes Reference + +* `allow_remote_vpc_dns_resolution` - Indicates whether a local VPC can resolve public DNS hostnames to +private IP addresses when queried from instances in a peer VPC. +* `allow_classic_link_to_remote_vpc` - Indicates whether a local ClassicLink connection can communicate +with the peer VPC over the VPC Peering Connection. +* `allow_vpc_to_remote_classic_link` - Indicates whether a local VPC can communicate with a ClassicLink +connection in the peer VPC over the VPC Peering Connection. diff --git a/website/source/layouts/aws.erb b/website/source/layouts/aws.erb index 6679e96adeba..9bec425b1eee 100644 --- a/website/source/layouts/aws.erb +++ b/website/source/layouts/aws.erb @@ -1172,6 +1172,10 @@ aws_vpc_peering_connection +