有时天灾人祸, 当本人尝试利用terraform 创建1个vm时, 当执行到最后一步时出现了问题
从日志看出, 其实资源能正确创建, 但是同步state file时出现了问题, 这个项目的state file是存放在GCS /bucket 上的。
backend.tf
terraform {
backend "gcs" {
bucket = "jason-hsbc"
prefix = "terraform/state"
}
}
root cause? 日志上写的是网络问题, 估计是踮脚的东西突然塌了几秒
先试下rerun, 其实我已经知道rerun注定失败, 因为这时, gcs 上的state file 并没有这个vm资源, 但是这个vm资源其实已经被创建。
所以当下次执行同样的terraform version时, terraform 还是会尝试创建这个vm资源, 但是其id 已经被上次创建的vm占用. 失败!
这个方法肯定是work的, 相当有效。
但是过于暴力, 而且在生产环境不一定让开发人员这么做。
具体步骤是先把state file 从gcs download 到本地, 然后把这个vm的资源加上去, 再上传回gcs
这个 方案 又过于技术了, 而且风险更高, 万一改错了别的地方…
有没有自动同步state file的方法呢?
有!
先看看 terraform refresh的解释:
1.更新状态信息:terraform refresh 从基础设施中获取当前的资源状态,并将这些信息更新到 Terraform 的状态文件中。这样,Terraform 就能了解实际基础设施的当前状态,以便在后续的操作中进行准确的计划和变更。
2.检测变更:通过与当前基础设施进行比较,terraform refresh 可以检测到已经发生的变更。它会比较基础设施中的资源属性和 Terraform 状态文件中的资源属性,并标记出任何不匹配的地方。
3.同步状态:如果资源的属性在基础设施中发生了变化,terraform refresh 将更新 Terraform 状态文件中相应资源的属性信息。这样,在后续的计划和应用变更过程中,Terraform 将使用最新的属性信息来确保与基础设施保持一致。
4.识别已删除资源:terraform refresh 还可以识别基础设施中已被删除的资源。它会在 Terraform 的状态文件中标记这些资源,并在后续的计划和应用步骤中通知您这些资源已被删除,以便您可以相应地处理。
上面的解释来自于 chatgpt
通俗地讲
但是!
不支持本文开头介绍的情况 – terraform refresh 不支持 资源已经被创建 而没有写入state file的case
看来正主出来了
语法: terraform import 《resource tf address》《resource instance ID》
出现了两个变量, 下面是解释
就是 这个资源的terraform 地址啦
我们可以用 terraform state list 来查看state file 已经注册的所有resource 的 terraform 地址
[gateman@manjaro-x13 Terraform-GCP-config]$ terraform state list
module.artifact_registry.google_artifact_registry_repository.repository
module.artifact_registry.google_project_service.artifact_registry
module.bigquery.google_project_service.bq_api
module.bucket.google_storage_bucket.bucket-jason-hsbc
module.bucket.google_storage_bucket.bucket-jason-hsbc-dataflow
module.network.google_compute_firewall.tf-vpc0-firewall
module.network.google_compute_firewall.tf-vpc1-firewall
module.network.google_compute_network.tf-vpc0
module.network.google_compute_network.tf-vpc1
module.network.google_compute_router.tf-vpc0-nat-router
module.network.google_compute_router_nat.tf-vpc0-cloud-nat
module.network.google_compute_subnetwork.tf-vpc0-subnet0
module.network.google_compute_subnetwork.tf-vpc0-subnet1
module.network.google_compute_subnetwork.tf-vpc1-subnet0
module.pubsub.google_pubsub_subscription.subscription_a1
module.pubsub.google_pubsub_subscription.subscription_a2
module.pubsub.google_pubsub_topic.topic_a
module.vm.google_compute_instance.k8s-master
module.vm.google_compute_instance.k8s-node0
module.vm.google_compute_instance.k8s-node1
module.vm.google_compute_instance.tf-vpc0-subnet0-vm0
module.vm.google_compute_instance.tf-vpc0-subnet0-vm1
module.vm.google_compute_instance.tf-vpc0-subnet0-vpc1-subnet0-vm0
module.vm.google_compute_instance.tf-vpc0-subnet1-vm0
module.vm.google_compute_instance.tf-vpc1-subnet0-vm0
module.vm.google_compute_instance_from_template.tf-vpc0-subnet0-vm20
module.vm.google_compute_instance_from_template.tf-vpc0-subnet0-vm21
module.vm.google_compute_instance_from_template.tf-vpc0-subnet1-vm1
module.vm.google_compute_instance_template.vm-template-vpc0-subnet0-e2-small-tomcat
module.bigquery.module.bq.google_bigquery_dataset.dataset1
module.bigquery.module.bq.google_bigquery_table.table1
[gateman@manjaro-x13 Terraform-GCP-config]$
对应的就是该资源在GCP 上创建的实例ID
我们可以用 terraform show 查看全部
或者 terraform state show 《resource tf address》 来查看某个资源的instance id
gateman@manjaro-x13 Terraform-GCP-config]$ terraform state show module.vm.google_compute_instance_from_template.tf-vpc0-subnet0-vm21
# module.vm.google_compute_instance_from_template.tf-vpc0-subnet0-vm21:
resource "google_compute_instance_from_template" "tf-vpc0-subnet0-vm21" {
attached_disk = []
can_ip_forward = false
cpu_platform = "Unknown CPU Platform"
current_status = "TERMINATED"
deletion_protection = false
enable_display = false
guest_accelerator = []
id = "projects/jason-hsbc/zones/europe-west2-c/instances/tf-vpc0-subnet0-vm21"
instance_id = "442217657071685871"
label_fingerprint = "42WmSpB8rSM="
labels = {}
machine_type = "e2-small"
metadata = {}
metadata_fingerprint = "t09GrcHA4z0="
name = "tf-vpc0-subnet0-vm21"
project = "jason-hsbc"
resource_policies = []
scratch_disk = []
self_link = "https://www.googleapis.com/compute/v1/projects/jason-hsbc/zones/europe-west2-c/instances/tf-vpc0-subnet0-vm21"
service_account = [
{
email = "[email protected]"
scopes = [
"https://www.googleapis.com/auth/cloud-platform",
]
},
]
source_instance_template = "https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/instanceTemplates/vm-template-vpc0-subnet0-e2-small-tomcat?uniqueId=7261720283884147418"
tags = []
tags_fingerprint = "42WmSpB8rSM="
zone = "europe-west2-c"
boot_disk {
auto_delete = true
device_name = "persistent-disk-0"
mode = "READ_WRITE"
source = "https://www.googleapis.com/compute/v1/projects/jason-hsbc/zones/europe-west2-c/disks/tf-vpc0-subnet0-vm21"
initialize_params {
image = "https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/images/e2-small-tomcat-image"
labels = {}
resource_manager_tags = {}
size = 20
type = "pd-standard"
}
}
network_interface {
access_config = []
alias_ip_range = []
name = "nic0"
network = "https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/networks/tf-vpc0"
network_ip = "192.168.0.34"
queue_count = 0
stack_type = "IPV4_ONLY"
subnetwork = "https://www.googleapis.com/compute/v1/projects/jason-hsbc/regions/europe-west2/subnetworks/tf-vpc0-subnet0"
subnetwork_project = "jason-hsbc"
}
scheduling {
automatic_restart = false
instance_termination_action = "STOP"
min_node_cpus = 0
on_host_maintenance = "TERMINATE"
preemptible = true
provisioning_model = "SPOT"
}
shielded_instance_config {
enable_integrity_monitoring = true
enable_secure_boot = false
enable_vtpm = true
}
}
[gateman@manjaro-x13
上面的 projects/jason-hsbc/zones/europe-west2-c/instances/tf-vpc0-subnet0-vm21 就是instance id了
所以为了解决本文的问题
我们应该执行
terraform import module.vm.google_compute_instance_from_template.tf-vpc0-subnet1-vm1 projects/jason-hsbc/zones/europe-west2-c/instances/tf-vpc0-subnet1-vm1
但是很不幸, 出现了下面的错误
Error: resource google_compute_instance_from_template doesn’t support import
google_compute_instance_from_template 类型的vm不支持 terraform import!
所以本文的问题还是用方法1 解决的。
但是我相信一些其他类型的资源, 例如bucket, BQ table等可以用这个方法解决state file同步问题。