Terraform: converting an aws_instance network interface into an explicitly managed interface

August 23, 2022 

The aws_instance resource in Terraform can automatically create the default network interface for you. There are cases, however, when you notice that the default network interface is not enough anymore, and modifying it via the limited aws_instance parameters is not sufficient. In these cases you can convert the interface into an aws_network_interface resource, but the process is far from straightforward.

The first step is to create a Terraform resource for the network interface:

resource "aws_network_interface" "myinstance" {
  subnet_id          = aws_subnet.primary.id
  description        = "Network interface for myinstance"
  # Add any parameters you need, such as this:
  ipv6_prefix_count  = 2

Now you need to import the network interface into the Terraform state file. There's no need to "terraform apply", as the network interface is already present in AWS. For example:

terraform import aws_network_interface.myinstance eni-0123456789abcedf0

The next step is to add a network_interface block into aws_instance's Terraform code:

network_interface {
  delete_on_termination = false
  network_interface_id  = aws_network_interface.myinstance.id
  device_index          = 0

At this point Terraform will be confused because the state file does not have such a network_interface block. So, get the current state file:

terraform state pull > temp.tfstate

Now add the network_interface block into the state file:

--- snip ---
            "monitoring": false,
            "network_interface": [
                "delete_on_termination": false,
                "device_index": 0,
                "network_interface_id": "eni-0123456789abcedf0"
            "outpost_arn": "",
            "password_data": "",
            "placement_group": "",
            "placement_partition_number": null,
            "primary_network_interface_id": "eni-0123456789abcedf0",
--- snip ---

Then modify the value of "serial" at the top of the state file, incrementing it by one, e.g. from 50 to 51:

  "serial": 51,

Now push the massaged state file to the remote state:

terraform state push temp.tfstate

Now when you run "terraform plan" you should not see any changes, or at most, changes that are non-destructive and/or to be expected. The delete_on_termination parameter's value might not match: if so, just change the real value in AWS network interface settings to match what Terraform expects.

Samuli Seppänen
Samuli Seppänen
Author archive