github.com/i0n/terraform@v0.4.3-0.20150506151324-010a39a58ec1/builtin/providers/aws/resource_aws_vpc_peering_connection.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "time" 7 8 "github.com/awslabs/aws-sdk-go/aws" 9 "github.com/awslabs/aws-sdk-go/service/ec2" 10 "github.com/hashicorp/terraform/helper/resource" 11 "github.com/hashicorp/terraform/helper/schema" 12 ) 13 14 func resourceAwsVpcPeeringConnection() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceAwsVPCPeeringCreate, 17 Read: resourceAwsVPCPeeringRead, 18 Update: resourceAwsVPCPeeringUpdate, 19 Delete: resourceAwsVPCPeeringDelete, 20 21 Schema: map[string]*schema.Schema{ 22 "peer_owner_id": &schema.Schema{ 23 Type: schema.TypeString, 24 Required: true, 25 ForceNew: true, 26 DefaultFunc: schema.EnvDefaultFunc("AWS_ACCOUNT_ID", nil), 27 }, 28 "peer_vpc_id": &schema.Schema{ 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 }, 33 "vpc_id": &schema.Schema{ 34 Type: schema.TypeString, 35 Required: true, 36 ForceNew: true, 37 }, 38 "auto_accept": &schema.Schema{ 39 Type: schema.TypeBool, 40 Optional: true, 41 }, 42 "accept_status": &schema.Schema{ 43 Type: schema.TypeString, 44 Computed: true, 45 }, 46 "tags": tagsSchema(), 47 }, 48 } 49 } 50 51 func resourceAwsVPCPeeringCreate(d *schema.ResourceData, meta interface{}) error { 52 conn := meta.(*AWSClient).ec2conn 53 54 // Create the vpc peering connection 55 createOpts := &ec2.CreateVPCPeeringConnectionInput{ 56 PeerOwnerID: aws.String(d.Get("peer_owner_id").(string)), 57 PeerVPCID: aws.String(d.Get("peer_vpc_id").(string)), 58 VPCID: aws.String(d.Get("vpc_id").(string)), 59 } 60 log.Printf("[DEBUG] VPCPeeringCreate create config: %#v", createOpts) 61 resp, err := conn.CreateVPCPeeringConnection(createOpts) 62 if err != nil { 63 return fmt.Errorf("Error creating vpc peering connection: %s", err) 64 } 65 66 // Get the ID and store it 67 rt := resp.VPCPeeringConnection 68 d.SetId(*rt.VPCPeeringConnectionID) 69 log.Printf("[INFO] VPC Peering Connection ID: %s", d.Id()) 70 71 // Wait for the vpc peering connection to become available 72 log.Printf( 73 "[DEBUG] Waiting for vpc peering connection (%s) to become available", 74 d.Id()) 75 stateConf := &resource.StateChangeConf{ 76 Pending: []string{"pending"}, 77 Target: "pending-acceptance", 78 Refresh: resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id()), 79 Timeout: 1 * time.Minute, 80 } 81 if _, err := stateConf.WaitForState(); err != nil { 82 return fmt.Errorf( 83 "Error waiting for vpc peering (%s) to become available: %s", 84 d.Id(), err) 85 } 86 87 return resourceAwsVPCPeeringUpdate(d, meta) 88 } 89 90 func resourceAwsVPCPeeringRead(d *schema.ResourceData, meta interface{}) error { 91 conn := meta.(*AWSClient).ec2conn 92 pcRaw, _, err := resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id())() 93 if err != nil { 94 return err 95 } 96 if pcRaw == nil { 97 d.SetId("") 98 return nil 99 } 100 101 pc := pcRaw.(*ec2.VPCPeeringConnection) 102 103 d.Set("accept_status", *pc.Status.Code) 104 d.Set("peer_owner_id", pc.AccepterVPCInfo.OwnerID) 105 d.Set("peer_vpc_id", pc.AccepterVPCInfo.VPCID) 106 d.Set("vpc_id", pc.RequesterVPCInfo.VPCID) 107 d.Set("tags", tagsToMapSDK(pc.Tags)) 108 109 return nil 110 } 111 112 func resourceVPCPeeringConnectionAccept(conn *ec2.EC2, id string) (string, error) { 113 114 log.Printf("[INFO] Accept VPC Peering Connection with id: %s", id) 115 116 req := &ec2.AcceptVPCPeeringConnectionInput{ 117 VPCPeeringConnectionID: aws.String(id), 118 } 119 120 resp, err := conn.AcceptVPCPeeringConnection(req) 121 pc := resp.VPCPeeringConnection 122 return *pc.Status.Code, err 123 } 124 125 func resourceAwsVPCPeeringUpdate(d *schema.ResourceData, meta interface{}) error { 126 conn := meta.(*AWSClient).ec2conn 127 128 if err := setTagsSDK(conn, d); err != nil { 129 return err 130 } else { 131 d.SetPartial("tags") 132 } 133 134 if _, ok := d.GetOk("auto_accept"); ok { 135 136 pcRaw, _, err := resourceAwsVPCPeeringConnectionStateRefreshFunc(conn, d.Id())() 137 138 if err != nil { 139 return err 140 } 141 if pcRaw == nil { 142 d.SetId("") 143 return nil 144 } 145 pc := pcRaw.(*ec2.VPCPeeringConnection) 146 147 if *pc.Status.Code == "pending-acceptance" { 148 149 status, err := resourceVPCPeeringConnectionAccept(conn, d.Id()) 150 151 log.Printf( 152 "[DEBUG] VPC Peering connection accept status %s", 153 status) 154 if err != nil { 155 return err 156 } 157 } 158 } 159 160 return resourceAwsVPCPeeringRead(d, meta) 161 } 162 163 func resourceAwsVPCPeeringDelete(d *schema.ResourceData, meta interface{}) error { 164 conn := meta.(*AWSClient).ec2conn 165 166 _, err := conn.DeleteVPCPeeringConnection( 167 &ec2.DeleteVPCPeeringConnectionInput{ 168 VPCPeeringConnectionID: aws.String(d.Id()), 169 }) 170 return err 171 } 172 173 // resourceAwsVPCPeeringConnectionStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch 174 // a VPCPeeringConnection. 175 func resourceAwsVPCPeeringConnectionStateRefreshFunc(conn *ec2.EC2, id string) resource.StateRefreshFunc { 176 return func() (interface{}, string, error) { 177 178 resp, err := conn.DescribeVPCPeeringConnections(&ec2.DescribeVPCPeeringConnectionsInput{ 179 VPCPeeringConnectionIDs: []*string{aws.String(id)}, 180 }) 181 if err != nil { 182 if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidVpcPeeringConnectionID.NotFound" { 183 resp = nil 184 } else { 185 log.Printf("Error on VPCPeeringConnectionStateRefresh: %s", err) 186 return nil, "", err 187 } 188 } 189 190 if resp == nil { 191 // Sometimes AWS just has consistency issues and doesn't see 192 // our instance yet. Return an empty state. 193 return nil, "", nil 194 } 195 196 pc := resp.VPCPeeringConnections[0] 197 198 return pc, *pc.Status.Code, nil 199 } 200 }