Terraform: Reference multiple resources without naming each of them - terraform

I am creating multiple subnets via a variable:
variable "private_subnets" {
description = "Private Subnets"
default = ["10.0.0.0/20", "10.0.32.0/20"]
}
resource "aws_subnet" "private" {
vpc_id = aws_vpc.main.id
cidr_block = element(var.private_subnets, count.index)
availability_zone = element(var.availability_zones, count.index)
count = length(var.private_subnets)
}
I count how many subnets I have listed in my Var and then create a subnet for each. The problem is so far I can only figure out how to reference them by each individual index:
subnets = [ aws_subnet.private[0].id, aws_subnet.private[1].id ]
What is the correct way to do this? I tried a similar element() and count section to the ECS network config where I'm referencing this, but it isn't working.

I am not sure if this is what you are after, but you can try:
subnets = aws_subnet.private[*].id
This syntax is called splat expressions

Related

How to reference a subnet from multiple subnets created in Terraform

With terraform, I created a resource block to create multiple public subnets. I want to reference one of the subnets I created in my module - How do I pass the var.aws_subnet.public_subnet to get one of the subnets created
variable "pub_sub_number" {
default = 2
type = number
resource "aws_subnet" "public_subnet" {
count = var.pub_sub_number
vpc_id = aws_vpc.bless.id
cidr_block = cidrsubnet("10.0.0.0/16", 8, range(0, 255, 2)[count.index])
map_public_ip_on_launch = true
tags = {
Name = "public_subnet_${count.index +1}"
}
}
How do I reference the resource block in my module?
I tried
var.aws_subnet.public_subnet
but it is capturing all the subnets I provisioned. I only need one

Terraform: creation of resources with nested loop

I have created a bunch of VPC endpoints in one AWS account and need to share them with other VPCs across different accounts. Break down of my terraform code is provided below.
Created the Route53 private hosted zones (Resource#1 for easy reference) as below
resource "aws_route53_zone" "private" {
for_each = local.vpc_endpoints
name = each.value.phz
vpc {
vpc_id = var.vpc_id
}
lifecycle {
ignore_changes = [vpc]
}
tags = {
Name = each.key
}
}
Created vpc association authorizations (Resource#2). The VPC ID, to which the endpoints are to be shared is passed as a variable as shown below.
resource "aws_route53_vpc_association_authorization" "example" {
for_each = local.vpc_endpoints
vpc_id = var.vpc
zone_id = aws_route53_zone.private[each.key].zone_id
}
Finally, I have created the VPC associations (Resource#3)
resource "aws_route53_zone_association" "target" {
for_each = aws_route53_vpc_association_authorization.example
provider = aws.target-account
vpc_id = aws_route53_vpc_association_authorization.example[each.key].vpc_id
zone_id = aws_route53_vpc_association_authorization.example[each.key].zone_id
}
Everything works fine for the first VPC (vpc-A). But now I need to share the same hosted zones (Resource#1) with a different VPC (vpc-B) and more VPCs in the future. This means I need to repeat the creation of "aws_route53_vpc_association_authorization" (Resource#2) for all new VPCs as well, ideally looping through a list of VPC IDs.
But I am unable to it as nested for_each loop is not supported. Tried other options like count + for_each etc., but nothing help.
Could you provide some guidance on how to achieve this?

Nested Dynamic block on counted resource not working as expected

Need your kind help. I am stuck with the following resource creation. Using Terraform v1.0.6
I need to create appropriate subnets dynamically in two VPCs
variables.tf
vpc_resource_networks = {
pnw-01 = [
[
{
subnet_name = "wb-01"
subnet_ip = "10.58.72.0/25"
description = "WEB01"
index = 0
},
{
subnet_name = "wb-02"
subnet_ip = "10.58.72.128/25"
description = "WEB02"
index = 1
}
],
[
{
subnet_name = "wb-01"
subnet_ip = "10.58.80.0/25"
description = "WEB01"
index = 0
},
{
subnet_name = "web-02"
subnet_ip = "10.58.72.128/25"
description = "WEB02"
index = 1
}
]
]
}
main.tf
locals {
wlb_net = element(keys(var.vpc_resource_networks), 0)
}
resource "aws_subnet" "wlb" {
count = length(module.aws_vpc_app_resource)
vpc_id = element(module.aws_vpc_app_resource.*.vpc_id, count.index)
dynamic "subnet_group" {
for_each = var.vpc_resource_networks[local.wlb_net][count.index]
content {
dynamic "subnet" {
for_each = subnet_group.value
content {
cidr_block = subnet.subnet_ip
availability_zone = element(var.azs, subnet.index)
tags = {
Name = subnet.subnet_name
}
}
}
}
}
I intend to create subnets dynamically which is var.vpc_resource_networks.pnw01[0] should be on one vpc and other index on another VPC.
The above block returns
dynamic “subnet_group” {
Blocks of type “subnet_group” are not expected here.
Please assist
Looking at the resource definition of aws_subnet, I can see that, as the error message suggests, there's no property for a "subnet_group".
There are several different resource types that are subnet groups though for different services; such as DMS, DocumentDB, DAX, Elasticache, MemoryDB, Neptune, RDS, and Redshift. Search the term "subnet_group" on the left panel within the provider page.
Perhaps an AWS expert can comment here but I believe you're trying to do two things in one motion here.
First you should create the subnets and define their ranges, then you should create subnet groups that need access to different subnets for a particular service.
Here's some more information on subnets and subnet groups.

terraform - passing vpc_id parameter from different VPC's to several subnets

I'm new to terraform and trying the following:
I created 3 aws VPC's:
#VPC creation
enter codresource "aws_vpc" "new_vpc" {
cidr_block = var.new_vpc[count.index]
count = 3
tags = {
Name = var.vpc_name[count.index]
count = 3
}
}
The variables.tf is as following:
#varibales for the vpc
#=======================
variable "new_vpc" {
type = list
}
variable "vpc_name" {
type = list
}
the terraform.tfvars is :
new_vpc=["10.0.0.0/16" , "10.0.0.0/17" , "10.0.0.0/18"]
vpc_name=["DEV_VPC" , "UAT_VPC" , "PROD_VPC" ]
all the VPC's created successfully
the next step is to create 3 subnets and each subnet need to be assign to a different VPC.
in oder to create a subnet the following paramaters are required : vpc_id + cidr_block
need your advice for the required vpc_id parameter - how to pass each subnet different vpc_id (as i mentioned above 3 vpc's created)
10x a lot
Since you used count to create vpc you can also use count to create subnets.
resource "aws_subnet" "You_subnet_name" {
count = 3
vpc_id = aws_vpc.new_vpc[count.index].id
}
You don't need to specify the cidr, the vpc id is enough.
You need however to specify the cidr_block part to alocate ip range for your subnet.
If you want to use all the ip space in the vpc for 1 subnet you can simply do:
resource "aws_subnet" "You_subnet_name" {
count = 3
vpc_id = aws_vpc.new_vpc[count.index].id
cidr_block = aws_vpc.new_vpc[count.index].cidr_block
}

How to pass a list of subnet to the 'subnets' attribute?

I am rewriting my subnets code to make it more flexible and driven by parameters:
resource "aws_subnet" "private" {
count = "${var.az_count}"
cidr_block = "${cidrsubnet(aws_vpc.ecs.cidr_block, 8, count.index)}"
availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
vpc_id = "${aws_vpc.ecs.id}"
}
This is the old code that pass the subnets to
resource "aws_ecs_service" "service" {
network_configuration {
subnets = [ "${aws_subnet.subnet1.id}", "${aws_subnet.subnet2.id}" ]
...
}
How can I pass the subnet ids from aws_subnet.private to the subnets attribute?
I have tried
subnets = ${aws_subnet.priate[*].id}
but there is an error:
Expected the start of an expression, but found an invalid expression token
First off, you can remove the ${} except in cases where you're interpolating. Strike that stuff, and you have the much more readable:
resource "aws_subnet" "private" {
count = var.az_count
cidr_block = cidrsubnet(aws_vpc.ecs.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
vpc_id = aws_vpc.ecs.id
}
Your reference syntax with the splat is correct, and your spelling is wrong. Try this:
subnets = aws_subnet.private[*].id
Splat ref: https://www.terraform.io/docs/configuration/expressions.html#splat-expressions

Resources