Allow assocation of EIP to ENI

This commit is contained in:
James Stremick 2015-04-25 22:30:37 -04:00
parent fa85e6b769
commit b29e9d3b6f
2 changed files with 79 additions and 12 deletions

View File

@ -31,6 +31,12 @@ func resourceAwsEip() *schema.Resource {
Optional: true,
},
"network_interface": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ConflictsWith: []string{"instance"},
},
"allocation_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
@ -114,10 +120,14 @@ func resourceAwsEipRead(d *schema.ResourceData, meta interface{}) error {
"[DEBUG] EIP describe configuration: %#v, %#v (domain: %s)",
assocIds, publicIps, domain)
req := &ec2.DescribeAddressesInput{
AllocationIDs: assocIds,
PublicIPs: publicIps,
req := &ec2.DescribeAddressesInput{}
if domain == "vpc" {
req.AllocationIDs = []*string{aws.String(id)}
} else {
req.PublicIPs = []*string{aws.String(id)}
}
describeAddresses, err := ec2conn.DescribeAddresses(req)
if err != nil {
if ec2err, ok := err.(aws.APIError); ok && ec2err.Code == "InvalidAllocationID.NotFound" {
@ -141,6 +151,7 @@ func resourceAwsEipRead(d *schema.ResourceData, meta interface{}) error {
d.Set("association_id", address.AssociationID)
d.Set("instance", address.InstanceID)
d.Set("network_interface", address.NetworkInterfaceID)
d.Set("private_ip", address.PrivateIPAddress)
d.Set("public_ip", address.PublicIP)
@ -152,9 +163,13 @@ func resourceAwsEipUpdate(d *schema.ResourceData, meta interface{}) error {
domain := resourceAwsEipDomain(d)
// Only register with an instance if we have one
if v, ok := d.GetOk("instance"); ok {
instanceId := v.(string)
// Associate to instance or interface if specified
v_instance, ok_instance := d.GetOk("instance")
v_interface, ok_interface := d.GetOk("network_interface")
if ok_instance || ok_interface {
instanceId := v_instance.(string)
networkInterfaceId := v_interface.(string)
assocOpts := &ec2.AssociateAddressInput{
InstanceID: aws.String(instanceId),
@ -164,16 +179,16 @@ func resourceAwsEipUpdate(d *schema.ResourceData, meta interface{}) error {
// more unique ID conditionals
if domain == "vpc" {
assocOpts = &ec2.AssociateAddressInput{
InstanceID: aws.String(instanceId),
AllocationID: aws.String(d.Id()),
PublicIP: aws.String(""),
NetworkInterfaceID: aws.String(networkInterfaceId),
InstanceID: aws.String(instanceId),
AllocationID: aws.String(d.Id()),
}
}
log.Printf("[DEBUG] EIP associate configuration: %#v (domain: %v)", assocOpts, domain)
_, err := ec2conn.AssociateAddress(assocOpts)
if err != nil {
return fmt.Errorf("Failure associating instances: %s", err)
return fmt.Errorf("Failure associating EIP: %s", err)
}
}
@ -191,8 +206,8 @@ func resourceAwsEipDelete(d *schema.ResourceData, meta interface{}) error {
return nil
}
// If we are attached to an instance, detach first.
if d.Get("instance").(string) != "" {
// If we are attached to an instance or interface, detach first.
if d.Get("instance").(string) != "" || d.Get("association_id").(string) != "" {
log.Printf("[DEBUG] Disassociating EIP: %s", d.Id())
var err error
switch resourceAwsEipDomain(d) {

View File

@ -57,6 +57,26 @@ func TestAccAWSEIP_instance(t *testing.T) {
})
}
func TestAccAWSEIP_network_interface(t *testing.T) {
var conf ec2.Address
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEIPDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSEIPNetworkInterfaceConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEIPExists("aws_eip.bar", &conf),
testAccCheckAWSEIPAttributes(&conf),
testAccCheckAWSEIPAssociated(&conf),
),
},
},
})
}
func testAccCheckAWSEIPDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).ec2conn
@ -101,6 +121,16 @@ func testAccCheckAWSEIPAttributes(conf *ec2.Address) resource.TestCheckFunc {
}
}
func testAccCheckAWSEIPAssociated(conf *ec2.Address) resource.TestCheckFunc {
return func(s *terraform.State) error {
if *conf.AssociationID == "" {
return fmt.Errorf("empty association_id")
}
return nil
}
}
func testAccCheckAWSEIPExists(n string, res *ec2.Address) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
@ -177,3 +207,25 @@ resource "aws_eip" "bar" {
instance = "${aws_instance.bar.id}"
}
`
const testAccAWSEIPNetworkInterfaceConfig = `
resource "aws_vpc" "bar" {
cidr_block = "10.0.0.0/24"
}
resource "aws_internet_gateway" "bar" {
vpc_id = "${aws_vpc.bar.id}"
}
resource "aws_subnet" "bar" {
vpc_id = "${aws_vpc.bar.id}"
availability_zone = "us-west-2a"
cidr_block = "10.0.0.0/24"
}
resource "aws_network_interface" "bar" {
subnet_id = "${aws_subnet.bar.id}"
private_ips = ["10.0.0.10"]
security_groups = [ "${aws_vpc.bar.default_security_group_id}" ]
}
resource "aws_eip" "bar" {
vpc = "true"
network_interface = "${aws_network_interface.bar.id}"
}
`