github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_network_interface_attachment.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "time" 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 "github.com/hashicorp/terraform/helper/resource" 12 "github.com/hashicorp/terraform/helper/schema" 13 ) 14 15 func resourceAwsNetworkInterfaceAttachment() *schema.Resource { 16 return &schema.Resource{ 17 Create: resourceAwsNetworkInterfaceAttachmentCreate, 18 Read: resourceAwsNetworkInterfaceAttachmentRead, 19 Delete: resourceAwsNetworkInterfaceAttachmentDelete, 20 21 Schema: map[string]*schema.Schema{ 22 "device_index": { 23 Type: schema.TypeInt, 24 Required: true, 25 ForceNew: true, 26 }, 27 28 "instance_id": { 29 Type: schema.TypeString, 30 Required: true, 31 ForceNew: true, 32 }, 33 34 "network_interface_id": { 35 Type: schema.TypeString, 36 Required: true, 37 ForceNew: true, 38 }, 39 40 "attachment_id": { 41 Type: schema.TypeString, 42 Computed: true, 43 }, 44 45 "status": { 46 Type: schema.TypeString, 47 Computed: true, 48 }, 49 }, 50 } 51 } 52 53 func resourceAwsNetworkInterfaceAttachmentCreate(d *schema.ResourceData, meta interface{}) error { 54 conn := meta.(*AWSClient).ec2conn 55 56 device_index := d.Get("device_index").(int) 57 instance_id := d.Get("instance_id").(string) 58 network_interface_id := d.Get("network_interface_id").(string) 59 60 opts := &ec2.AttachNetworkInterfaceInput{ 61 DeviceIndex: aws.Int64(int64(device_index)), 62 InstanceId: aws.String(instance_id), 63 NetworkInterfaceId: aws.String(network_interface_id), 64 } 65 66 log.Printf("[DEBUG] Attaching network interface (%s) to instance (%s)", network_interface_id, instance_id) 67 resp, err := conn.AttachNetworkInterface(opts) 68 if err != nil { 69 if awsErr, ok := err.(awserr.Error); ok { 70 return fmt.Errorf("Error attaching network interface (%s) to instance (%s), message: \"%s\", code: \"%s\"", 71 network_interface_id, instance_id, awsErr.Message(), awsErr.Code()) 72 } 73 return err 74 } 75 76 stateConf := &resource.StateChangeConf{ 77 Pending: []string{"false"}, 78 Target: []string{"true"}, 79 Refresh: networkInterfaceAttachmentRefreshFunc(conn, network_interface_id), 80 Timeout: 5 * time.Minute, 81 Delay: 10 * time.Second, 82 MinTimeout: 3 * time.Second, 83 } 84 85 _, err = stateConf.WaitForState() 86 if err != nil { 87 return fmt.Errorf( 88 "Error waiting for Volume (%s) to attach to Instance: %s, error: %s", network_interface_id, instance_id, err) 89 } 90 91 d.SetId(*resp.AttachmentId) 92 return resourceAwsNetworkInterfaceAttachmentRead(d, meta) 93 } 94 95 func resourceAwsNetworkInterfaceAttachmentRead(d *schema.ResourceData, meta interface{}) error { 96 conn := meta.(*AWSClient).ec2conn 97 98 interfaceId := d.Get("network_interface_id").(string) 99 100 req := &ec2.DescribeNetworkInterfacesInput{ 101 NetworkInterfaceIds: []*string{aws.String(interfaceId)}, 102 } 103 104 resp, err := conn.DescribeNetworkInterfaces(req) 105 if err != nil { 106 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidNetworkInterfaceID.NotFound" { 107 // The ENI is gone now, so just remove the attachment from the state 108 d.SetId("") 109 return nil 110 } 111 112 return fmt.Errorf("Error retrieving ENI: %s", err) 113 } 114 if len(resp.NetworkInterfaces) != 1 { 115 return fmt.Errorf("Unable to find ENI (%s): %#v", interfaceId, resp.NetworkInterfaces) 116 } 117 118 eni := resp.NetworkInterfaces[0] 119 120 if eni.Attachment == nil { 121 // Interface is no longer attached, remove from state 122 d.SetId("") 123 return nil 124 } 125 126 d.Set("attachment_id", eni.Attachment.AttachmentId) 127 d.Set("device_index", eni.Attachment.DeviceIndex) 128 d.Set("instance_id", eni.Attachment.InstanceId) 129 d.Set("network_interface_id", eni.NetworkInterfaceId) 130 d.Set("status", eni.Attachment.Status) 131 132 return nil 133 } 134 135 func resourceAwsNetworkInterfaceAttachmentDelete(d *schema.ResourceData, meta interface{}) error { 136 conn := meta.(*AWSClient).ec2conn 137 138 interfaceId := d.Get("network_interface_id").(string) 139 140 detach_request := &ec2.DetachNetworkInterfaceInput{ 141 AttachmentId: aws.String(d.Id()), 142 Force: aws.Bool(true), 143 } 144 145 _, detach_err := conn.DetachNetworkInterface(detach_request) 146 if detach_err != nil { 147 if awsErr, _ := detach_err.(awserr.Error); awsErr.Code() != "InvalidAttachmentID.NotFound" { 148 return fmt.Errorf("Error detaching ENI: %s", detach_err) 149 } 150 } 151 152 log.Printf("[DEBUG] Waiting for ENI (%s) to become dettached", interfaceId) 153 stateConf := &resource.StateChangeConf{ 154 Pending: []string{"true"}, 155 Target: []string{"false"}, 156 Refresh: networkInterfaceAttachmentRefreshFunc(conn, interfaceId), 157 Timeout: 10 * time.Minute, 158 } 159 160 if _, err := stateConf.WaitForState(); err != nil { 161 return fmt.Errorf( 162 "Error waiting for ENI (%s) to become dettached: %s", interfaceId, err) 163 } 164 165 return nil 166 }