I need to create one EC2 and associate 2 subnets to it.
variables.tf
variable "aws_subnet_id_this" {
description = "Subnet ID"
default = ["subnet-09df122a4faee8882", "subnet-2fcc756f02ddb4b62"]
}
main.tf
resource "aws_instance" "test" {
ami = var.ami_id
instance_type = var.ec2_instance_type
subnet_id = var.aws_subnet_id_this
key_name = var.pki_name
vpc_security_group_ids = [aws_security_group.Allow_SSH_in.id]
}
Error:
Error: Incorrect attribute value type
on main_count_data.tf line 57, in resource "aws_instance" "test":
57: subnet_id = var.aws_subnet_id_this
|----------------
| var.aws_subnet_id_eks is tuple with 2 elements
Inappropriate value for attribute "subnet_id": string required.
So I tried this:
main.tf
resource "aws_instance" "prueba" {
ami = var.ami_id
instance_type = var.ec2_instance_type
#subnet_id = var.aws_subnet_id_this
count = 2
subnet_id = "${element(var.aws_subnet_id_this, count.index)}"
key_name = var.pki_name
vpc_security_group_ids = [aws_security_group.Allow_SSH_in.id]
}
}
but this last portion of code tries to create a new EC2 instance with the second subnet and this is not what I expect tough.
To sum up: I need 1 EC2 containing 2 subnets defined in the variables.tf file.
How can I do this?
Below is an example of how you can create one instance with two NICs in different subnets. The NICs must be in same AZ. So instance can have two NICs in different subnets as long as they are in same AZ:
variable "aws_subnet_id_this" {
description = "Subnet ID"
default = ["subnet-09df122a4faee8882", "subnet-2fcc756f02ddb4b62"]
}
resource "aws_network_interface" "nic1" {
subnet_id = var.aws_subnet_id_this[0]
}
resource "aws_network_interface" "nic2" {
subnet_id = var.aws_subnet_id_this[1]
}
resource "aws_instance" "prueba" {
ami = var.ami_id
instance_type = var.ec2_instance_type
key_name = var.pki_name
network_interface {
device_index = 0
network_interface_id = aws_network_interface.nic1.id
}
network_interface {
device_index = 1
network_interface_id = aws_network_interface.nic2.id
}
}
Related
I have came up with below:
resource "aws_network_interface" "eni_carl" {
subnet_id = module.vpc.public_subnets[3]
private_ip = "10.0.4.1/32"
security_groups = [module.vpc.ssh_sg]
}
resource "aws_instance" "carl" {
ami = var.ami
instance_type = "t2.micro"
key_name = var.key_name
network_interface {
network_interface_id = aws_network_interface.eni_carl.id
device_index = 0
}
}
But aws will randomly assign private ip for my instance. How can I achieve generating the same and fixed private ip address for my instance?
Terraform v1.3.4
on linux_amd64
provider registry.terraform.io/hashicorp/aws v4.39.0
From aws_instance | Resources | hashicorp/aws | Terraform Registry:
resource "aws_network_interface" "foo" {
subnet_id = aws_subnet.my_subnet.id
private_ips = ["172.16.10.100"]
tags = {
Name = "primary_network_interface"
}
}
Therefore, the parameter appears to be: private_ips = ["172.16.10.100"]
It takes an IP address instead of a CIDR block.
Hello I'm trying to create multiple instance based on a count variable. I currently have 1 private subnet with 2 cidr blocks however when i try to create the instance i get
"Error: Error launching source instance: InvalidSubnetID.NotFound: The subnet ID '10.7.90.96/27' does not exist
status code: 400, request id: d7ef5147-ac30-4d31-815a-ad6a46bfe456
on .terraform\modules\vpc\AWS-VPC-Module\main.tf line 1427, in resource "aws_instance" "FID":
1427: resource "aws_instance" "FID" {"
when clearly the TF does create the subnets are present
resource "aws_instance" "FID" {
depends_on = [aws_kms_key.aws-wm-wmad-prod]
count = var.How_many_FID
ami = var.windows_dc_ami_2016
availability_zone = element(var.availability_zones, count.index)
ebs_optimized = var.windows_dc_ebs_optimized
instance_type = var.windows_dc_instance_type_FID
key_name = var.key_name
monitoring = true
subnet_id = element(var.private_subnet_cidr_blocks, count.index)
associate_public_ip_address = false
here is my subnet creation code:
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidr_blocks) # count = 2
vpc_id = aws_vpc.default.id #id34odfjdf
cidr_block = var.private_subnet_cidr_blocks[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(
{
Name_TF = "dctr-ad-sbn-use1-az1A-prod-lan-0${count.index+1}",
Project = var.project,
Environment = var.environment
},
var.tags
)
}
subnet_id must be actual subnet id, not its CIDR:
subnet_id = element(aws_subnet.private, count.index).id
Subnets are created from the below code:
resource "aws_subnet" "Private" {
for_each = var.subnet_cidrs_private
vpc_id = aws_vpc.vpc.id
cidr_block = each.value
availability_zone = each.key
tags = {
Name = format("%s-%s-%s", var.environment, "Pri-Subnet", substr(each.key, -2, -1))
}
}
Trying to create 1 instance with count parameter.
resource "aws_instance" "visualapp" {
instance_type = "t2.micro"
ami = var.visualapp-ami
key_name = var.key_pair
vpc_security_group_ids = [aws_security_group.visualapp.id]
subnet_id = element(aws_subnet.Private[*].id, count.index)
count = 1
tags = {
Name = format("%s-%s", var.environment, "mage-varnish-${count.index + 1}")
}
}
Getting the below error:
subnet_id = element(aws_subnet.Private[*].id, count.index)
This object does not have an attribute named "id".
Variables:
variable "subnet_cidrs_private" {
default = {
eu-west-1a = "172.26.3.0/24",
eu-west-1b = "172.26.4.0/24"
}
}
Can anyone help me?.
element would be used if you had used count. Since you've used for_each you need to use values first:
subnet_id = element(values(aws_subnet.Private)[*].id, count.index)
I currently have multiple subnets created within a VPC for each availability zone within a region. I am now trying to create one EC2 instance per subnet within each availability zone, and am running into an issue. Below is my code, I am having some trouble getting the subnet ID to attach to EC2 instances. Any advice would be appreciated.
Instance
resource "aws_instance" "public" {
for_each = aws_subnet.public
ami = data.aws_ami.ec2.id
instance_type = var.tableau_instance
key_name = aws_key_pair.main.key_name
subnet_id = [for subnet in aws_subnet.public : subnet.id]
}
Subnet
locals {
az_names = data.aws_availability_zones.azs.names
}
resource "aws_subnet" "public" {
for_each = { for index, az_name in local.az_names : index => az_name }
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, each.key + 1)
availability_zone = local.az_names[each.key]
map_public_ip_on_launch = true
tags = {
Name = "${var.vpc_tags}_PubSubnet"
}
}
Error
Error: Incorrect attribute value type
on vpc.tf line 18, in resource "aws_instance" "public":
18: subnet_id = [for subnet in aws_subnet.public : subnet.id]
|----------------
| aws_subnet.public is object with 3 attributes
Inappropriate value for attribute "subnet_id": string required.
The instance code should be as follows:
resource "aws_instance" "public" {
for_each = aws_subnet.public
ami = data.aws_ami.ec2.id
instance_type = var.tableau_instance
key_name = aws_key_pair.main.key_name
subnet_id = each.value.id
}
This will place 1 instance in each subnet.
I'm trying to create an aws instance with an aws_network_interface as below:
resource "aws_network_interface" "lustre-mds01" {
subnet_id = "${var.subnet_id}"
private_ips = ["10.1.0.10"]
}
resource "aws_instance" "lustre-mds01" {
ami = "${var.ec2_ami}"
instance_type = "t2.nano"
key_name = "${var.key_name}"
vpc_security_group_ids = [ "${var.vpc_security_group_id}" ]
root_block_device {
volume_type = "gp2"
volume_size = 128
}
network_interface {
network_interface_id = "${aws_network_interface.lustre-mds01.id}"
device_index = 0
}
}
However, this results in:
Error: "network_interface": conflicts with vpc_security_group_ids
It appears there is an issue for this, but the ticket was closed due to inactivity. I'm a terraform noob, so I'm not sure if this looks like a bug or is just user error.
My environment:
$ terraform -v
Terraform v0.12.2
+ provider.aws v2.15.0
+ provider.external v1.1.2
+ provider.local v1.2.2
+ provider.null v2.1.2
The aws_network_interface resource allows you to set the security group for the interface (security groups are scoped by the ENI so this makes sense) so if you define the network_interface block then you're overriding the default ENI and so can't specify security groups at the instance level.
So in your case you probably want something like:
resource "aws_network_interface" "lustre-mds01" {
subnet_id = "${var.subnet_id}"
private_ips = ["10.1.0.10"]
security_groups = ["${var.vpc_security_group_id}"]
}
resource "aws_instance" "lustre-mds01" {
ami = "${var.ec2_ami}"
instance_type = "t2.nano"
key_name = "${var.key_name}"
root_block_device {
volume_type = "gp2"
volume_size = 128
}
network_interface {
network_interface_id = "${aws_network_interface.lustre-mds01.id}"
device_index = 0
}
}
However, I would question why you are replacing the default ENI here when it's much simpler to just set the private IP address of the instance directly in the aws_instance resource instead:
resource "aws_instance" "lustre-mds01" {
ami = "${var.ec2_ami}"
instance_type = "t2.nano"
key_name = "${var.key_name}"
subnet_id = "${var.subnet_id}"
private_ip = "10.1.0.10"
vpc_security_group_ids = ["${var.vpc_security_group_id}"]
root_block_device {
volume_type = "gp2"
volume_size = 128
}
}
You would also probably benefit from using data sources to select your security group and AMI instead of passing in opaque IDs for these. This allows them to be more self documenting.