provider/aws: Fix importing of EIP by IP address (#8970)

* provider/aws: Fix importing of EIP by IP address

EIPs are meant to be imported by their allocation id, however, importing
by their EIP *appears* to work because this API actually accepts IP
lookup, despite the documentation asking for the allocation id.

This PR does:

- update docs on how to import EIPs
- fix case if user imported by IP, to switch to using the alloc id for
the resource id

I chose not to document that looking up by IP is a method of import,
because the AWS  API docs do not explicitly say that looking up by IP is
OK, so I'd rather people not do it if it's not documented to stay that
way.

Alternatively, we could parse the resource ID and reject it (remove from
state with error/warning) if it doesn't match the `eipalloc-*` format,
but I thought this was a bit better UX.

* fix issue with swapping IDs on EC2 Classic

* update docs

* update comment
This commit is contained in:
Clint 2016-09-22 21:53:21 -05:00 committed by GitHub
parent 50eb2338f0
commit b7ad602993
2 changed files with 25 additions and 2 deletions

View File

@ -3,6 +3,7 @@ package aws
import ( import (
"fmt" "fmt"
"log" "log"
"net"
"strings" "strings"
"time" "time"
@ -127,12 +128,12 @@ func resourceAwsEipRead(d *schema.ResourceData, meta interface{}) error {
} }
log.Printf( log.Printf(
"[DEBUG] EIP describe configuration: %#v (domain: %s)", "[DEBUG] EIP describe configuration: %s (domain: %s)",
req, domain) req, domain)
describeAddresses, err := ec2conn.DescribeAddresses(req) describeAddresses, err := ec2conn.DescribeAddresses(req)
if err != nil { if err != nil {
if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidAllocationID.NotFound" { if ec2err, ok := err.(awserr.Error); ok && (ec2err.Code() == "InvalidAllocationID.NotFound" || ec2err.Code() == "InvalidAddress.NotFound") {
d.SetId("") d.SetId("")
return nil return nil
} }
@ -173,6 +174,13 @@ func resourceAwsEipRead(d *schema.ResourceData, meta interface{}) error {
d.Set("domain", address.Domain) d.Set("domain", address.Domain)
// Force ID to be an Allocation ID if we're on a VPC
// This allows users to import the EIP based on the IP if they are in a VPC
if *address.Domain == "vpc" && net.ParseIP(id) != nil {
log.Printf("[DEBUG] Re-assigning EIP ID (%s) to it's Allocation ID (%s)", d.Id(), *address.AllocationId)
d.SetId(*address.AllocationId)
}
return nil return nil
} }

View File

@ -107,4 +107,19 @@ The following attributes are exported:
* `instance` - Contains the ID of the attached instance. * `instance` - Contains the ID of the attached instance.
* `network_interface` - Contains the ID of the attached network interface. * `network_interface` - Contains the ID of the attached network interface.
## Import
EIPs in a VPC can be imported using their Allocation ID, e.g.
```
$ terraform import aws_eip.bar eipalloc-00a10e96
```
EIPs in EC2 Classic can be imported using their Public IP, e.g.
```
$ terraform import aws_eip.bar 52.0.0.0
```
[1]: https://docs.aws.amazon.com/fr_fr/AWSEC2/latest/APIReference/API_AssociateAddress.html [1]: https://docs.aws.amazon.com/fr_fr/AWSEC2/latest/APIReference/API_AssociateAddress.html