當我們想把原有的基礎架構改成用 Terraform 控制時,可以使用 terraform import
指令,將現有的資源匯入 Terraform。
不同於從零開始使用 Terraform 的工作流程,匯入的過程大概會經過以下步驟:
terraform plan
驗證組態檔的正確性我們以 AWS 的 EC2 instance 為測試案例,事先建立一台虛擬機 (可以使用前幾篇的範例來快速建立)。
找到 instance id: i-0123abcd
先建立 main.tf
,加入 aws provider 的設定
provider "aws" {
profile = "default"
region = "ap-northeast-1"
}
執行 terraform init
初始化你的工作資料夾
$ terraform init
接著在 main.tf
加入空的 aws_instance
resource
區塊
resource "aws_instance" "web" {}
執行 terraform import <resouce 名稱> <ID>
指令匯入
$ terraform import aws_instance.web i-042c5053c3ba5622e
aws_instance.web: Importing from ID "i-042c5053c3ba5622e"...
aws_instance.web: Import prepared!
Prepared aws_instance for import
aws_instance.web: Refreshing state... [id=i-042c5053c3ba5622e]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
成功之後,使用 terraform show
查看匯入的狀態
$ terraform show
# aws_instance.web:
resource "aws_instance" "web" {
ami = "ami-05484c96f4ac5493e"
...
vpc_security_group_ids = [
"sg-069828d4600dcef95",
"sg-07a788a7e5772455e",
]
credit_specification {
cpu_credits = "standard"
}
metadata_options {
http_endpoint = "enabled"
http_put_response_hop_limit = 1
http_tokens = "optional"
}
root_block_device {
delete_on_termination = true
device_name = "/dev/sda1"
encrypted = false
iops = 100
volume_id = "vol-06b89ae054f993045"
volume_size = 8
volume_type = "gp2"
}
timeouts {}
}
匯入狀態之後,還要建立一個完整的組態檔,之後才有辦法用 Terraform 控制基礎架構。
首先執行 terraform plan
,會看到錯誤訊息,提示缺少的設定。
$ terraform plan
Error: Missing required argument
on main.tf line 6, in resource "aws_instance" "web":
6: resource "aws_instance" "web" {}
The argument "instance_type" is required, but no definition was found.
Error: Missing required argument
on main.tf line 6, in resource "aws_instance" "web":
6: resource "aws_instance" "web" {}
The argument "ami" is required, but no definition was found.
我們依照錯誤訊息並參考狀態檔的內容,修改 aws_instance
resource
區塊如下:
resource "aws_instance" "web" {
ami = "ami-05484c96f4ac5493e"
instance_type = "t2.micro"
}
再次執行 terraform plan
,這次沒有錯誤了,不過還是有一些小狀況。
根據 plan
的結果,顯示組態檔跟實際的情況還是有差異。
$ terraform plan
...
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# aws_instance.web will be updated in-place
~ resource "aws_instance" "web" {
ami = "ami-05484c96f4ac5493e"
...
id = "i-042c5053c3ba5622e"
instance_state = "running"
instance_type = "t2.micro"
...
~ tags = {
- "Name" = "web-packer-terraform" -> null
- "topic" = "web-packer" -> null
}
tenancy = "default"
volume_tags = {}
vpc_security_group_ids = [
"sg-069828d4600dcef95",
"sg-07a788a7e5772455e",
]
...
}
Plan: 0 to add, 1 to change, 0 to destroy.
我們根據差異的內容,修改組態檔如下:
provider "aws" {
profile = "default"
region = "ap-northeast-1"
}
resource "aws_instance" "web" {
ami = "ami-05484c96f4ac5493e"
instance_type = "t2.micro"
tags = {
"Name" = "web-packer-terraform"
"topic" = "web-packer"
}
}
再次執行 terraform plan
,這次一模一樣了。
$ terraform plan
...
No changes. Infrastructure is up-to-date.
這個版本的組態檔可以先提交到版本控制裡,之後再做你想要的修改。