interview-prep

Crisp answer: A resource block declares a piece of infrastructure to create and manage. Every resource has a type (from the provider), a local name (for referencing within the config), and arguments that configure it.

Anatomy:

resource "<PROVIDER>_<TYPE>" "<LOCAL_NAME>" {
  # arguments
}

resource "aws_instance" "web" {    # type: aws_instance, name: web
  ami           = "ami-0abc123"
  instance_type = "t3.micro"
}

resource "aws_security_group" "app" {   # type: aws_security_group, name: app
  name   = "app-sg"
  vpc_id = aws_vpc.main.id             # references another resource
}

Referencing a resource:

# Pattern: <TYPE>.<LOCAL_NAME>.<ATTRIBUTE>
aws_vpc.main.id
aws_instance.web.private_ip
aws_security_group.app.arn
aws_s3_bucket.logs.bucket

Meta-arguments that work on any resource:

resource "aws_instance" "web" {
  ami           = "ami-0abc123"
  instance_type = "t3.micro"

  # count — create multiple identical resources
  count = 3
  # Reference: aws_instance.web[0], aws_instance.web[1], aws_instance.web[2]
  tags = { Name = "web-${count.index}" }

  # for_each — create one resource per map entry or set element
  # (cannot use both count and for_each)
}

resource "aws_iam_user" "team" {
  for_each = toset(["alice", "bob", "carol"])
  name     = each.key
  # Reference: aws_iam_user.team["alice"], aws_iam_user.team["bob"]
}

resource "aws_subnet" "private" {
  for_each          = var.subnet_map   # map(string)
  vpc_id            = aws_vpc.main.id
  cidr_block        = each.value       # map value
  availability_zone = each.key         # map key
}

depends_on:

resource "aws_eks_node_group" "workers" {
  cluster_name  = aws_eks_cluster.main.name
  node_role_arn = aws_iam_role.node.arn

  depends_on = [
    aws_iam_role_policy_attachment.worker_node,
    aws_iam_role_policy_attachment.cni,
  ]
}

lifecycle:

resource "aws_rds_cluster" "main" {
  cluster_identifier = "prod-db"

  lifecycle {
    create_before_destroy = true   # New resource before old is destroyed
    prevent_destroy       = true   # Block accidental destruction
    ignore_changes        = [tags] # Ignore tag changes managed elsewhere
  }
}

What to say in the interview:

"A resource block is the fundamental unit in Terraform. Type plus local name is the address used to reference it everywhere else. The meta-arguments that work on any resource are count and for_each for creating multiple instances, depends_on for explicit ordering, and lifecycle for controlling create, update, and destroy behaviour. count gives you indexed instances, for_each gives you named instances keyed by map key or set element — prefer for_each because it's more robust to index shifting when items are removed."


My notes