DEV Community

1suleyman
1suleyman

Posted on

🔗 How to Reference One Resource in Another Using Terraform (Without Losing Your Mind)

Hey everyone 👋

If you’re starting to build real-world infrastructure with Terraform, you’ll quickly run into this scenario:

“How do I use a value from one resource — like an Elastic IP — inside another resource — like a security group rule?”

At first, this might seem tricky (especially when the value doesn’t exist yet). But with a little Terraform magic and some string interpolation, it’s actually really clean.

Let me break it down in a way that helped me finally “get it” 👇


🧠 The Real-World Analogy: Mailing Yourself a Key

Let’s say you’re building a smart lock system:

  • You create a lock (Security Group)
  • Then you generate a digital key (Elastic IP)
  • Finally, you want to add a rule that only lets that key unlock the door.

But here's the twist: you don’t know the key (IP address) until the system gives it to you.

So you need a way to:

  1. Generate the key
  2. Grab its value
  3. Use it in the lock configuration

Terraform lets you do exactly that.


🧩 The Setup

You’re creating 3 things:

  1. aws_eip.lb – Elastic IP
  2. aws_security_group.attribute_sg – Security Group
  3. aws_vpc_security_group_ingress_rule.allow_tls – Rule that allows HTTPS (port 443) from the EIP

Here's the tricky part:
The cidr_ipv4 field must include the IP of the EIP with a /32 CIDR suffix.


💥 The Gotcha: Why This Fails Without Help

If you try this:

cidr_ipv4 = aws_eip.lb.public_ip/32
Enter fullscreen mode Exit fullscreen mode

Terraform will throw an error like:

Invalid attribute value: must be a valid IPv4 CIDR block
Enter fullscreen mode Exit fullscreen mode

Because Terraform can’t just smush values and strings like that.


🧪 The Fix: String Interpolation

The solution? Use Terraform’s string interpolation syntax:

cidr_ipv4 = "${aws_eip.lb.public_ip}/32"
Enter fullscreen mode Exit fullscreen mode

✅ This tells Terraform:

“First, wait for the EIP to be created. Then, grab its public IP. Then, add /32. Then, use that value.”

Boom. Problem solved.


🔁 Dependency Graph Magic

Terraform automatically figures out:

  • The EIP must be created before the SG rule
  • The SG must be created before the SG rule can attach to it

You don’t need to add depends_on. Terraform handles the sequencing based on your references.

💡 So when you write this:

security_group_id = aws_security_group.attribute_sg.id
Enter fullscreen mode Exit fullscreen mode

Terraform knows to wait until that SG is ready.


📘 Code Sample (Simplified)

resource "aws_eip" "lb" {
  domain = "vpc"
}

resource "aws_security_group" "attribute_sg" {
  name = "attribute-sg"
  description = "Security group for EIP demo"
  vpc_id = "your-vpc-id" # replace accordingly
}

resource "aws_vpc_security_group_ingress_rule" "allow_tls" {
  security_group_id = aws_security_group.attribute_sg.id
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
  cidr_ipv4         = "${aws_eip.lb.public_ip}/32"
}
Enter fullscreen mode Exit fullscreen mode

🧹 Cleanup Tip

⚠️ Don’t forget:
Terraform apply might work partially (some resources created, some fail). If that happens, run:

terraform destroy -auto-approve
Enter fullscreen mode Exit fullscreen mode

Then rerun your plan for a clean, full apply.


🧠 Final Takeaways

✅ Use cross-resource references to link your infrastructure
✅ Always check what attributes a resource gives you
✅ Use string interpolation when combining values like public_ip + /32
✅ Let Terraform handle dependencies — it’s good at it!


Want to see the full working example? I’ve got a .tf file for it and more coming soon to my GitHub 👇

Also, if you’re learning Terraform or AWS and want to swap ideas, let’s connect on LinkedIn — always down to talk cloud, IaC, and how not to go crazy with CIDR blocks 😅

Keep building 🙌

Top comments (0)