Bird
Raised Fist0
Terraformcloud~5 mins

Data source block syntax in Terraform - Commands & Configuration

Choose your learning style10 modes available
Introduction
Sometimes you need to get information about existing resources outside your Terraform code. Data source blocks let you read this information so you can use it in your setup.
When you want to find details about an existing cloud resource like a network or storage bucket.
When you need to use information from resources created outside your Terraform project.
When you want to reference shared resources managed by other teams without recreating them.
When you want to get the latest data about a resource before creating dependent resources.
When you want to avoid hardcoding values by fetching them dynamically.
Config File - main.tf
main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
  required_version = ">= 1.0"
}

provider "aws" {
  region = "us-east-1"
}

# Data source block to get information about an existing AWS VPC

data "aws_vpc" "example" {
  filter {
    name   = "tag:Name"
    values = ["example-vpc"]
  }
  most_recent = true
}

output "vpc_id" {
  value = data.aws_vpc.example.id
}

This Terraform file uses a data block to fetch details about an existing AWS VPC named "example-vpc". The filter section tells Terraform how to find the VPC by its tag. The most_recent argument ensures the latest matching VPC is selected if multiple exist. The output block then shows the VPC's ID after applying the configuration.

Commands
This command sets up Terraform in the current folder, downloading the AWS provider so Terraform can talk to AWS.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding hashicorp/aws versions matching "~> 4.0"... - Installing hashicorp/aws v4.60.0... - Installed hashicorp/aws v4.60.0 (signed by HashiCorp) Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work.
This command shows what Terraform will do. Here, it will read the existing VPC data and show the output value without making changes.
Terminal
terraform plan
Expected OutputExpected
Refreshing Terraform state in-memory prior to plan... ------------------------------------------------------------------------ No changes. Your infrastructure matches the configuration. This means that Terraform did not detect any differences between your configuration and real physical resources that exist. As a result, no actions need to be performed.
This command applies the configuration, fetching the VPC data and showing the VPC ID as output.
Terminal
terraform apply -auto-approve
Expected OutputExpected
data.aws_vpc.example: Refreshing state... Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: vpc_id = "vpc-0abcd1234efgh5678"
→
-auto-approve - Automatically approve the apply without asking for confirmation
Key Concept

If you remember nothing else from this pattern, remember: data source blocks let Terraform read existing resources so you can use their information without creating them.

Common Mistakes
Trying to use a data source without initializing Terraform first
Terraform needs to download providers before it can read data sources, so the command will fail.
Always run 'terraform init' before 'terraform plan' or 'terraform apply' when adding new data sources.
Using incorrect filter names or values in the data source block
Terraform won't find the resource and will error or return empty data.
Check the exact tag names and values in your cloud console and match them exactly in the filter.
Expecting data sources to create or change resources
Data sources only read existing resources; they do not create or modify anything.
Use resource blocks to create or change infrastructure, and data sources only to read.
Summary
Use a data source block to read information about existing resources by specifying filters.
Run 'terraform init' to prepare Terraform and download providers before using data sources.
Use 'terraform plan' to preview and 'terraform apply' to fetch data and see outputs.

Practice

(1/5)
1. What is the main purpose of a data source block in Terraform?
easy
A. To create new cloud resources from scratch
B. To define variables for Terraform configuration
C. To delete existing cloud resources
D. To read information about existing cloud resources without creating new ones

Solution

  1. Step 1: Understand the role of data sources

    Data sources in Terraform are used to fetch information about existing resources, not to create or delete them.
  2. Step 2: Compare options with this role

    Only To read information about existing cloud resources without creating new ones describes reading existing resource info without creation, matching the data source purpose.
  3. Final Answer:

    To read information about existing cloud resources without creating new ones -> Option D
  4. Quick Check:

    Data source = read existing info [OK]
Hint: Data sources read existing resources, not create or delete [OK]
Common Mistakes:
  • Confusing data sources with resource blocks
  • Thinking data sources create resources
  • Assuming data sources delete resources
2. Which of the following is the correct syntax to define a data source block for an AWS AMI in Terraform?
easy
A. data "aws_ami" example { filter { name = "name" values = ["my-ami"] } }
B. resource "aws_ami" "example" { filter { name = "name" values = ["my-ami"] } }
C. data "aws_ami" "example" { filter { name = "name" values = ["my-ami"] } }
D. data aws_ami example { filter { name = "name" values = ["my-ami"] } }

Solution

  1. Step 1: Identify correct block type and syntax

    Data source blocks start with data, followed by resource type and local name in quotes.
  2. Step 2: Check each option

    data "aws_ami" "example" { filter { name = "name" values = ["my-ami"] } } uses correct quotes and block structure. resource "aws_ami" "example" { filter { name = "name" values = ["my-ami"] } } uses resource instead of data. Options A and C miss quotes around local name or resource type.
  3. Final Answer:

    data "aws_ami" "example" { filter { name = "name" values = ["my-ami"] } } -> Option C
  4. Quick Check:

    Data source syntax = data "type" "name" { ... } [OK]
Hint: Data source block uses data "type" "name" with quotes [OK]
Common Mistakes:
  • Using resource instead of data
  • Omitting quotes around type or name
  • Incorrect block nesting or missing braces
3. Given this Terraform data source block:
data "aws_vpc" "selected" {
  filter {
    name   = "tag:Name"
    values = ["main-vpc"]
  }
}

What will data.aws_vpc.selected.id return?
medium
A. The ID of the VPC tagged with Name=main-vpc
B. The name tag value main-vpc
C. A list of all VPC IDs in the AWS account
D. An error because filter syntax is invalid

Solution

  1. Step 1: Understand the filter block

    The filter selects the VPC resource with tag Name equal to main-vpc.
  2. Step 2: Identify the returned attribute

    data.aws_vpc.selected.id accesses the ID of the matched VPC, not the tag value or a list.
  3. Final Answer:

    The ID of the VPC tagged with Name=main-vpc -> Option A
  4. Quick Check:

    Filter selects resource, .id returns its ID [OK]
Hint: Filter narrows resource, .id returns its unique ID [OK]
Common Mistakes:
  • Confusing tag value with resource ID
  • Expecting a list instead of single ID
  • Assuming filter syntax is wrong
4. Identify the error in this Terraform data source block:
data "aws_subnet" "example" {
  filter {
    name = "availability-zone"
    values = "us-west-2a"
  }
}
medium
A. The values attribute should be a list, not a string
B. The filter block is missing a closing brace
C. The data source type aws_subnet does not support filters
D. The local name example must be uppercase

Solution

  1. Step 1: Check the values attribute type

    In Terraform, filter values must be a list, even if only one value is given.
  2. Step 2: Verify the given values

    The code uses a string instead of a list, which causes a syntax error.
  3. Final Answer:

    The values attribute should be a list, not a string -> Option A
  4. Quick Check:

    Filter values = list, not string [OK]
Hint: Always use list syntax ["value"] for filter values [OK]
Common Mistakes:
  • Using string instead of list for values
  • Assuming filter block needs no braces
  • Thinking local name case matters
5. You want to use a data source block to get the latest Amazon Linux 2 AMI ID filtered by owner and name pattern. Which of these blocks correctly achieves this?
hard
A. resource "aws_ami" "latest" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } }
B. data "aws_ami" "latest" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } }
C. data "aws_ami" "latest" { filter { name = "owner" values = ["amazon"] } filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } }
D. data "aws_ami" "latest" { most_recent = true owner = "amazon" filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } }

Solution

  1. Step 1: Confirm correct block type and attributes

    Use data block for reading AMI info, with most_recent = true and owners as a list.
  2. Step 2: Check filter and owner syntax

    data "aws_ami" "latest" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } correctly uses owners list and a filter for name pattern. data "aws_ami" "latest" { filter { name = "owner" values = ["amazon"] } filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } incorrectly filters owner as a filter. resource "aws_ami" "latest" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } uses resource block instead of data. data "aws_ami" "latest" { most_recent = true owner = "amazon" filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } uses singular owner instead of owners list.
  3. Final Answer:

    data "aws_ami" "latest" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } -> Option B
  4. Quick Check:

    Use data block, owners list, most_recent true [OK]
Hint: Use owners list and most_recent true in data block [OK]
Common Mistakes:
  • Using resource block instead of data
  • Filtering owner instead of using owners attribute
  • Using singular owner instead of owners list
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard