英文:
Why 'terraform import' did not read my configuration?
问题
我正在使用Go构建一个Terraform插件/提供程序。我在我的模式中有以下内容(链接):
Importer: &schema.ResourceImporter{
State: resourceKubernetesClusterNodePoolImport,
}
这是函数的代码(链接):
func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
apiClient := m.(*civogo.Client)
clusterID, nodePoolID, err := utils.ResourceCommonParseID(d.Id())
if err != nil {
return nil, err
}
log.Printf("[INFO] retriving the node pool %s", nodePoolID)
resp, err := apiClient.GetKubernetesCluster(clusterID)
if err != nil {
if resp != nil {
return nil, err
}
}
d.Set("cluster_id", resp.ID)
for _, v := range resp.Pools {
if v.ID == nodePoolID {
d.Set("num_target_nodes", v.Count)
d.Set("target_nodes_size", v.Size)
}
}
return []*schema.ResourceData{d}, nil
}
当我在上面的函数顶部添加了这些调试行时,结果(reg
和ok
)为空且为false
:
reg, ok := d.GetOk("region")
log.Printf("resourceKubernetesClusterNodePoolImport reg %+v\n", reg)
log.Println("resourceKubernetesClusterNodePoolImport ok", ok)
log.Println("resourceKubernetesClusterNodePoolImport d.Get()", d.Get("region"))
if !ok {
return nil, fmt.Errorf("[ERR] Please provide a region in your import configuration")
}
跟踪信息如下:
$ echo $TF_LOG
INFO
$ tf import civo_kubernetes_node_pool.my_pool 1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad
2021-08-12T11:22:30.552+0800 [INFO] Terraform version: 1.0.3
2021-08-12T11:22:30.552+0800 [INFO] Go runtime version: go1.16.4
2021-08-12T11:22:30.552+0800 [INFO] CLI args: []string{"/usr/local/bin/terraform", "import", "civo_kubernetes_node_pool.my_pool", "1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad"}
2021-08-12T11:22:30.552+0800 [INFO] Loading CLI configuration from /Users/zulh/.terraformrc
2021-08-12T11:22:30.553+0800 [INFO] CLI command args: []string{"import", "civo_kubernetes_node_pool.my_pool", "1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad"}
2021-08-12T11:22:30.629+0800 [INFO] Failed to read plugin lock file .terraform/plugins/darwin_amd64/lock.json: open .terraform/plugins/darwin_amd64/lock.json: no such file or directory
2021-08-12T11:22:30.631+0800 [INFO] provider: configuring client automatic mTLS
2021-08-12T11:22:31.284+0800 [INFO] provider.terraform-provider-civo_v99.0.0: configuring server automatic mTLS: timestamp=2021-08-12T11:22:31.283+0800
2021-08-12T11:22:31.358+0800 [INFO] provider: configuring client automatic mTLS
2021-08-12T11:22:31.404+0800 [INFO] provider.terraform-provider-civo_v99.0.0: configuring server automatic mTLS: timestamp=2021-08-12T11:22:31.404+0800
2021-08-12T11:22:31.478+0800 [WARN] ValidateProviderConfig from "provider["registry.terraform.io/civo/civo"]" changed the config value, but that value is unused
civo_kubernetes_node_pool.my_pool: Importing from ID "1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad"...
2021-08-12T11:22:31.479+0800 [INFO] provider.terraform-provider-civo_v99.0.0: 2021/08/12 11:22:31 resourceKubernetesClusterNodePoolImport reg: timestamp=2021-08-12T11:22:31.479+0800 <-- 这一行
2021-08-12T11:22:31.479+0800 [INFO] provider.terraform-provider-civo_v99.0.0: 2021/08/12 11:22:31 resourceKubernetesClusterNodePoolImport ok false: timestamp=2021-08-12T11:22:31.479+0800 <-- 这一行
2021-08-12T11:22:31.479+0800 [INFO] provider.terraform-provider-civo_v99.0.0: 2021/08/12 11:22:31 resourceKubernetesClusterNodePoolImport d.Get(): timestamp=2021-08-12T11:22:31.479+0800 <-- 这一行
│ Error: [ERR] Please provide a region in your import configuration
│
│
问题是,在运行上述tf import
命令之前,我已经在我的Terraform配置文件main.tf中添加了region
(并保存了它)。这是我的main.tf文件:
resource "civo_kubernetes_cluster" "my_cluster" {
name = "my-cluster"
}
resource "civo_kubernetes_node_pool" "my_pool" {
region = "LON1" <-- 这一行
}
为什么我的Terraform插件/提供程序将区域视为空?
据我了解,Terraform在运行导入逻辑之前会先读取配置文件。我错了吗?我是否遗漏了什么?
为了完整起见,我正在使用Terraform v1.0.3,这是我的provider.tf文件...
terraform {
required_providers {
civo = {
source = "civo/civo"
version = "99.0.0"
}
}
}
provider "civo" {
token = "my-api-key-here"
}
...其中99.0.0
是我仅用于测试的版本。我发布这个问题时,此提供程序的最新/生产版本是0.10.9。
英文:
I'm building a Terraform plugin/provider using Go. I have the following in my schema (link):
Importer: &schema.ResourceImporter{
State: resourceKubernetesClusterNodePoolImport,
}
And this is the function (link):
func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
apiClient := m.(*civogo.Client)
clusterID, nodePoolID, err := utils.ResourceCommonParseID(d.Id())
if err != nil {
return nil, err
}
log.Printf("[INFO] retriving the node pool %s", nodePoolID)
resp, err := apiClient.GetKubernetesCluster(clusterID)
if err != nil {
if resp != nil {
return nil, err
}
}
d.Set("cluster_id", resp.ID)
for _, v := range resp.Pools {
if v.ID == nodePoolID {
d.Set("num_target_nodes", v.Count)
d.Set("target_nodes_size", v.Size)
}
}
return []*schema.ResourceData{d}, nil
}
When I added these debug lines at the top of function above, the results (reg
and ok
) were empty and false
:
reg, ok := d.GetOk("region")
log.Printf("resourceKubernetesClusterNodePoolImport reg %+v\n", reg)
log.Println("resourceKubernetesClusterNodePoolImport ok", ok)
log.Println("resourceKubernetesClusterNodePoolImport d.Get()", d.Get("region"))
if !ok {
return nil, fmt.Errorf("[ERR] Please provide a region in your import configuration")
}
Traces:
$ echo $TF_LOG
INFO
$ tf import civo_kubernetes_node_pool.my_pool 1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad
2021-08-12T11:22:30.552+0800 [INFO] Terraform version: 1.0.3
2021-08-12T11:22:30.552+0800 [INFO] Go runtime version: go1.16.4
2021-08-12T11:22:30.552+0800 [INFO] CLI args: []string{"/usr/local/bin/terraform", "import", "civo_kubernetes_node_pool.my_pool", "1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad"}
2021-08-12T11:22:30.552+0800 [INFO] Loading CLI configuration from /Users/zulh/.terraformrc
2021-08-12T11:22:30.553+0800 [INFO] CLI command args: []string{"import", "civo_kubernetes_node_pool.my_pool", "1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad"}
2021-08-12T11:22:30.629+0800 [INFO] Failed to read plugin lock file .terraform/plugins/darwin_amd64/lock.json: open .terraform/plugins/darwin_amd64/lock.json: no such file or directory
2021-08-12T11:22:30.631+0800 [INFO] provider: configuring client automatic mTLS
2021-08-12T11:22:31.284+0800 [INFO] provider.terraform-provider-civo_v99.0.0: configuring server automatic mTLS: timestamp=2021-08-12T11:22:31.283+0800
2021-08-12T11:22:31.358+0800 [INFO] provider: configuring client automatic mTLS
2021-08-12T11:22:31.404+0800 [INFO] provider.terraform-provider-civo_v99.0.0: configuring server automatic mTLS: timestamp=2021-08-12T11:22:31.404+0800
2021-08-12T11:22:31.478+0800 [WARN] ValidateProviderConfig from "provider[\"registry.terraform.io/civo/civo\"]" changed the config value, but that value is unused
civo_kubernetes_node_pool.my_pool: Importing from ID "1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad"...
2021-08-12T11:22:31.479+0800 [INFO] provider.terraform-provider-civo_v99.0.0: 2021/08/12 11:22:31 resourceKubernetesClusterNodePoolImport reg: timestamp=2021-08-12T11:22:31.479+0800 <-- this line
2021-08-12T11:22:31.479+0800 [INFO] provider.terraform-provider-civo_v99.0.0: 2021/08/12 11:22:31 resourceKubernetesClusterNodePoolImport ok false: timestamp=2021-08-12T11:22:31.479+0800 <-- this line
2021-08-12T11:22:31.479+0800 [INFO] provider.terraform-provider-civo_v99.0.0: 2021/08/12 11:22:31 resourceKubernetesClusterNodePoolImport d.Get(): timestamp=2021-08-12T11:22:31.479+0800 <-- this line
╷
│ Error: [ERR] Please provide a region in your import configuration
│
│
╵
The problem is, I have added the region
in my Terraform configuration main.tf file (and saved it) before I run the tf import
command above. Here is my main.tf file:
resource "civo_kubernetes_cluster" "my_cluster" {
name = "my-cluster"
}
resource "civo_kubernetes_node_pool" "my_pool" {
region = "LON1" <-- this line
}
Why my Terraform plugin/provider sees the region as empty?
From my understanding, Terraform will first read the configuration file before running the import logic. Am I wrong? Did I miss something here?
For the sake of completeness, I'm using Terraform v1.0.3 and this is my provider.tf file...
terraform {
required_providers {
civo = {
source = "civo/civo"
version = "99.0.0"
}
}
}
provider "civo" {
token = “my-api-key-here”
}
...where 99.0.0
is the version that I built for my testing only. The latest/prod version for this provider is 0.10.9 when I posted this question.
答案1
得分: 1
Importer.State
函数无法访问现有的配置,它会提供一个空的资源状态和id
- 请参考代码。
作为解决方法,您可以通过下划线(或任何不与id或区域名称中的符号冲突的符号)将region
传递给导入命令,例如:
terraform import civo_kubernetes_node_pool.my_pool <poolid>_<region>
然后在导入函数中处理这个参数:
func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
apiClient := m.(*civogo.Client)
// 从提供的字符串中提取id和region
parts := strings.Split(d.Id(), "_")
if len(parts) != 2 {
return nil, errors.New("要导入一个池,请使用格式{pool_id}_{region}")
}
poolId := parts[0]
region := parts[1]
// 为资源设置新的ID
d.SetId(poolId)
// 设置region
d.Set("region", region)
// 完成导入的其余部分
...
}
英文:
Importer.State
function does not have access to existing config, it is provided an empty resource state with id
- see code.
As a workaround you can allow passing region
to import command through underscore (or any symbol that does not conflict with symbols in ids or region names), like so:
terraform import civo_kubernetes_node_pool.my_pool <poolid>_<region>
And handle this in you importer function:
func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
apiClient := m.(*civogo.Client)
// extract id and region from provided string
parts := strings.Split(d.Id(), "_")
if len(parts) != 2 {
return nil, errors.New("To import a pool, use the format {pool_id}_{region}")
}
poolId := parts[0]
region := parts[1]
// Set new ID for resource
d.SetId(poolId)
// Set region
d.Set("region", region)
// Do the rest of the import
...
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论