Terraform Import 現有資源匯入

Terraform Import Existing Resources

Import 概述

Terraform Import 是一個強大的功能,允許您將現有的基礎設施資源匯入到 Terraform 的狀態管理中。當您有已經在雲端環境中運行的資源,但尚未使用 Terraform 進行管理時,Import 功能可以幫助您將這些資源納入 Infrastructure as Code(IaC)的管理範疇。

透過 Import,您可以:

  • 將手動建立的資源納入 Terraform 管理
  • 從其他工具遷移到 Terraform
  • 恢復遺失的 Terraform 狀態檔案
  • 整合不同團隊管理的資源

Import 使用情境

以下是常見的 Terraform Import 使用情境:

  1. 遺留系統遷移:將過去透過 AWS Console 或 CLI 手動建立的資源匯入 Terraform
  2. 災難復原:當 terraform.tfstate 檔案遺失或損壞時,重新建立狀態
  3. 團隊整合:將不同團隊或專案的資源統一管理
  4. 合規性需求:確保所有基礎設施都有對應的程式碼定義

基本 Import 語法

Terraform Import 的基本語法如下:

1
terraform import [options] <resource_type>.<resource_name> <resource_id>

參數說明:

  • resource_type:Terraform 資源類型(如 aws_instance
  • resource_name:您在 Terraform 配置中定義的資源名稱
  • resource_id:雲端提供商中的資源識別碼

匯入 EC2 執行個體

以下示範如何匯入一個現有的 EC2 執行個體。

首先,在 Terraform 配置檔案中定義資源區塊:

1
2
3
4
# main.tf
resource "aws_instance" "web_server" {
  # 配置將在匯入後補充
}

執行匯入命令:

1
terraform import aws_instance.web_server i-0abc123def456789

匯入成功後,使用 terraform state show 查看資源屬性:

1
terraform state show aws_instance.web_server

根據輸出結果,補充完整的資源配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
resource "aws_instance" "web_server" {
  ami           = "ami-0abcdef1234567890"
  instance_type = "t3.micro"

  tags = {
    Name        = "web-server"
    Environment = "production"
  }

  vpc_security_group_ids = ["sg-0123456789abcdef0"]
  subnet_id              = "subnet-0123456789abcdef0"
}

匯入 S3 儲存桶

S3 儲存桶的匯入相對簡單,使用儲存桶名稱作為識別碼:

1
2
3
4
5
6
7
8
9
# s3.tf
resource "aws_s3_bucket" "data_bucket" {
  # 配置將在匯入後補充
}

resource "aws_s3_bucket_versioning" "data_bucket_versioning" {
  bucket = aws_s3_bucket.data_bucket.id
  # 配置將在匯入後補充
}

執行匯入:

1
2
3
4
5
# 匯入 S3 儲存桶
terraform import aws_s3_bucket.data_bucket my-data-bucket-2024

# 匯入版本控制設定
terraform import aws_s3_bucket_versioning.data_bucket_versioning my-data-bucket-2024

補充完整配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
resource "aws_s3_bucket" "data_bucket" {
  bucket = "my-data-bucket-2024"

  tags = {
    Name        = "Data Bucket"
    Environment = "production"
  }
}

resource "aws_s3_bucket_versioning" "data_bucket_versioning" {
  bucket = aws_s3_bucket.data_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

匯入 IAM 資源

IAM 資源的匯入需要使用對應的識別碼格式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# iam.tf
resource "aws_iam_user" "developer" {
  # 配置將在匯入後補充
}

resource "aws_iam_role" "lambda_execution" {
  # 配置將在匯入後補充
}

resource "aws_iam_policy" "s3_access" {
  # 配置將在匯入後補充
}

執行匯入命令:

1
2
3
4
5
6
7
8
# 匯入 IAM 使用者(使用使用者名稱)
terraform import aws_iam_user.developer john.doe

# 匯入 IAM 角色(使用角色名稱)
terraform import aws_iam_role.lambda_execution lambda-execution-role

# 匯入 IAM 政策(使用 ARN)
terraform import aws_iam_policy.s3_access arn:aws:iam::123456789012:policy/S3AccessPolicy

Import Block(Terraform 1.5+)

從 Terraform 1.5 版本開始,您可以使用 import 區塊在配置檔案中宣告匯入操作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# imports.tf
import {
  to = aws_instance.web_server
  id = "i-0abc123def456789"
}

import {
  to = aws_s3_bucket.data_bucket
  id = "my-data-bucket-2024"
}

import {
  to = aws_iam_role.lambda_execution
  id = "lambda-execution-role"
}

使用 Import Block 的優點:

  • 可以版本控制匯入操作
  • 支援批次匯入多個資源
  • 可以與 terraform plan 整合預覽變更
  • 團隊成員可以審查匯入操作

執行匯入:

1
2
terraform plan   # 預覽匯入操作
terraform apply  # 執行匯入

產生配置(terraform plan -generate-config-out)

Terraform 1.5+ 提供了自動產生配置的功能,大幅簡化匯入流程:

1
terraform plan -generate-config-out=generated.tf

此命令會:

  1. 讀取 import 區塊中定義的資源
  2. 從雲端提供商讀取資源的當前狀態
  3. 自動產生對應的 Terraform 配置

完整工作流程範例:

1
2
3
4
5
# imports.tf - 定義要匯入的資源
import {
  to = aws_instance.imported_server
  id = "i-0abc123def456789"
}

執行產生配置:

1
2
3
4
5
6
7
8
# 產生配置到 generated.tf
terraform plan -generate-config-out=generated.tf

# 檢視產生的配置
cat generated.tf

# 確認無誤後執行匯入
terraform apply

產生的配置檔案範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# generated.tf(自動產生)
resource "aws_instance" "imported_server" {
  ami                         = "ami-0abcdef1234567890"
  instance_type               = "t3.micro"
  availability_zone           = "ap-northeast-1a"
  subnet_id                   = "subnet-0123456789abcdef0"
  vpc_security_group_ids      = ["sg-0123456789abcdef0"]
  associate_public_ip_address = true

  tags = {
    Name = "imported-server"
  }
}

最佳實踐

1. 匯入前準備

  • 備份現有的 terraform.tfstate 檔案
  • 確認資源識別碼正確無誤
  • 了解資源的相依性關係

2. 循序漸進匯入

1
2
3
4
5
6
7
8
9
# 建議的匯入順序
# 1. 先匯入基礎網路資源
terraform import aws_vpc.main vpc-0123456789abcdef0

# 2. 再匯入子網路
terraform import aws_subnet.public subnet-0123456789abcdef0

# 3. 最後匯入運算資源
terraform import aws_instance.web i-0abc123def456789

3. 驗證匯入結果

1
2
3
4
5
# 匯入後務必執行 plan 確認
terraform plan

# 應該顯示 "No changes" 表示配置與實際狀態一致
# Plan: 0 to add, 0 to change, 0 to destroy.

4. 使用工作區隔離

1
2
3
# 為匯入作業建立獨立工作區
terraform workspace new import-migration
terraform import aws_instance.web i-0abc123def456789

5. 文件記錄

建議在專案中維護一份匯入記錄:

1
2
3
4
5
6
# Import Log

| 日期 | 資源類型 | 資源名稱 | 資源 ID | 執行者 |
|------|----------|----------|---------|--------|
| 2024-11-04 | aws_instance | web_server | i-0abc123 | admin |
| 2024-11-04 | aws_s3_bucket | data_bucket | my-bucket | admin |

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy