github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_vpn_connection_route.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 8 "github.com/aws/aws-sdk-go/aws" 9 "github.com/aws/aws-sdk-go/aws/awserr" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 12 "github.com/hashicorp/terraform/helper/schema" 13 ) 14 15 func resourceAwsVpnConnectionRoute() *schema.Resource { 16 return &schema.Resource{ 17 // You can't update a route. You can just delete one and make 18 // a new one. 19 Create: resourceAwsVpnConnectionRouteCreate, 20 Read: resourceAwsVpnConnectionRouteRead, 21 Delete: resourceAwsVpnConnectionRouteDelete, 22 23 Schema: map[string]*schema.Schema{ 24 "destination_cidr_block": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 }, 29 30 "vpn_connection_id": &schema.Schema{ 31 Type: schema.TypeString, 32 Required: true, 33 ForceNew: true, 34 }, 35 }, 36 } 37 } 38 39 func resourceAwsVpnConnectionRouteCreate(d *schema.ResourceData, meta interface{}) error { 40 conn := meta.(*AWSClient).ec2conn 41 42 createOpts := &ec2.CreateVpnConnectionRouteInput{ 43 DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)), 44 VpnConnectionId: aws.String(d.Get("vpn_connection_id").(string)), 45 } 46 47 // Create the route. 48 log.Printf("[DEBUG] Creating VPN connection route") 49 _, err := conn.CreateVpnConnectionRoute(createOpts) 50 if err != nil { 51 return fmt.Errorf("Error creating VPN connection route: %s", err) 52 } 53 54 // Store the ID by the only two data we have available to us. 55 d.SetId(fmt.Sprintf("%s:%s", *createOpts.DestinationCidrBlock, *createOpts.VpnConnectionId)) 56 57 return resourceAwsVpnConnectionRouteRead(d, meta) 58 } 59 60 func resourceAwsVpnConnectionRouteRead(d *schema.ResourceData, meta interface{}) error { 61 conn := meta.(*AWSClient).ec2conn 62 63 cidrBlock, vpnConnectionId := resourceAwsVpnConnectionRouteParseId(d.Id()) 64 65 routeFilters := []*ec2.Filter{ 66 &ec2.Filter{ 67 Name: aws.String("route.destination-cidr-block"), 68 Values: []*string{aws.String(cidrBlock)}, 69 }, 70 &ec2.Filter{ 71 Name: aws.String("vpn-connection-id"), 72 Values: []*string{aws.String(vpnConnectionId)}, 73 }, 74 } 75 76 // Technically, we know everything there is to know about the route 77 // from its ID, but we still want to catch cases where it changes 78 // outside of terraform and results in a stale state file. Hence, 79 // conduct a read. 80 resp, err := conn.DescribeVpnConnections(&ec2.DescribeVpnConnectionsInput{ 81 Filters: routeFilters, 82 }) 83 if err != nil { 84 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVpnConnectionID.NotFound" { 85 d.SetId("") 86 return nil 87 } else { 88 log.Printf("[ERROR] Error finding VPN connection route: %s", err) 89 return err 90 } 91 } 92 if resp == nil || len(resp.VpnConnections) == 0 { 93 // This is kind of a weird edge case. I'd rather return an error 94 // instead of just blindly setting the ID to ""... since I don't know 95 // what might cause this. 96 return fmt.Errorf("No VPN connections returned") 97 } 98 99 vpnConnection := resp.VpnConnections[0] 100 101 var found bool 102 for _, r := range vpnConnection.Routes { 103 if *r.DestinationCidrBlock == cidrBlock { 104 d.Set("destination_cidr_block", *r.DestinationCidrBlock) 105 d.Set("vpn_connection_id", *vpnConnection.VpnConnectionId) 106 found = true 107 } 108 } 109 if !found { 110 // Something other than terraform eliminated the route. 111 d.SetId("") 112 } 113 114 return nil 115 } 116 117 func resourceAwsVpnConnectionRouteDelete(d *schema.ResourceData, meta interface{}) error { 118 conn := meta.(*AWSClient).ec2conn 119 120 _, err := conn.DeleteVpnConnectionRoute(&ec2.DeleteVpnConnectionRouteInput{ 121 DestinationCidrBlock: aws.String(d.Get("destination_cidr_block").(string)), 122 VpnConnectionId: aws.String(d.Get("vpn_connection_id").(string)), 123 }) 124 if err != nil { 125 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVpnConnectionID.NotFound" { 126 d.SetId("") 127 return nil 128 } else { 129 log.Printf("[ERROR] Error deleting VPN connection route: %s", err) 130 return err 131 } 132 } 133 134 return nil 135 } 136 137 func resourceAwsVpnConnectionRouteParseId(id string) (string, string) { 138 parts := strings.SplitN(id, ":", 2) 139 return parts[0], parts[1] 140 }