公司项目往云上迁移,Terraform作为IoC基础设施即代码的新生代工具,声明式的语言简单粗暴,理所当然地成为我们的首选。
在建立项目的时候,我们希望可以让非专业人员也可以轻易上手,觉得把机器的管理都放到csv里边管理。那么是怎么实行的呢?
第一步, 构建符合你要求的cs文件, project.csv
hostname,ip,machine_type,disk
app001,10.176.19,16,e2-standard-4,
app002,10.176.19.17,e2-standard-4,
web001,10.176.19.18,e2-standard-4,web001-disk
web002,10.176.19.19,e2-standard-4,web002-disk
第二步,解释以及重构本地参数 main.tf:
locals {
vm_list = {
for hostname in csvdecode(file("project.csv")) :
hostname["hostname"] => hostname
#if hostname.status == "active" #可以增加过滤器,只对某些列符合条件的item进行处理
}
}
说明:这里边主要是通过csvdecode功能把csv转化成为list, 然后通过一个for循环把这个list组装成为一个map类型。使用map类型非常的重要以及必要。因为这步假如不用map类型, 第三步里边的循环读取就要使用count关键字来循环,产生的坏处是资源的名字变得没有意义。比如说你会在state 文件里边看到 google_compute_instance.myvm[0], google_compute_instance.myvm[1] 这样的资源名字。当你以后需要调整机器,比如说减少一台vm,那么这条从csv对应的记录后边的资源都会收到影响。而使用map则不会出现这种情况,你看到的资源会是 google_compute_instance.myvm[”app001“], google_compute_instance.myvm[”app002“]。 不但更有意义,还方便增删改。
第三步,使用
resource "google_compute_instance" "myvm" {
for_each = local.vm_list
project = "${var.project_id}"
name = "${var.project_name}${each.value.hostname}"
machine_type = each.value.machine_type
zone = "us-east4-c"
hostname = "${var.project_name}${each.value.hostname}.${var.project_name}.com"
allow_stopping_for_update = true
boot_disk {
initialize_params {
image = "image-base"
size = "30"
}
}
network_interface {
subnetwork = "projects/${var.vpchost_project_id}/regions/${var.region}/subnetworks/${var.project_name}-subnet"
network_ip = each.value.ip
}
dynamic attached_disk {
for_each = compact([each.value.disk])
content {
source = attached_disk.value
}
}
}
通过这样的处理, 我们以后要管理vm, 只要简单编辑这个csv文件就可以达到了。