Harnessing Terraform rich features (Part-1)
Soumyadip Chatterjee
??? DevOps Engineer |Istio ?? | Terraform ???, |Docker ?? | K8's??| Snowflake ?? | Argo CD?? | Helm ?? | GitLab ?? | Ansible ?? | Certifications:- 2x AWS ??, 1x Azure???, 1x OCI??, 1x Commvault
In this article we will deep dive into some of the rich features of Terraform which significantly distinguish with other IAAC tools and cloud agnostic.
Implicit Dependencies :-
Explicit Dependencies:
Example :-
resource "aws_vpc" "my_vpc" {
# VPC configuration...
}
resource "aws_subnet" "my_subnet" {
# Subnet configuration...
vpc_id = aws_vpc.my_vpc.id
}
resource "aws_security_group" "web_sg" {
# Security group configuration...
vpc_id = aws_vpc.my_vpc.id
}
resource "aws_instance" "web_instance" {
# EC2 instance configuration...
subnet_id = aws_subnet.my_subnet.id
vpc_security_group_ids = [aws_security_group.web_sg.id]
}
In this example, the EC2 instance implicitly depends on the VPC and subnet. Terraform ensures that the VPC and subnet are created before attempting to create the EC2 instance.
Explicit Dependency: S3 Bucket and EC2 Instance
resource "aws_s3_bucket" "my_bucket" {
# S3 bucket configuration...
}
resource "aws_instance" "my_instance" {
# EC2 instance configuration...
depends_on = [aws_s3_bucket.my_bucket]
}
By using depends_on, you ensure that the EC2 instance waits for the S3 bucket to be created before proceeding.
Data Source:
data "aws_security_group" "existing_sg" {
name = "my-existing-sg"
}
Fetching Existing Resources:
data "aws_security_group" "existing_sg" {
name = "my-existing-sg"
}
resource "aws_instance" "my_instance" {
# EC2 instance configuration...
vpc_security_group_ids = [data.aws_security_group.existing_sg.id]
}
Dynamic Configuration:
data "aws_ami" "latest_web_ami" {
most_recent = true
filter {
name = "tag:Name"
values = ["web"]
}
}
resource "aws_instance" "web_instance" {
ami = data.aws_ami.latest_web_ami.id
instance_type = "t2.micro"
# Other configuration...
}
Keeping Configurations Up-to-Date:
data "aws_ami" "latest_ami" {
most_recent = true
# Other filters...
}
resource "aws_instance" "my_instance" {
ami = data.aws_ami.latest_ami.id
instance_type = "t2.micro"
# Other configuration...
}
Avoiding Hardcoding:
data "aws_subnet" "my_subnet" {
filter {
name = "tag:Name"
values = ["my-subnet-name"]
}
}
resource "aws_instance" "my_instance" {
subnet_id = data.aws_subnet.my_subnet.id
# Other configuration...
}
Centralizing Data Retrieval:
data "aws_ami" "my_image" {
# Filters to find the desired image...
}
resource "aws_instance" "my_instance" {
ami = data.aws_ami.my_image.id
instance_type = "t2.micro"
# Other configuration...
}
Managing Many Resources Efficiently:
data "aws_security_group" "existing_sg" {
name = "my-existing-sg"
}
resource "aws_instance" "web_instances" {
count = 3
vpc_security_group_ids = [data.aws_security_group.existing_sg.id]
# Other configuration...
}