Skip to main content

Using Data Sources

1. Declaring Data Blocks

Property Description Example
data "aws_ami" "latest_amazon_linux" Declares a data block to fetch information about an AMI
data "aws_ami" "latest_amazon_linux" {
  most_recent = true
  owners      = ["137112412987"]
  filters {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}
data "aws_vpc" "main" Fetches details of a VPC by ID
data "aws_vpc" "main" {
  id = var.vpc_id
}
data "local_file" "config" Reads content from a local file
data "local_file" "config" {
  filename = "${path.module}/config.json"
}

Example: Using Data Block in Resource

resource "aws_instance" "web" {
  ami           = data.aws_ami.latest_amazon_linux.id
  instance_type = "t2.micro"
}

2. Querying External Data

Example: Fetching AWS Instance Information

data "aws_instance" "web" {
  filter {
    name   = "instance-state-name"
    values = ["running"]
  }
  filter {
    name   = "tag:Environment"
    values = ["production"]
  }
}
Attribute Description Required
filter Defines a filter to apply to the data source query Yes
name The name of the filter to apply Yes
values List of values to match against the filter Yes
Note: Filters are used to narrow down the results returned by a data source. They can be combined for more complex queries.

Example: Using Data Source in Resource Configuration

resource "aws_instance" "web_server" {
  ami           = data.aws_instance.web.ami_id
  instance_type = data.aws_instance.web.instance_type
}

Key Concepts

  • Data sources allow you to fetch information from external systems
  • They are read-only and do not create or modify resources
  • Use filters to query specific data from external providers

3. Filtering Data Source Results

Filter Type Description Example
id Filter by the unique identifier of a data source
data "aws_instance" "filtered_instance" {
  filter {
    name   = "instance-id"
    values = ["i-1234567890abcdef0"]
  }
}
tag Filter by tag key-value pairs
data "aws_instances" "by_tag" {
  filter {
    name   = "tag:Environment"
    values = ["production"]
  }
}
state Filter by instance state (running, stopped, etc.)
data "aws_instances" "by_state" {
  filter {
    name   = "instance-state-name"
    values = ["running"]
  }
}

Example: Filtering EC2 Instances by Tag

data "aws_instances" "web_servers" {
  filter {
    name   = "tag:Name"
    values = ["web-server"]
  }
}
Note: Filters are applied at the AWS API level, which can improve performance when querying large datasets.

4. Referencing Data Attributes

Attribute Type Description Example
id string Unique identifier for the data source data.aws_ami.ubuntu.id
arn string Amazon Resource Name (ARN) of the resource data.aws_s3_bucket.example.arn
name string Name of the resource or object data.aws_security_group.example.name
tags map(string) Map of tags associated with the resource data.aws_instance.example.tags
count number Number of items in a list or set data.aws_instances.example.count

Example: Referencing Data Attributes

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]
  filters {
    name   = "ubuntu/images/ubuntu-focal-20.04-amd64-server-*"
    values = ["ubuntu/images/ubuntu-focal-20.04-amd64-server-*"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
  tags = {
    Name = "web-server"
  }
}
Note: When referencing data attributes, ensure that the attribute path is correct to avoid runtime errors.
Warning: Data sources are read-only and cannot be modified or destroyed. Changes to data sources will not affect the state of your infrastructure.

5. Using Data Source Dependencies

Property Description Example
depends_on Ensures that the data source is evaluated after specified resources or data sources
data "aws_subnet" "by_id" {
  depends_on = [aws_vpc.main]
  id = var.subnet_id
}

Example: Using depends_on with Data Sources

data "aws_vpc" "main" {
  filter {
    name   = "tag:Name"
    values = ["production"]
  }
}

data "aws_subnet" "by_id" {
  depends_on = [data.aws_vpc.main]
  id = var.subnet_id
}
Note: The depends_on meta-argument ensures Terraform evaluates the data source only after the specified resources have been created.

6. Reading Remote State

Example: Reading remote state in Terraform

data "terraform_remote_state" "prod" {
  backend = "local"
  config = {
    path = "/path/to/prod/terraform.tfstate"
  }
}

resource "aws_instance" "web" {
  ami           = data.terraform_remote_state.prod.outputs.ami_id
  instance_type = data.terraform_remote_state.prod.outputs.instance_type
}
Argument Description Required
backend The backend type to use (e.g., local, s3, azurerm) Yes
config Configuration for the backend (e.g., path, bucket, key) Yes
workspace The workspace to read from (defaults to default) No
Note: Ensure that the remote state backend is properly configured and accessible to avoid errors during state reads.

7. Using Template Data Sources

Property Description Example
template The template content as a string "Hello {{ name }}!"
vars Map of variables to pass into the template {"name": "Terraform"}

Example: Using Template Data Source

data "template_file" "greeting" {
  template = "Hello {{ name }}!"
  vars = {
    name = "Terraform"
  }
}

output "greeting" {
  value = data.template_file.greeting.rendered
}
Note: The template_file data source is useful for generating dynamic content from templates, such as configuration files or user data.

8. Querying Cloud Provider APIs

Field Description Example
provider The cloud provider to query (e.g., aws, azurerm) aws
type The type of data source (e.g., aws_ami, azurerm_resource_group) aws_ami
name Unique identifier for the data source within the configuration latest_ami

Example: Fetching Latest AMI ID from AWS

data "aws_ami" "latest_ami" {
  most_recent = true
  owners      = ["amazon"]
  filters {
    name   = "amzn2-ami-hvm-*"
    values = ["*x86_64-gp2"]
  }
}

Example: Using the Fetched AMI ID in a Resource

resource "aws_instance" "web" {
  ami           = data.aws_ami.latest_ami.id
  instance_type = "t2.micro"
}
Note: Data sources are read-only and do not create or modify infrastructure. They allow you to fetch information from external systems for use in your configuration.

9. Using External Programs

Note: The external data source is used to execute external programs and capture their output as Terraform data.
Argument Description Required
program List of strings representing the command and arguments to execute. Yes
working_dir Directory in which to execute the program. No
environment Map of environment variables to set for the program execution. No

Example: Executing a Shell Script

data "external" "current_user" {
  program = ["/bin/bash", "-c", "id -u"]
}

Example: Capturing JSON Output

data "external" "json_output" {
  program = ["python3", "-c", "import json; print(json.dumps({\"key\": \"value\"}))"]
}

10. Using Lifecycle with Data Sources

Attribute Description Values
prevent_destroy Prevents destruction of the data source during a destroy operation false or true
ignore_changes Prevents specific attributes from triggering a replacement List of attribute paths

Example: Preventing Destruction of Data Source

data "aws_ami" "latest" {
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/ubuntu-20.04/amd64/server-*"]
  }
  lifecycle {
    prevent_destroy = true
  }
}
Note: The lifecycle block in data sources is used to control how Terraform handles changes and destruction, similar to resources.

11. Combining Multiple Data Sources

Example: Combining AWS AMI and VPC Data Sources

data "aws_ami" "latest_amazon_linux" {
  most_recent = true
  owners      = ["137112412987"]
  filters {
    name   = "amzn2-ami-hvm-*"
    values = ["hvm"]
  }
}

data "aws_vpc" "main_vpc" {
  filter {
    name   = "tag:Name"
    values = ["main-vpc"]
  }
}

resource "aws_instance" "web_server" {
  ami           = data.aws_ami.latest_amazon_linux.id
  vpc_security_group_ids = [data.aws_vpc.main_vpc.default_security_group_id]
  instance_type = "t3.micro"
}
Source Property Description Usage
data.aws_ami id AMI ID for the latest Amazon Linux 2 image Used to specify the AMI for EC2 instance
data.aws_vpc default_security_group_id ID of the default security group for the VPC Used to assign security groups to EC2 instances
Note: Data sources are resolved during terraform plan and terraform apply, not at runtime.
Warning: Combining data sources can increase plan time if the sources are expensive to query.

Was this article helpful?