Hi ALL,
I am planning to create network interface and attach to ec2 instace primary IP, but i am getting below error,Please help me.
on main.tf line 25, in resource “aws_instance” “ec2_instance”:
25: network_interface = [for nic_idx in range(aws_network_interface.test):
An argument named “network_interface” is not expected here. Did you mean to
define a block of type “network_interface”?
provider "aws" {
shared_credentials_file = "/c/Users/test/.aws/credentials"
profile = "sandbox"
region = "us-east-1"
}
resource "aws_network_interface" "test" {
subnet_id = "subnet-*"
security_groups = ["sg*"]
count = "${var.number_of_instances}"
}
// EC2 Instance Resource for Module
resource "aws_instance" "ec2_instance" {
ami = "${var.ami_id}"
count = "${var.number_of_instances}"
instance_type = "${var.instance_type}"
subnet_id = "${var.subnet_id}"
vpc_security_group_ids = ["${aws_security_group.apigee-instance.id}"]
key_name = "java"
network_interface = [for nic_idx in range(aws_network_interface.test):
{
device_index = nic_idx
network_interface_id = aws_network_interface.test[nic_idx].id
delete_on_termination = false
}
]
ebs_block_device {
device_name = "/dev/sdg"
volume_type = "gp2"
volume_size = 200
delete_on_termination = true
}
ebs_block_device {
device_name = "/dev/sdf"
volume_type = "gp2"
volume_size = 20
delete_on_termination = true
}
ebs_block_device {
device_name = "/dev/sdh"
volume_type = "gp2"
volume_size = 10
delete_on_termination = true
}
}
The issue here is that your configuration is assigning an argument (using network_interface = [ … ]
, but it should be using a block (no x = y
assignment, just x {…}
).
To use for_each
with blocks, please refer to the dynamic
blocks documentation. In this case, I think the below configuration should do what you’re trying to do:
resource "aws_instance" "ec2_instance" {
ami = var.ami_id
instance_type = var.instance_type
count = var.number_of_instances
dynamic "network_interface" {
for_each = aws_network_interface.test
content {
device_index = network_interface.key
network_interface_id = network_interface.value.id
delete_on_termination = false
}
}
}
Please note that I have never actually tried creating and assigning AWS network interfaces in this way, so it may not be a best practice—I’m just trying to help with the Terraform language semantics where I can. Hopefully someone with more practical experience can chime in if there’s a better way to do this!
Hi @alisdair,
Sill i ma getting error like below
Error: Incorrect attribute value type
on main.tf line 28, in resource "aws_instance" "ec2_instance":
28: network_interface_id =aws_network_interface.test[*].id
|----------------
| aws_network_interface.test is tuple with 2 elements
Inappropriate value for attribute "network_interface_id": string required.
Error: Incorrect attribute value type
on main.tf line 28, in resource "aws_instance" "ec2_instance":
28: network_interface_id =aws_network_interface.test[*].id
|----------------
| aws_network_interface.test is tuple with 2 elements
Inappropriate value for attribute "network_interface_id": string required.
Error: Incorrect attribute value type
on main.tf line 28, in resource "aws_instance" "ec2_instance":
28: network_interface_id =aws_network_interface.test[*].id
|----------------
| aws_network_interface.test is tuple with 2 elements
Inappropriate value for attribute "network_interface_id": string required.
Error: Incorrect attribute value type
on main.tf line 28, in resource "aws_instance" "ec2_instance":
28: network_interface_id =aws_network_interface.test[*].id
|----------------
| aws_network_interface.test is tuple with 2 elements
Inappropriate value for attribute "network_interface_id": string required.
// Provider specific configs
provider "aws" {
shared_credentials_file = "/c/Users/ag64160/.aws/credentials"
profile = "sandbox"
region = "us-east-1"
}
resource "aws_network_interface" "test" {
subnet_id = "subnet-06de28df4461194be"
security_groups = ["sg-0de4b3a45f739ee0f"]
count = "${var.number_of_instances}"
}
// EC2 Instance Resource for Module
resource "aws_instance" "ec2_instance" {
ami = "${var.ami_id}"
count = "${var.number_of_instances}"
instance_type = "${var.instance_type}"
subnet_id = "${var.subnet_id}"
vpc_security_group_ids = ["${aws_security_group.apigee-instance.id}"]
key_name = "psdev"
dynamic "network_interface" {
for_each = aws_network_interface.test
content {
device_index = 1
network_interface_id =aws_network_interface.test[*].id
delete_on_termination = false
}
}
ebs_block_device {
device_name = "/dev/sdg"
volume_type = "gp2"
volume_size = 200
delete_on_termination = true
}
ebs_block_device {
device_name = "/dev/sdf"
volume_type = "gp2"
volume_size = 20
delete_on_termination = true
}
ebs_block_device {
device_name = "/dev/sdh"
volume_type = "gp2"
volume_size = 10
delete_on_termination = true
}
}
Did you try the configuration as I suggested? Quoted again:
Did this not work?
HI @alisdair,
Yes its working, but when am creating instances it creating 2 network interfaces,
i need only one network interface.
how to get that,Please help me.
FYR i am updating plan state
Terraform will perform the following actions:
# aws_instance.ec2_instance[0] will be created
+ resource "aws_instance" "ec2_instance" {
+ ami = "ami-0e8f1415d9ba49d82"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = "psdev"
+ network_interface_id = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ security_groups = (known after apply)
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = true
+ device_name = "/dev/sdf"
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = 20
+ volume_type = "gp2"
}
+ ebs_block_device {
+ delete_on_termination = true
+ device_name = "/dev/sdg"
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = 200
+ volume_type = "gp2"
}
+ ebs_block_device {
+ delete_on_termination = true
+ device_name = "/dev/sdh"
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = 10
+ volume_type = "gp2"
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = false
+ device_index = 0
+ network_interface_id = (known after apply)
}
+ network_interface {
+ delete_on_termination = false
+ device_index = 1
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
# aws_instance.ec2_instance[1] will be created
+ resource "aws_instance" "ec2_instance" {
+ ami = "ami-0e8f1415d9ba49d82"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = "psdev"
+ network_interface_id = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ security_groups = (known after apply)
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = true
+ device_name = "/dev/sdf"
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = 20
+ volume_type = "gp2"
}
+ ebs_block_device {
+ delete_on_termination = true
+ device_name = "/dev/sdg"
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = 200
+ volume_type = "gp2"
}
+ ebs_block_device {
+ delete_on_termination = true
+ device_name = "/dev/sdh"
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = 10
+ volume_type = "gp2"
}
+ ephemeral_block_device {
+ device_name = (known after apply)
+ no_device = (known after apply)
+ virtual_name = (known after apply)
}
+ metadata_options {
+ http_endpoint = (known after apply)
+ http_put_response_hop_limit = (known after apply)
+ http_tokens = (known after apply)
}
+ network_interface {
+ delete_on_termination = false
+ device_index = 0
+ network_interface_id = (known after apply)
}
+ network_interface {
+ delete_on_termination = false
+ device_index = 1
+ network_interface_id = (known after apply)
}
+ root_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
# aws_network_interface.test[0] will be created
+ resource "aws_network_interface" "test" {
+ id = (known after apply)
+ mac_address = (known after apply)
+ outpost_arn = (known after apply)
+ private_dns_name = (known after apply)
+ private_ip = (known after apply)
+ private_ips = (known after apply)
+ private_ips_count = (known after apply)
+ security_groups = [
+ "sg-0de4b3a45f739ee0f",
]
+ source_dest_check = true
+ subnet_id = "subnet-06de28df4461194be"
+ attachment {
+ attachment_id = (known after apply)
+ device_index = (known after apply)
+ instance = (known after apply)
}
}
# aws_network_interface.test[1] will be created
+ resource "aws_network_interface" "test" {
+ id = (known after apply)
+ mac_address = (known after apply)
+ outpost_arn = (known after apply)
+ private_dns_name = (known after apply)
+ private_ip = (known after apply)
+ private_ips = (known after apply)
+ private_ips_count = (known after apply)
+ security_groups = [
+ "sg-0de4b3a45f739ee0f",
]
+ source_dest_check = true
+ subnet_id = "subnet-06de28df4461194be"
+ attachment {
+ attachment_id = (known after apply)
+ device_index = (known after apply)
+ instance = (known after apply)
}
Oh, I see! I completely misunderstood what you’re trying to do. I thought you wanted all network interfaces to be bound to each AWS instance.
I now think you’re trying to create, say, 5 aws_network_interface
resources and 5 aws_instance
resources, and assign them one-to-one. That does make more sense 
In that case, I think you want to bind the network interface using an address with count.index
, like this:
resource "aws_instance" "ec2_instance" {
ami = var.ami_id
instance_type = var.instance_type
count = var.number_of_instances
network_interface {
device_index = 0
network_interface_id = aws_network_interface.test[count.index].id
delete_on_termination = false
}
}
I hope that’s clearer. Again, I haven’t used this configuration with AWS, so if anyone would care to offer corrections or recommend best practices, that would be great!
Hi @alisdair,
Its working, Thanks.
I have one more question
How to assign tag to specific node (eg count= 5) in terraform.
usecase:
creating 5 nodes using count =5, but i need a specific tag to 2nd and 5th node,
is it possible via terraform.