

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 了解地形資料來源
<a name="data-sources"></a>

部署堆疊依賴先前現有資源的資料是很常見的。大多數 IaC 工具都有一種導入由其他進程創建的資源的方法。這些匯入的資源通常是唯讀的 (雖然 [IAM 角色](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IRole.html#attachwbrinlinewbrpolicypolicy)是明顯的例外)，並且用來存取堆疊中資源所需的資料。 AWS CloudFormation 允許導入資源，但這個想法可以通過查看 AWS Cloud Development Kit (AWS CDK).

 AWS CDK 可協助開發人員使用現有的程式設計語言產生 CloudFormation範本。 AWS CDK 作業的最終結果是中的匯入資源 CloudFormation。但是，與 AWS CDK 使用的語法可以更輕鬆地與 Terraform 進行比較。以下是使用匯入資源的範例 AWS CDK。

```
const importedBucket: IBucket = Bucket.fromBucketAttributes(
    scope,
    "imported-bucket",
    {
        bucketName: "My_S3_Bucket"
    }
);
```

導入的資源通常是通過在您用來創建相同類型的新資源的同一個類上調用靜態方法來創建的。調用`new Bucket(...`將創建一個新的資源，並調用`Bucket.fromBucketAttributes(...`導入一個現有的。您可以將值區屬性的子集傳遞給函數， AWS CDK 以便找到正確的值區。不過，另一個不同之處在於，建立新值區會傳回`Bucket`類別的完整執行個體，其中包含所有可用的屬性和方法。匯入資源會傳回一個`IBucket`，此類型僅包含`Bucket`必須具有的屬性。雖然您可以從外部堆棧導入資源，但是您可以使用它執行的操作的選項是有限的。

在 Terraform 中，類似的目標是通過使用[數據](https://developer.hashicorp.com/terraform/language/data-sources)源來實現。大多數定義的 Terraform 資源都有一個隨附的資料來源。以下是 Terraform S3 儲存貯體資源後跟其對應資料來源的範例。

```
# S3 Bucket resource:
resource "aws_s3_bucket" "My_S3_Bucket" {
  bucket = "My_S3_Bucket"
}

# S3 Bucket data source:
data "aws_s3_bucket" "My_S3_Bucket" {
  bucket = "My_S3_Bucket"
}
```

這兩個項目之間的唯一區別是名稱前綴。如資料來源的[文件](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_bucket)所示，可傳遞至資料來源的可用參數少於資源。這是因為資源使用這些參數來宣告新 S3 儲存貯體的所有屬性，而資料來源只需要足夠的資訊才能唯一識別和匯入現有資源的資料。

Terraform 資源的語法與資料來源之間的相似性可能很方便，但也可能會有問題。對於新手來說，Terraform 開發人員通常會在其配置中意外使用數據源而不是資源。地形資料來源永遠是唯讀的。您可以使用它們來取代讀取動作的對應資源 (例如向其他資源提供 ID 名稱)。但是，您不能將它們用於編寫操作，這從根本上改變了基礎資源的某些方面。因此，您可以將 Terraform 資料來源視為基礎資源的複製版本。

與之前的 AWS CDK iBucket 範例類似，資料來源適用於唯讀案例。如果您需要從現有資源取得資料，但不需要在堆疊中維護該資源，請使用資料來源。這方面的一個很好的例子是當您創建使用該帳戶的默認 VPC 的 Amazon EC2 實例時。由於 VPC 已經存在，您只需要提取其資料即可。下列程式碼範例顯示如何使用資料來識別目標 VPC。

```
data "aws_vpc" "default" {
  default = true
}

resource "aws_instance" "instance1" {
  ami           = "ami-123456"
  instance_type = "t2.micro"
  subnet_id     = data.aws_vpc.default.main_route_table_id
}
```