Terraform defines datasources as:

Data sources allow data to be fetched or computed for use elsewhere in Terraform configuration. Use of data sources allows a Terraform configuration to make use of information defined outside of Terraform, or defined by another separate Terraform configuration.

In simple words, let's say you have created VPC and subnet via console and now trying to launch EC2 instance into that subnet. Terraform doesn't know the subnet-id because we have created the subnet outside of Terraform. We can use data sources to feed the information into Terraform.

Scenario

  • Subnet already exists in AWS with the id of subnet-0f2b77293ad28a714
  • EC2 instance needs to be launched into that subnet using Terraform

Note - We can of course add the id into the terraform config file but it's not a scalable option.


Step 1 - Create a data.tf file. (it can be any name)

A data source configuration looks like the following:

data "aws_subnet" "get-subnet-id" {
  filter {
    name   = "tag:Name"
    values = ["public-1"]
  }

}

output "aws_subnet_id" {
  value = data.aws_subnet.get-subnet-id.id
}
data.tf
  • aws_subnet - data source
  • filter - One or more name/value pairs to filter off of.
  • name, value - The key/value combination of a tag assigned to the resource. Use the tag key in the filter name and the tag value as the filter value. In our example, to find the subnet that have a tag with the key Name and the value Public-1, specify tag:Name for the filter name and public-1 for the filter value.
  • output - The subnet-id will be shown on the terminal

Step -2 Create EC2 instance via Terraform.

provider "aws" {
  region  = "eu-west-2"
  
}

resource "aws_instance" "ec2-ubuntu" {
  ami                    = "ami-0917237b4e71c5759"
  instance_type          = "t2.micro"
  subnet_id              = data.aws_subnet.get-subnet-id.id
  key_name               = "test-key"

  tags = {
    Name = "Ubuntu-1"
    }
}
ec2.tf

subnet-id - Terraform will get the subnet-id from the data source.


Step -3 Run Terraform

Suresh-MacBook:ec2 sureshvinasiththamby$ terraform apply
data.aws_subnet.get-subnet-id: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.ec2-ubuntu will be created
  + resource "aws_instance" "ec2-ubuntu" {
      + ami                          = "ami-0917237b4e71c5759"
      + instance_type                = "t2.micro"
      + key_name                     = "test-key"
      
      
      + source_dest_check            = true
      + subnet_id                    = "subnet-0f2b77293ad28a714"
      + tags                         = {
          + "Name" = "Ubuntu-1"
        }
  
aws_instance.ec2-ubuntu: Creating...
aws_instance.ec2-ubuntu: Still creating... [10s elapsed]
aws_instance.ec2-ubuntu: Still creating... [20s elapsed]
aws_instance.ec2-ubuntu: Creation complete after 22s [id=i-09f8a11aee4eb13c3]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

aws_subnet_id = subnet-0f2b77293ad28a714

As you can see above, Terraform picked up the correct subnet-id and launched an instance.

Thanks for reading

As always, your feedback and comments are more than welcome

Reference

Data Sources - Configuration Language - Terraform by HashiCorp
Data sources allow data to be fetched or computed for use elsewhere in Terraform configuration.

https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html