用terraform管理现存资源
通过阅读前面几篇文章,希望大家了解了基础架构及代码的基本概念,以及如何使用packer和terraform在腾讯云上进行新云资源的高效编排。但是在现实世界里,云管理团队还要管理以前那些没有通过terraform管理的资源,本文会作出一个通用流程,方便大家使用。
首先,希望大家阅读Terraform的几个关键概念 ,并了解状态文件的作用。我们可以了解到,Terraform源文件的作用是声明使用者想要什么样的资源,状态文件的作用是记录最近一次操作以后,各云资源的状态。
接管一个已经存在的云资源实际上就是要在terraform源文件和状态文件里都反映出该资源的状态,这样就可以无缝对接了。
第一步-找到资源的id
首先我们需要找到该云资源的id,以腾讯云的CVM为例,在腾讯云控制台里可以看到cvm的id。
第二步-导入资源文件
然后我们需要写一个空的terraform文件,比如:
代码语言:txt复制➜ tencent-cloud cat tencentcloud.tf
provider tencentcloud {}
resource "tencentcloud_instance" "test" {}
并在该目录里做terraform init:
代码语言:txt复制➜ tencent-cloud terraform init
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "tencentcloud" (terraform-providers/tencentcloud) 1.16.0...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.tencentcloud: version = "~> 1.16"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
初始化完成以后就可以用terraform import来把该资源导入状态文件:
代码语言:txt复制➜ tencent-cloud terraform import tencentcloud_instance.test ins-eh8r833f
tencentcloud_instance.test: Importing from ID "ins-eh8r833f"...
tencentcloud_instance.test: Import prepared!
Prepared tencentcloud_instance for import
tencentcloud_instance.test: Refreshing state... [id=ins-eh8r833f]
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.
现在该资源就在状态文件里了:
代码语言:txt复制➜ tencent-cloud cat terraform.tfstate
{
"version": 4,
"terraform_version": "0.12.5",
"serial": 1,
"lineage": "1858f6d7-8ec5-99ae-be24-06ae9accd8d1",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "tencentcloud_instance",
"name": "test",
"provider": "provider.tencentcloud",
"instances": [
{
"schema_version": 0,
"attributes": {
"allocate_public_ip": true,
"availability_zone": "ap-shanghai-2",
"data_disks": [],
"disable_monitor_service": null,
"disable_security_service": null,
"hostname": null,
"id": "ins-eh8r833f",
"image_id": "img-pi0ii46r",
"instance_charge_type": null,
"instance_charge_type_prepaid_period": null,
"instance_charge_type_prepaid_renew_flag": null,
"instance_name": "Unnamed",
"instance_status": "RUNNING",
"instance_type": "S4.SMALL2",
"internet_charge_type": null,
"internet_max_bandwidth_out": 1,
"key_name": null,
"password": null,
"private_ip": "172.17.0.16",
"project_id": null,
"public_ip": "49.235.78.211",
"security_groups": [
"sg-85ei5m7e"
],
"subnet_id": "subnet-bq3v2fsr",
"system_disk_size": 50,
"system_disk_type": "CLOUD_PREMIUM",
"tags": null,
"user_data": null,
"user_data_raw": null,
"vpc_id": "vpc-khdn2ary"
},
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ=="
}
]
}
]
}
第三步-更新源文件
现在我们还需要把该资源写到terraform源文件里,我们可以用terraform show:
代码语言:txt复制➜ tencent-cloud terraform show
# tencentcloud_instance.test:
resource "tencentcloud_instance" "test" {
allocate_public_ip = true
availability_zone = "ap-shanghai-2"
id = "ins-eh8r833f"
image_id = "img-pi0ii46r"
instance_name = "Unnamed"
instance_status = "RUNNING"
instance_type = "S4.SMALL2"
internet_max_bandwidth_out = 1
private_ip = "172.17.0.16"
public_ip = "49.235.78.211"
security_groups = [
"sg-85ei5m7e",
]
subnet_id = "subnet-bq3v2fsr"
system_disk_size = 50
system_disk_type = "CLOUD_PREMIUM"
vpc_id = "vpc-khdn2ary"
}
现在就可以把这一段代码拷贝到源文件里边,另外删除一些不可设置的选项,包括id,public_ip以及instance_status:
代码语言:txt复制➜ tencent-cloud cat tencentcloud.tf
provider tencentcloud {}
resource "tencentcloud_instance" "test" {
allocate_public_ip = true
availability_zone = "ap-shanghai-2"
image_id = "img-pi0ii46r"
instance_name = "Unnamed"
instance_type = "S4.SMALL2"
internet_max_bandwidth_out = 1
private_ip = "172.17.0.16"
security_groups = [
"sg-85ei5m7e",
]
subnet_id = "subnet-bq3v2fsr"
system_disk_size = 50
system_disk_type = "CLOUD_PREMIUM"
vpc_id = "vpc-khdn2ary"
}
核对
这时候再做terraform plan,会发现terraform已经接管成功了:
代码语言:txt复制➜ tencent-cloud terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
tencentcloud_instance.test: Refreshing state... [id=ins-eh8r833f]
------------------------------------------------------------------------
No changes. Infrastructure is up-to-date.
This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
从现在开始,terraform已经成功接管成功了,terraform可以通过destroy来删除这个资源,也可以通过修改代码的方式对资源进行修改,比如下边的代码通过添加标签,让管理更加方便:
代码语言:txt复制➜ tencent-cloud cat tencentcloud.tf
provider tencentcloud {}
resource "tencentcloud_instance" "test" {
allocate_public_ip = true
availability_zone = "ap-shanghai-2"
image_id = "img-pi0ii46r"
instance_name = "Unnamed"
instance_type = "S4.SMALL2"
internet_max_bandwidth_out = 1
private_ip = "172.17.0.16"
security_groups = [
"sg-85ei5m7e",
]
subnet_id = "subnet-bq3v2fsr"
system_disk_size = 50
system_disk_type = "CLOUD_PREMIUM"
vpc_id = "vpc-khdn2ary"
tags = {
name="demo"
project="test-project"
owner="yulei"
}
}
➜ tencent-cloud terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
tencentcloud_instance.test: Refreshing state... [id=ins-eh8r833f]
------------------------------------------------------------------------
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:
# tencentcloud_instance.test will be updated in-place
~ resource "tencentcloud_instance" "test" {
allocate_public_ip = true
availability_zone = "ap-shanghai-2"
id = "ins-eh8r833f"
image_id = "img-pi0ii46r"
instance_name = "Unnamed"
instance_status = "RUNNING"
instance_type = "S4.SMALL2"
internet_max_bandwidth_out = 1
private_ip = "172.17.0.16"
public_ip = "49.235.78.211"
security_groups = [
"sg-85ei5m7e",
]
subnet_id = "subnet-bq3v2fsr"
system_disk_size = 50
system_disk_type = "CLOUD_PREMIUM"
tags = {
"name" = "demo"
"owner" = "yulei"
"theprojectname" = "test-project"
}
vpc_id = "vpc-khdn2ary"
}
Plan: 0 to add, 1 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
可以看到,新加的tags代码会导致terraform直接更新这个cvm实例,接管确实成功了。
结语
Terraform有着强大的云资源编排功能,但是很多读者以为terraform只能管理新资源,希望读者通过本文可以了解如何通过terraform import来管理现存资源,并能够从这里推广出去,把所有的现有云资源全部都写成代码,提高云资源的管理效率。