[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > [Basic infrastructure](../infrastructure/index.md) > Tools > Terraform data sources

# Terraform data sources

[Terraform data sources](https://developer.hashicorp.com/terraform/language/data-sources) allow you to get up-to-date information about the existing cloud resources and use this data in your infrastructure configuration.

With the [Yandex Cloud Terraform provider](../../terraform/index.md), you can get information about various cloud resources, including [VMs](../../compute/concepts/vm.md), [disks](../../compute/concepts/disk.md), [cloud networks](../../vpc/concepts/network.md), etc.

Data sources are available as read only, which prevents any changes to external resources.

Let's use Terraform data sources to get an [Ubuntu 22.04 LTS](https://yandex.cloud/en/marketplace/products/yc/ubuntu-22-04-lts) image ID from Cloud Marketplace.

To get an `Ubuntu 22.04 LTS` image ID using Terraform:

1. [Get your cloud ready](#before-you-begin).
1. [Install and configure Terraform](#prepare-terraform).
1. [Describe the data source](#prepare-plan).
1. [Check the result](#check).

## Get your cloud ready {#before-you-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).

## Install and configure Terraform {#prepare-terraform}

## Install and configure Terraform {#prepare-terraform}

### Install Terraform {#install-terraform}

{% list tabs group=operating_system %}

- Windows {#windows}

   Use one of the following methods:
   * [Download the Terraform distribution](https://www.terraform.io/downloads.html) and follow [this guide](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started) to install it.
   * Install Terraform using the [Chocolatey](https://chocolatey.org/install) package manager and the command below:

      ```bash
      choco install terraform
      ```

- Linux {#linux}

   [Download the Terraform distribution](https://www.terraform.io/downloads.html) and follow [this guide](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started) to install it.

- macOS {#macos}

   Use one of the following methods:
   * [Download the Terraform distribution](https://www.terraform.io/downloads.html) and follow [this guide](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started) to install it.
   * Install Terraform using the [Homebrew](https://brew.sh) package manager and the command below:

      ```bash
      brew install terraform
      ```

{% endlist %}

### Get the authentication credentials {#get-credentials}

Use a [service account](../../iam/concepts/users/service-accounts.md) to manage the Yandex Cloud infrastructure via Terraform. It will help you flexibly configure access permissions to resources.

You can also use Terraform under your [Yandex account](../../iam/concepts/users/accounts.md#passport), as well as a [federated](../../iam/concepts/users/accounts.md#saml-federation) or [local](../../iam/concepts/users/accounts.md#local) user account, but this method is less secure. For more information, see the end of this section.

1. If you do not have the Yandex Cloud CLI yet, [install it](../../cli/quickstart.md#install).

1. Set up the CLI profile to run operations under the service account:

    {% list tabs group=instructions %}

    - CLI {#cli}

      1. Create an [authorized key](../../iam/concepts/authorization/key.md) for your service account and save it to the file:

          ```bash
          yc iam key create \
            --service-account-id <service_account_ID> \
            --folder-name <service_account_folder_name> \
            --output key.json
          ```

          Where:
          * `service-account-id`: Service account ID.
          * `folder-name`: Name of the folder in which the service account was created.
          * `output`: Name of the file with the authorized key.

          Result:

          ```text
          id: aje8nn871qo4********
          service_account_id: ajehr0to1g8b********
          created_at: "2022-09-14T09:11:43.479156798Z"
          key_algorithm: RSA_2048
          ```

      1. Create a CLI profile to run operations on behalf of the service account. Name the profile:

          ```bash
          yc config profile create <profile_name>
          ```

          Result:

          ```text
          Profile 'sa-terraform' created and activated
          ```

      1. Configure the profile:

          ```bash
          yc config set service-account-key key.json
          yc config set cloud-id <cloud_ID>
          yc config set folder-id <folder_ID>
          ```

          Where:
          * `service-account-key`: Service account authorized key file.
          * `cloud-id`: [Cloud ID](../../resource-manager/operations/cloud/get-id.md).
          * `folder-id`: [Folder ID](../../resource-manager/operations/folder/get-id.md).

    {% endlist %}

1. Add your credentials to the environment variables:

    {% list tabs group=programming_language %}
    
    - Bash {#bash}
    
       ```bash
       export YC_TOKEN=$(yc iam create-token)
       export YC_CLOUD_ID=$(yc config get cloud-id)
       export YC_FOLDER_ID=$(yc config get folder-id)
       ```
    
       Where:
       * `YC_TOKEN`: [IAM token](../../iam/concepts/authorization/iam-token.md).
       * `YC_CLOUD_ID`: Cloud ID.
       * `YC_FOLDER_ID`: Folder ID.
    
    - PowerShell {#powershell}
    
       ```powershell
       $Env:YC_TOKEN=$(yc iam create-token)
       $Env:YC_CLOUD_ID=$(yc config get cloud-id)
       $Env:YC_FOLDER_ID=$(yc config get folder-id)
       ```
    
       Where:
       * `YC_TOKEN`: [IAM token](../../iam/concepts/authorization/iam-token.md).
       * `YC_CLOUD_ID`: Cloud ID.
       * `YC_FOLDER_ID`: Folder ID.
    
    {% endlist %}
    
    {% note info %}
    
    The IAM token [lifetime](../../iam/concepts/authorization/iam-token.md#lifetime) does not exceed 12 hours; however, we recommend requesting a token more often, e.g., every hour.
    
    To have the IAM token reissued automatically, the `export IAM_TOKEN=$(yc iam create-token)` script can be used.
    
    {% endnote %}

{% cut "Managing resources under a Yandex account, local account, or federated account" %}

{% note warning %}

Managing resources under a user's [Yandex account](../../iam/concepts/users/accounts.md#passport), [local account](../../iam/concepts/users/accounts.md#local), or [federated account](../../iam/concepts/users/accounts.md#saml-federation) is less secure than under a [service account](../../iam/concepts/users/service-accounts.md).

{% endnote %}

If you do not have the Yandex Cloud CLI yet, [install and initialize it](../../cli/quickstart.md#install).

The folder used by default is the one specified when [creating](../../cli/operations/profile/profile-create.md) the CLI profile. To change the default folder, use the `yc config set folder-id <folder_ID>` command. You can also specify a different folder for any command using `--folder-name` or `--folder-id`. If you access a resource by its name, the search will be limited to the default folder. If you access a resource by its ID, the search will be global, i.e., through all folders based on access permissions.

If you use a federated or local account, get authenticated in the [CLI](../../cli/index.md):

* [As a federated user](../../cli/operations/authentication/federated-user.md)
* [As a local user](../../cli/operations/authentication/local-user.md)

Add your credentials to the environment variables:

{% list tabs group=programming_language %}

- Bash {#bash}

   ```bash
   export YC_TOKEN=$(yc iam create-token)
   export YC_CLOUD_ID=$(yc config get cloud-id)
   export YC_FOLDER_ID=$(yc config get folder-id)
   ```

   Where:
   * `YC_TOKEN`: [IAM token](../../iam/concepts/authorization/iam-token.md).
   * `YC_CLOUD_ID`: Cloud ID.
   * `YC_FOLDER_ID`: Folder ID.

- PowerShell {#powershell}

   ```powershell
   $Env:YC_TOKEN=$(yc iam create-token)
   $Env:YC_CLOUD_ID=$(yc config get cloud-id)
   $Env:YC_FOLDER_ID=$(yc config get folder-id)
   ```

   Where:
   * `YC_TOKEN`: [IAM token](../../iam/concepts/authorization/iam-token.md).
   * `YC_CLOUD_ID`: Cloud ID.
   * `YC_FOLDER_ID`: Folder ID.

{% endlist %}

{% note info %}

The IAM token [lifetime](../../iam/concepts/authorization/iam-token.md#lifetime) does not exceed 12 hours; however, we recommend requesting a token more often, e.g., every hour.

To have the IAM token reissued automatically, the `export IAM_TOKEN=$(yc iam create-token)` script can be used.

{% endnote %}

{% endcut %}

### Create a Terraform configuration file {#configure-terraform}

1. Create a directory with any name, for example, `cloud-terraform`. It will store the Terraform configuration files.
1. Create a configuration file with the `.tf` extension in this directory, for example, `example.tf`.

### Configure your provider {#configure-provider}

{% note info %}

These settings apply to Terraform `0.13` and higher. We recommend using the latest stable version of Terraform.

{% endnote %}

1. If you previously configured a provider from the HashiCorp registry, save its settings:

   {% list tabs group=operating_system %}

   - Linux/macOS {#linux-macos}

     ```bash
     mv ~/.terraformrc ~/.terraformrc.old
     ```

   - Windows {#windows}

     ```powershell
     mv $env:APPDATA/terraform.rc $env:APPDATA/terraform.rc.old
     ```

   {% endlist %}

1. Specify the source the provider will be installed from.

   {% list tabs group=operating_system %}

   - Linux/macOS {#linux-macos}

     Open the Terraform CLI configuration file:

     ```bash
     nano ~/.terraformrc
     ```

     {% note info %}
     
     The `.terraformrc` file must be in the user's home root folder, e.g., `/home/user/` or `/User/user/`.
     
     {% endnote %}

   - Windows {#windows}

     Open the Terraform CLI `terraform.rc` configuration file in your user's `%APPDATA%` folder.

     To find out the absolute path to the `%APPDATA%` folder, run the `echo %APPDATA%` command for `cmd` or the `$env:APPDATA` command for PowerShell.

   {% endlist %}

   Add the following section to the file:

   ```hcl
   provider_installation {
     network_mirror {
       url = "https://terraform-mirror.yandexcloud.net/"
       include = ["registry.terraform.io/*/*"]
     }
     direct {
       exclude = ["registry.terraform.io/*/*"]
     }
   }
   ```

   For more information about setting up mirrors, see the [documentation](https://www.terraform.io/cli/config/config-file#explicit-installation-method-configuration).
1. At the beginning of the `.tf` configuration file, add the following sections:

   
   ```hcl
   terraform {
     required_providers {
       yandex = {
         source = "yandex-cloud/yandex"
       }
     }
     required_version = ">= 0.13"
   }

   provider "yandex" {
     zone = "<default_availability_zone>"
   }
   ```



   Where:
   * `source`: Provider's global [source address](https://www.terraform.io/docs/language/providers/requirements.html#source-addresses).
   * `required_version`: Minimum Terraform version the provider is compatible with.
   * `provider`: Provider name.
   * `zone`: Default [availability zone](../../overview/concepts/geo-scope.md) for all your cloud resources.
1. Run the `terraform init` command in the folder with the `.tf` configuration file. This command initializes the providers specified in the configuration files and allows you to work with the provider resources and data sources.

If the provider installation failed, create a [support](https://center.yandex.cloud/support) request indicating the provider name and version.

If you used the `.terraform.lock.hcl` file, run the `terraform providers lock` command prior to the initialization specifying the URL of the mirror to upload the provider from and the platforms the configuration will run on:

```bash
terraform providers lock -net-mirror=https://terraform-mirror.yandexcloud.net -platform=<platform_name_1> -platform=<platform_name_2> yandex-cloud/yandex
```

Where:
* `-net-mirror`: Address of the mirror to upload the provider from.
* `-platform`: Platforms to use the configuration on. The possible values are:
  * `windows_amd64`: Windows 64-bit.
  * `linux_amd64`: Linux 64-bit.
  * `darwin_arm64`: macOS 64-bit.

If you used the [Terraform modules](terraform-modules.md), first run `terraform init`, then delete the lock file. After that, run the `terraform providers lock` command.

For more information about the `terraform providers lock` command, see [this Terraform article](https://developer.hashicorp.com/terraform/cli/commands/providers/lock).

## Describe a data source {#prepare-plan}

{% note tip %}

In the Terraform code, data sources are defined using the `data` block.

{% endnote %}

1. In the configuration file, paste this code after the provider settings:

    ```hcl
    data "yandex_compute_image" "my_image" {
      family = "ubuntu-2204-lts"
    }

    output "my_image_id" {
      value = data.yandex_compute_image.my_image.id
    }
    ```

    Where:

    * `data "yandex_compute_image"`: Disk image description as a data source:
        * `family`: [Image family](../../compute/concepts/image.md#family).
    * `output "resource_active"`: Output variable with information about the current image ID for the specified family:
        * `value`: Return value.

    For more information about the `yandex_compute_image` data source parameters, see the [relevant provider documentation](../../terraform/data-sources/compute_image.md).

1. Create the resources:

    1. In the terminal, navigate to the configuration file directory.
    1. Make sure the configuration is correct using this command:
    
       ```bash
       terraform validate
       ```
    
       If the configuration is valid, you will get this message:
    
       ```bash
       Success! The configuration is valid.
       ```
    
    1. Run this command:
    
       ```bash
       terraform plan
       ```
    
       You will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
    1. Apply the configuration changes:
    
       ```bash
       terraform apply
       ```
    
    1. Type `yes` and press **Enter** to confirm the changes.

    Terraform will create the required resources and display their output variables.

## Check the result {#check}

To check the results, run this command:

```bash
terraform output
```

Result:

```text
my_image_id = "fd8li2lvvfc6bdj4c787"
```

Then you can use this ID to [create a VM](../../compute/operations/images-with-pre-installed-software/create.md), e.g.:

```hcl
resource "yandex_compute_disk" "boot-disk" {
  name     = "<disk_name>"
  type     = "<disk_type>"
  zone     = "<availability_zone>"
  size     = "<disk_size>"
  image_id = data.yandex_compute_image.my_image.id
}

...
```

## See also {#see-also}

* [Getting started with Terraform](terraform-quickstart.md).
* [Uploading Terraform states to Object Storage](terraform-state-storage.md).
* [Locking Terraform states using Managed Service for YDB](terraform-state-lock.md).
* [Using Yandex Cloud modules in Terraform](terraform-modules.md).