Attach Public Ip (EIP) to a existing ENI (Created outside of terraform)

Hello,

How to attach existing EIP (Created outside of terraform) and exsiting ENI (Created outside of terraform) using terraform?

I’m unable to find documentation to request additional secondary private IP’s for ENI, to attach the EIP

Thanks

Hi @boredmonkey,

When a particular Terraform configuration depends on objects managed outside of that configuration (whether managed by another Terraform configuration or by some other workflow entirely) you need to decide on some way for the Terraform configuration to find out the necessary IDs for those external objects.

The two main options would be:

  • If you don’t expect these objects to change frequently, the most straightforward option is to just hard-code them. If this represents a boundary between two subsystems where the EIP and ENI are part of the stable public interface of the other system then this can be a reasonable answer, but it could be bothersome if you expect to be recreating either object regularly.
  • For objects that get replaced relatively often but have some systematic way to locate them, you can use Data Sources, which allow for a special kind of Terraform resource that represents a dependency on an external object defined by some matching criteria, as opposed to an object managed directly by Terraform.

I’m going to show the second option here just because the first option is essentially the same except that you’d remove the two data blocks and just hard-coded their results directly into the resource block.

data "aws_eip" "example" {
  # For the sake of example I'm assuming the
  # tag Name is the stable characteristic we'll
  # use to locate the intended EIP. See the
  # docs for the aws_eip data source for other
  # possibilities.
  tags = {
    Name = "ExampleENIConnection"
  }
}

data "aws_network_interface" "example" {
  # This data source has a slightly different
  # syntax for looking up by tag, because
  # the underlying API is a bit different,
  # but this is the same idea as above.
  filter {
    name   = "tag:Name"
    values = ["ExampleENIConnection"]
  }
}

resource "aws_eip_association" "example" {
  network_interface_id = data.aws_network_interface.example.id
  allocation_id        = data.aws_eip.example.id
}

The two data sources here have various other query arguments that you can use to distinguish the one object of each type that you intend to use from any others that might be visible in the target AWS region. For more information, see their documentation:

If it’s easier to look up the EC2 instance which holds the network interface rather than the network interface directly then that’s also possible, using the aws_instance data source and the instance_id argument of the aws_ip_association resource type. I mention this because in many cases ENIs are created automatically as a side-effect of starting an EC2 instance, in which case the ENI itself is often not tagged at all or is tagged in a less comprehensive way than the instance it belongs to, and so it may not be practical to narrow down exactly the ENI you want using an ENI lookup alone.

@apparentlymart when I try aws_eip_association resource type, without specifying the Private Ip, it is assigning it to default private ip, but in my case default IP is already associated to another EIP.

I need a way to request secondary private ip to an existing ENI, after that i can use data and aws_eip_association resource to associate them.

Error associating EIP: Resource.AlreadyAssociated: resource eni-xxxxx and 10.xx.xx.xx is already associated with public address xx.xx.xx.xx