Import #

Jarang sekali tim memulai dari infrastruktur yang benar-benar kosong. Lebih sering, ada server, database, dan jaringan yang sudah berjalan dan dikelola secara manual jauh sebelum Terraform diperkenalkan. Import adalah mekanisme yang memungkinkan Terraform mengambil alih pengelolaan resource-resource ini tanpa harus menghapus dan membuat ulangnya. Dilakukan dengan benar, import adalah jembatan yang mulus antara infrastruktur manual dan infrastruktur as code.

Apa yang Import Lakukan (dan Tidak Lakukan) #

YANG IMPORT LAKUKAN:
  ✓ Membaca kondisi aktual resource dari cloud provider
  ✓ Menambahkan resource ke state Terraform
  ✓ Memungkinkan Terraform mengelola resource ini ke depannya

YANG IMPORT TIDAK LAKUKAN:
  ✗ Membuat atau mengubah konfigurasi .tf secara otomatis
    (kamu harus tulis sendiri — kecuali pakai -generate-config-out)
  ✗ Mengubah resource yang ada di cloud sedikitpun
  ✗ Menjamin konfigurasi .tf yang kamu tulis sudah sesuai
    (butuh terraform plan untuk verifikasi)

Menemukan Resource ID untuk Import #

Setiap resource memerlukan ID unik yang dikenali provider untuk proses import. Format ID berbeda-beda per resource type.

# AWS: Cara menemukan resource ID

# EC2 Instance — gunakan instance ID
aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId'
# Output: ["i-0abcdef1234567890"]

# VPC — gunakan VPC ID
aws ec2 describe-vpcs --query 'Vpcs[].VpcId'
# Output: ["vpc-0abcdef1234567890"]

# S3 Bucket — gunakan nama bucket
aws s3api list-buckets --query 'Buckets[].Name'
# Output: ["my-existing-bucket"]

# RDS Instance — gunakan DB identifier
aws rds describe-db-instances --query 'DBInstances[].DBInstanceIdentifier'
# Output: ["production-database"]

# Security Group — gunakan security group ID
aws ec2 describe-security-groups --query 'SecurityGroups[].GroupId'
# Output: ["sg-0abcdef1234567890"]
FORMAT ID UMUM DI BERBAGAI RESOURCE:
  aws_instance            → i-0abcdef1234567890
  aws_vpc                 → vpc-0abcdef1234567890
  aws_subnet              → subnet-0abcdef1234567890
  aws_security_group      → sg-0abcdef1234567890
  aws_s3_bucket           → nama-bucket (bukan ARN)
  aws_rds_instance        → db-identifier (bukan ARN)
  aws_iam_role            → nama-role
  aws_route53_record      → ZONE_ID_RECORD-NAME_TYPE
  aws_ecs_service         → cluster-name/service-name

Metode 1: Import via CLI #

Metode klasik menggunakan perintah terraform import di command line.

# Format: terraform import <resource_address> <resource_id>

# Langkah 1: Tulis blok resource kosong (atau dengan konfigurasi)
# main.tf:
resource "aws_instance" "web" {
  # Isi ini setelah import
}

# Langkah 2: Import
terraform import aws_instance.web i-0abcdef1234567890

# Output:
# aws_instance.web: Importing from ID "i-0abcdef1234567890"...
# aws_instance.web: Import prepared!
#   Prepared aws_instance for import
# aws_instance.web: Refreshing state... [id=i-0abcdef1234567890]
#
# Import successful!

# Langkah 3: Lihat semua atribut yang tersimpan di state
terraform state show aws_instance.web

# Langkah 4: Lengkapi konfigurasi berdasarkan output state show
resource "aws_instance" "web" {
  ami                    = "ami-0abcdef1234567890"
  instance_type          = "t3.micro"
  subnet_id              = "subnet-0abcdef1234"
  vpc_security_group_ids = ["sg-0abcdef1234567890"]

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

# Langkah 5: Verifikasi
terraform plan
# Hasil yang diharapkan: "No changes. Your infrastructure matches the configuration."

Metode 2: Import Blok Deklaratif (Terraform 1.5+) #

Blok import dalam konfigurasi lebih deklaratif, bisa di-commit ke version control, dan bisa digunakan bersama -generate-config-out.

# import.tf — file khusus untuk mendefinisikan import
import {
  to = aws_instance.web
  id = "i-0abcdef1234567890"
}

import {
  to = aws_vpc.main
  id = "vpc-0abcdef1234567890"
}

import {
  to = aws_security_group.web
  id = "sg-0abcdef1234567890"
}
# Generate konfigurasi otomatis berdasarkan kondisi aktual di cloud
terraform plan -generate-config-out=generated_resources.tf

# Output: file generated_resources.tf berisi konfigurasi yang di-generate
# Review file ini — mungkin ada atribut yang perlu disesuaikan

# Apply import
terraform apply

# Setelah selesai, hapus blok import (sudah tidak diperlukan)
# dan pindahkan konfigurasi dari generated_resources.tf ke file yang tepat

Import Massal: Strategi untuk Infrastruktur Besar #

Mengimport puluhan atau ratusan resource satu per satu tidak praktis. Ada strategi yang lebih efisien.

# Strategi 1: Script bash untuk import massal
#!/bin/bash

# Dapatkan semua instance ID
INSTANCES=$(aws ec2 describe-instances \
  --filters "Name=tag:ManagedBy,Values=manual" \
  --query 'Reservations[].Instances[].InstanceId' \
  --output text)

# Import setiap instance
for INSTANCE_ID in $INSTANCES; do
  # Buat nama resource dari tag Name
  NAME=$(aws ec2 describe-instances \
    --instance-ids $INSTANCE_ID \
    --query 'Reservations[0].Instances[0].Tags[?Key==`Name`].Value' \
    --output text | tr '[:upper:]' '[:lower:]' | tr ' ' '_')

  echo "Importing $NAME ($INSTANCE_ID)..."
  terraform import "aws_instance.$NAME" "$INSTANCE_ID"
done
# Strategi 2: for_each dalam blok import (Terraform 1.7+)
locals {
  instances = {
    web_1    = "i-0abcdef1234567890"
    web_2    = "i-0abcdef2345678901"
    worker_1 = "i-0abcdef3456789012"
  }
}

import {
  for_each = local.instances
  to       = aws_instance.servers[each.key]
  id       = each.value
}

resource "aws_instance" "servers" {
  for_each      = local.instances
  ami           = var.ami_id
  instance_type = "t3.micro"
}

Jebakan Umum Saat Import #

# JEBAKAN 1: Konfigurasi tidak cocok dengan kondisi aktual
# Setelah import, terraform plan menampilkan perubahan
# → konfigurasi .tf berbeda dari kondisi aktual
#
# terraform plan output:
# ~ resource "aws_instance" "web" {
#     ~ instance_type = "t3.micro" -> "t3.small"
#   }
#
# Ini berarti instance aktualnya t3.small, bukan t3.micro seperti yang kamu tulis
# Sesuaikan konfigurasi .tf dengan kondisi aktual

# JEBAKAN 2: Import resource dengan computed attributes
# Beberapa atribut hanya bisa diketahui setelah resource ada
# Jangan tulis nilai yang bisa berubah atau tidak deterministik di konfigurasi

# JEBAKAN 3: Import resource yang sudah punya dependency
# Jika VPC di-import tapi subnet belum, dependency graph tidak lengkap
# Import selalu dimulai dari resource "pondasi" (VPC, IAM role, dll.)
# sebelum resource yang bergantung padanya

# JEBAKAN 4: Lupa hapus blok import setelah selesai
# Blok import yang dibiarkan tidak menyebabkan error,
# tapi membuang waktu di setiap plan karena Terraform mencoba import ulang

Ringkasan #

  • Import tidak mengubah resource di cloud — ia hanya menambahkan resource ke state Terraform.
  • Import tidak membuat konfigurasi .tf otomatis (kecuali dengan -generate-config-out) — kamu harus tulis konfigurasi sendiri lalu verifikasi dengan terraform plan.
  • Tujuan akhir import yang benar: terraform plan menampilkan “No changes” setelah import selesai.
  • Blok import deklaratif (Terraform 1.5+) lebih clean dari CLI command — bisa di-commit, bisa di-review, bisa digunakan bersama -generate-config-out.
  • Import dari resource pondasi dulu — VPC sebelum subnet, subnet sebelum instance — agar dependency graph terbentuk dengan benar.
  • Hapus blok import setelah selesai — resource sudah di state, blok import tidak diperlukan lagi.

← Sebelumnya: Migration   Berikutnya: Anti-Pattern →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact