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_vpc" "main" | Fetches details of a VPC by ID | |
| data "local_file" "config" | Reads content from a local file | |
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 | |
| tag | Filter by tag key-value pairs | |
| state | Filter by instance state (running, stopped, etc.) | |
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 | |
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.