> ## Documentation Index
> Fetch the complete documentation index at: https://cdktn.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Sources - CDK Terrain

> Use data sources to allow Terraform to use external data, function output, and data from other configurations.

[Terraform data sources](https://developer.hashicorp.com/terraform/language/data-sources) fetch information from external APIs and from other Terraform configurations. For example, you may want to import disk image IDs from a cloud provider or share data between configurations for different parts of your infrastructure.

## When to Use Data Sources

Use data sources when you need to reference dynamic data that is not known until after Terraform (or OpenTofu) applies a configuration. For example, instance IDs that cloud providers assign on creation.

When data is static or you know the values before [synthesizing your code](/cli-reference/commands#synth), we recommend creating static references in your preferred programming language or using [Terraform variables](/concepts/variables-and-outputs).

## Define Data Sources

Data Sources are part of a [Terraform provider](/concepts/providers). All classes representing Data Sources are prefixed with `Data`.

In the following TypeScript example, a Terraform data source fetches the AWS region `DataAwsRegion` from the AWS provider.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { TerraformStack } from "cdktn";
  import { Construct } from "constructs";
  import { AwsProvider } from "@cdktn/provider-aws/lib/aws-provider";
  import { DataAwsRegion } from "@cdktn/provider-aws/lib/data-aws-region";

  export class DataSourcesStack extends TerraformStack {
    constructor(scope: Construct, id: string) {
      super(scope, id);

      new AwsProvider(this, "aws", {
        region: "us-west-2",
      });

      const region = new DataAwsRegion(this, "region");
    }
  }
  ```

  ```java Java theme={null}
  import imports.aws.data_aws_region.DataAwsRegion;
  import imports.aws.provider.AwsProvider;
  import imports.aws.provider.AwsProviderConfig;

  public class DataSourcesDefine extends TerraformStack {

      public DataSourcesDefine(Construct scope, String id){
          super(scope, id);

          new AwsProvider(this, "temp", AwsProviderConfig.builder()
                  .region("us-east-1")
                  .build()
          );
          //......
          DataAwsRegion region = new DataAwsRegion(this, "region");
      }
  }
  ```

  ```python Python theme={null}
  from cdktn import TerraformStack, App
  from imports.aws.data_aws_region import DataAwsRegion
  from imports.aws.provider import AwsProvider

  class HelloTerraform(TerraformStack):
      def __init__(self, scope: Construct, id: str):
          super().__init__(scope, id)

          AwsProvider(self, "aws",
                      region="us-east-1"
                      )

          # .....
          region = DataAwsRegion(self, "region")


  app = App()
  HelloTerraform(app, "data-sources")
  app.synth()
  ```

  ```csharp C# theme={null}
  using System;
  using System.IO;
  using System.Collections.Generic;
  using System.Linq;
  using Constructs;
  using Io.Cdktn;
  using aws.Provider;
  using aws.DataAwsRegion;

  namespace Examples
  {
      class DataSourceStack : TerraformStack
      {
          public DataSourceStack(Construct scope, string name) : base(scope, name)
          {

              new AwsProvider(this, "aws", new AwsProviderConfig
              {
                  Region = "eu-central-1"
              });

              DataAwsRegion region = new DataAwsRegion(this, "region", new DataAwsRegionConfig
              {
                  Name = "eu-central-1"
              });
          }
      }
  }
  ```

  ```go Go theme={null}
  import (
  	"github.com/aws/constructs-go/constructs/v10"
  	"github.com/aws/jsii-runtime-go"
  	"github.com/open-constructs/cdk-terrain-go/cdktn"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/dataawsregion"
  	aws "github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/provider"
  )

  func NewDatasourcesStack(scope constructs.Construct, name string) cdktn.TerraformStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
  		Region: jsii.String("eu-central-1"),
  	})

  	dataawsregion.NewDataAwsRegion(stack, jsii.String("region"), &dataawsregion.DataAwsRegionConfig{
  		Name: jsii.String("eu-central-1"),
  	})

  	return stack
  }

  ```
</CodeGroup>

## Remote State Data Source

The [`terraform_remote_state` data source](https://developer.hashicorp.com/terraform/language/state/remote-state-data) retrieves state data from a remote [Terraform backend](https://developer.hashicorp.com/terraform/language/backend). This allows you to use the root-level outputs of one or more Terraform configurations as input data for another configuration. For example, a core infrastructure team can handle building the core machines, networking, etc. and then expose some information to other teams that allows them to run their own infrastructure. Refer to the [Remote Backends page](/concepts/remote-backends) for more details.

The following example uses the global `DataTerraformRemoteState` to reference a Terraform Output of another Terraform configuration.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { TerraformStack } from "cdktn";
  import { Construct } from "constructs";
  import { AwsProvider } from "@cdktn/provider-aws/lib/aws-provider";
  import { DataTerraformRemoteState } from "cdktn";
  import { Instance } from "@cdktn/provider-aws/lib/instance";

  export class DataSourcesStack extends TerraformStack {
    constructor(scope: Construct, id: string) {
      super(scope, id);

      new AwsProvider(this, "aws", {
        region: "us-west-2",
      });

      const remoteState = new DataTerraformRemoteState(this, "remote-state", {
        organization: "hashicorp",
        workspaces: {
          name: "vpc-prod",
        },
      });

      new Instance(this, "foo", {
        instanceType: "t2.micro",
        ami: "ami-123456",
        subnetId: `${remoteState.get("subnet_id")}`,
      });
    }
  }
  ```

  ```java Java theme={null}
  import io.cdktn.cdktn.DataTerraformRemoteState;
  import io.cdktn.cdktn.DataTerraformRemoteStateRemoteConfig;
  import imports.aws.instance.Instance;
  import imports.aws.instance.InstanceConfig;

  public class DataSourcesRemoteState extends TerraformStack {

      public DataSourcesRemoteState(Construct scope, String id) {
          super(scope, id);

          // ....
          DataTerraformRemoteState remoteState = new DataTerraformRemoteState(this, "state",
                  DataTerraformRemoteStateRemoteConfig.builder()
                          .organization("hashicorp")
                          .workspaces(new NamedRemoteWorkspace("vpc-prod"))
                          .build());

          new Instance(this, "foo", InstanceConfig.builder()
                  // ....
                  .subnetId(remoteState.getString("subnet_id"))
                  .build());
      }
  }
  ```

  ```python Python theme={null}
  from cdktn import TerraformStack, App
  from cdktn import DataTerraformRemoteState, NamedRemoteWorkspace
  class HelloTerraformRemoteState(TerraformStack):
      def __init__(self, scope: Construct, id: str):
          super().__init__(scope, id)

          AwsProvider(self, "aws",
              region="us-east-1"
          )

          # .....
          remoteState = DataTerraformRemoteState(self, "vpc-prod-remote-state",
                              organization="hashicorp",
                              workspaces=NamedRemoteWorkspace(name='vpc-prod')
                          )

          Instance(self, "foo",
              # .....
              subnet_id=remoteState.get_string('subnet_id')
          )
  app = App()
  HelloTerraformRemoteState(app, "terraform-remotes-state")
  app.synth()
  ```

  ```csharp C# theme={null}
  using System;
  using System.IO;
  using System.Collections.Generic;
  using System.Linq;
  using Constructs;
  using Io.Cdktn;
  using aws.Provider;
  using aws.Instance;

  namespace Examples
  {
      class RemoteStateDataSourceStack : TerraformStack
      {
          public RemoteStateDataSourceStack(Construct scope, string name) : base(scope, name)
          {

              new AwsProvider(this, "aws", new AwsProviderConfig
              {
                  Region = "eu-central-1"
              });

              DataTerraformRemoteState remoteState = new DataTerraformRemoteState(this, "remoteState", new DataTerraformRemoteStateRemoteConfig
              {
                  Organization = "hashicorp",
                  Workspaces = new NamedRemoteWorkspace("vpc-prod")
              });

              new Instance(this, "foo", new InstanceConfig
              {
                  // ....
                  SubnetId = remoteState.GetString("subnet_id")
              });
          }
      }
  }
  ```

  ```go Go theme={null}
  import (
  	"github.com/aws/constructs-go/constructs/v10"
  	"github.com/aws/jsii-runtime-go"
  	"github.com/open-constructs/cdk-terrain-go/cdktn"
  	"github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/instance"
  	aws "github.com/open-constructs/cdk-terrain/examples/go/documentation/generated/hashicorp/aws/provider"
  )

  func RemoteStateDataSourceStack(scope constructs.Construct, name string) cdktn.TerraformStack {
  	stack := cdktn.NewTerraformStack(scope, &name)

  	aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
  		Region: jsii.String("eu-central-1"),
  	})

  	remote_state := cdktn.NewDataTerraformRemoteState(stack, jsii.String("remote_state"), &cdktn.DataTerraformRemoteStateRemoteConfig{
  		Organization: jsii.String("hashicorp"),
  		Workspaces:   cdktn.NewNamedRemoteWorkspace(jsii.String("vpc-prod")),
  	})

  	instance.NewInstance(stack, jsii.String("region"), &instance.InstanceConfig{
  		SubnetId: remote_state.GetString(jsii.String("subnet_id")),
  	})

  	return stack
  }

  ```
</CodeGroup>

### Large Data Source Configurations

A few individual Terraform Data Sources have very deeply nested schemas with a lot of attributes. This blows up the config classes and slows down the code generation for languages besides Typescript. To work around this we sometimes limit the depth of the config classes and use `any` on deeper level, some attributes we directly expose as `any` on the top level config class.

* `aws` Provider:
  * `data.aws_quicksight_analysis.definition` is set to `any`
