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
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.
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 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
}
}
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 have code to create VPC, with 2 private subnets, 2xec2 instances in private and bastion in public.
ec2 code uses outputs.tf of VPC module subnet_ids. as there are 2 private subnets there are 2 subnet_ids being generated. when these generated subnet_ids are fed into ec2 instances instead of one subnet_id, it is feeding 2 subnet_ids at once as a single value.
As a result terraform couldn't find that subnet_ids value, creation is being failed.
error:
The subnet ID 'subnet-0***********,subnet-0*************' does not exist
editing subnets*
vpc.tf
private_subnets = "10.10.20.#/#,10.10.20.#/#"
instanceec2.tf
subnet_id = "${module.vpc.private_subnets}"
below are modules:
vpc_main.tf
// Private subnet/s
resource "aws_subnet" "private" {
vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "${element(split(",", var.private_subnets), count.index)}"
availability_zone = "${element(split(",", var.azs), count.index)}"
count = "${length(split(",", var.private_subnets))}"
tags {
Name = "${var.name}-private-${element(split(",", var.azs), count.index)}"
Team = "${var.team}"
Environment = "${var.environment}"
Service = "${var.service}"
Product = "${var.product}"
Owner = "${var.owner}"
Description = "${var.description}"
managed_by = "terraform"
}
}
resource "aws_route_table" "private" {
vpc_id = "${aws_vpc.vpc.id}"
count = "${length(split(",", var.private_subnets))}"
tags {
Name = "${var.name}-private-${element(split(",", var.azs), count.index)}"
Team = "${var.team}"
Environment = "${var.environment}"
Service = "${var.service}"
Product = "${var.product}"
Owner = "${var.owner}"
Description = "${var.description}"
managed_by = "terraform"
}
}
resource "aws_route_table_association" "private" {
subnet_id = "${element(aws_subnet.private.*.id, count.index)}"
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
count = "${length(split(",", var.private_subnets))}"
}
``````
vpc_outputs.tf
```````
output "private_subnets" {
value = "${join(",", aws_subnet.private.*.id)}"
}
Expected value is only one subnet ID as value:
Error: supply 2 Subnet IDs as one value.
aws_instance.ec2-instance[0]: 1 error(s) occurred:
aws_instance.ec2-instance.0: Error launching source instance: InvalidSubnetID.NotFound: The subnet ID 'subnet-0**********,subnet-0***********' does not exist
you are joining the subnet IDs in your output variable:
output "private_subnets" {
value = "${join(",", aws_subnet.private.*.id)}"
}
When you access this output value from your instanceec2.tf you will only receive this joined string of IDs.
So, you again have to slipt the received value as you've done before and access the respective individual ID with your count index of the ec2 resource:
resource "aws_instance" "default" {
count = "${length(split(",", module.vpc.private_subnets))}"
subnet_id = "${element(split(",", module.vpc.private_subnets), count.index)}"
....
}
That should solve you're issue.
Alternatively, you can also output the subnet IDs directly as a list:
output "private_subnets" {
description = "The IDs of the private subnets as list"
value = ["${aws_subnet.private.*.id}"]
}
and then access them with:
subnet_id = "${element(module.vpc.private_subnets, count.index)}"
Since you have 'join'ed the result, you would have to split again if you require just one subnet value.
Something like:
element(split(",", var.private_subnets), 0)