第 12 章:把現有架構匯入狀態檔
當我們想把原有的基礎架構改成用 Terraform 控制時,可以使用 terraform import
指令,將現有的資源匯入 Terraform。
不同於從零開始使用 Terraform 的工作流程,匯入的過程大概會經過以下步驟:
- 找出要匯入的資源 id
- 匯入到 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.
change configuration file
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.