为什么 ‘terraform import’ 没有读取我的配置文件?

huangapple go评论106阅读模式
英文:

Why 'terraform import' did not read my configuration?

问题

我正在使用Go构建一个Terraform插件/提供程序。我在我的模式中有以下内容(链接):

  1. Importer: &schema.ResourceImporter{
  2. State: resourceKubernetesClusterNodePoolImport,
  3. }

这是函数的代码(链接):

  1. func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
  2. apiClient := m.(*civogo.Client)
  3. clusterID, nodePoolID, err := utils.ResourceCommonParseID(d.Id())
  4. if err != nil {
  5. return nil, err
  6. }
  7. log.Printf("[INFO] retriving the node pool %s", nodePoolID)
  8. resp, err := apiClient.GetKubernetesCluster(clusterID)
  9. if err != nil {
  10. if resp != nil {
  11. return nil, err
  12. }
  13. }
  14. d.Set("cluster_id", resp.ID)
  15. for _, v := range resp.Pools {
  16. if v.ID == nodePoolID {
  17. d.Set("num_target_nodes", v.Count)
  18. d.Set("target_nodes_size", v.Size)
  19. }
  20. }
  21. return []*schema.ResourceData{d}, nil
  22. }

当我在上面的函数顶部添加了这些调试行时,结果(regok)为空且为false

  1. reg, ok := d.GetOk("region")
  2. log.Printf("resourceKubernetesClusterNodePoolImport reg %+v\n", reg)
  3. log.Println("resourceKubernetesClusterNodePoolImport ok", ok)
  4. log.Println("resourceKubernetesClusterNodePoolImport d.Get()", d.Get("region"))
  5. if !ok {
  6. return nil, fmt.Errorf("[ERR] Please provide a region in your import configuration")
  7. }

跟踪信息如下:

  1. $ echo $TF_LOG
  2. INFO
  3. $ tf import civo_kubernetes_node_pool.my_pool 1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad
  4. 2021-08-12T11:22:30.552+0800 [INFO] Terraform version: 1.0.3
  5. 2021-08-12T11:22:30.552+0800 [INFO] Go runtime version: go1.16.4
  6. 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"}
  7. 2021-08-12T11:22:30.552+0800 [INFO] Loading CLI configuration from /Users/zulh/.terraformrc
  8. 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"}
  9. 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
  10. 2021-08-12T11:22:30.631+0800 [INFO] provider: configuring client automatic mTLS
  11. 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
  12. 2021-08-12T11:22:31.358+0800 [INFO] provider: configuring client automatic mTLS
  13. 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
  14. 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
  15. civo_kubernetes_node_pool.my_pool: Importing from ID "1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad"...
  16. 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 <-- 这一行
  17. 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 <-- 这一行
  18. 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 <-- 这一行
  19. Error: [ERR] Please provide a region in your import configuration

问题是,在运行上述tf import命令之前,我已经在我的Terraform配置文件main.tf中添加了region(并保存了它)。这是我的main.tf文件:

  1. resource "civo_kubernetes_cluster" "my_cluster" {
  2. name = "my-cluster"
  3. }
  4. resource "civo_kubernetes_node_pool" "my_pool" {
  5. region = "LON1" <-- 这一行
  6. }

为什么我的Terraform插件/提供程序将区域视为空?

据我了解,Terraform在运行导入逻辑之前会先读取配置文件。我错了吗?我是否遗漏了什么?


为了完整起见,我正在使用Terraform v1.0.3,这是我的provider.tf文件...

  1. terraform {
  2. required_providers {
  3. civo = {
  4. source = "civo/civo"
  5. version = "99.0.0"
  6. }
  7. }
  8. }
  9. provider "civo" {
  10. token = "my-api-key-here"
  11. }

...其中99.0.0是我仅用于测试的版本。我发布这个问题时,此提供程序的最新/生产版本是0.10.9

英文:

I'm building a Terraform plugin/provider using Go. I have the following in my schema (link):

  1. Importer: &amp;schema.ResourceImporter{
  2. State: resourceKubernetesClusterNodePoolImport,
  3. }

And this is the function (link):

  1. func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
  2. apiClient := m.(*civogo.Client)
  3. clusterID, nodePoolID, err := utils.ResourceCommonParseID(d.Id())
  4. if err != nil {
  5. return nil, err
  6. }
  7. log.Printf(&quot;[INFO] retriving the node pool %s&quot;, nodePoolID)
  8. resp, err := apiClient.GetKubernetesCluster(clusterID)
  9. if err != nil {
  10. if resp != nil {
  11. return nil, err
  12. }
  13. }
  14. d.Set(&quot;cluster_id&quot;, resp.ID)
  15. for _, v := range resp.Pools {
  16. if v.ID == nodePoolID {
  17. d.Set(&quot;num_target_nodes&quot;, v.Count)
  18. d.Set(&quot;target_nodes_size&quot;, v.Size)
  19. }
  20. }
  21. return []*schema.ResourceData{d}, nil
  22. }

When I added these debug lines at the top of function above, the results (reg and ok) were empty and false:

  1. reg, ok := d.GetOk(&quot;region&quot;)
  2. log.Printf(&quot;resourceKubernetesClusterNodePoolImport reg %+v\n&quot;, reg)
  3. log.Println(&quot;resourceKubernetesClusterNodePoolImport ok&quot;, ok)
  4. log.Println(&quot;resourceKubernetesClusterNodePoolImport d.Get()&quot;, d.Get(&quot;region&quot;))
  5. if !ok {
  6. return nil, fmt.Errorf(&quot;[ERR] Please provide a region in your import configuration&quot;)
  7. }

Traces:

  1. $ echo $TF_LOG
  2. INFO
  3. $ tf import civo_kubernetes_node_pool.my_pool 1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad
  4. 2021-08-12T11:22:30.552+0800 [INFO] Terraform version: 1.0.3
  5. 2021-08-12T11:22:30.552+0800 [INFO] Go runtime version: go1.16.4
  6. 2021-08-12T11:22:30.552+0800 [INFO] CLI args: []string{&quot;/usr/local/bin/terraform&quot;, &quot;import&quot;, &quot;civo_kubernetes_node_pool.my_pool&quot;, &quot;1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad&quot;}
  7. 2021-08-12T11:22:30.552+0800 [INFO] Loading CLI configuration from /Users/zulh/.terraformrc
  8. 2021-08-12T11:22:30.553+0800 [INFO] CLI command args: []string{&quot;import&quot;, &quot;civo_kubernetes_node_pool.my_pool&quot;, &quot;1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad&quot;}
  9. 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
  10. 2021-08-12T11:22:30.631+0800 [INFO] provider: configuring client automatic mTLS
  11. 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
  12. 2021-08-12T11:22:31.358+0800 [INFO] provider: configuring client automatic mTLS
  13. 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
  14. 2021-08-12T11:22:31.478+0800 [WARN] ValidateProviderConfig from &quot;provider[\&quot;registry.terraform.io/civo/civo\&quot;]&quot; changed the config value, but that value is unused
  15. civo_kubernetes_node_pool.my_pool: Importing from ID &quot;1b272dc1-836c-4ea7-8f20-4569f20ddbdd:d0c22622-54b3-41c2-9eae-24591737d5ad&quot;...
  16. 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 &lt;-- this line
  17. 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 &lt;-- this line
  18. 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 &lt;-- this line
  19. 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:

  1. resource &quot;civo_kubernetes_cluster&quot; &quot;my_cluster&quot; {
  2. name = &quot;my-cluster&quot;
  3. }
  4. resource &quot;civo_kubernetes_node_pool&quot; &quot;my_pool&quot; {
  5. region = &quot;LON1&quot; &lt;-- this line
  6. }

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...

  1. terraform {
  2. required_providers {
  3. civo = {
  4. source = &quot;civo/civo&quot;
  5. version = &quot;99.0.0&quot;
  6. }
  7. }
  8. }
  9. provider &quot;civo&quot; {
  10. token = my-api-key-here
  11. }

...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传递给导入命令,例如:

  1. terraform import civo_kubernetes_node_pool.my_pool <poolid>_<region>

然后在导入函数中处理这个参数:

  1. func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
  2. apiClient := m.(*civogo.Client)
  3. // 从提供的字符串中提取id和region
  4. parts := strings.Split(d.Id(), "_")
  5. if len(parts) != 2 {
  6. return nil, errors.New("要导入一个池,请使用格式{pool_id}_{region}")
  7. }
  8. poolId := parts[0]
  9. region := parts[1]
  10. // 为资源设置新的ID
  11. d.SetId(poolId)
  12. // 设置region
  13. d.Set("region", region)
  14. // 完成导入的其余部分
  15. ...
  16. }
英文:

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:

  1. terraform import civo_kubernetes_node_pool.my_pool &lt;poolid&gt;_&lt;region&gt;

And handle this in you importer function:

  1. func resourceKubernetesClusterNodePoolImport(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
  2. apiClient := m.(*civogo.Client)
  3. // extract id and region from provided string
  4. parts := strings.Split(d.Id(), &quot;_&quot;)
  5. if len(parts) != 2 {
  6. return nil, errors.New(&quot;To import a pool, use the format {pool_id}_{region}&quot;)
  7. }
  8. poolId := parts[0]
  9. region := parts[1]
  10. // Set new ID for resource
  11. d.SetId(poolId)
  12. // Set region
  13. d.Set(&quot;region&quot;, region)
  14. // Do the rest of the import
  15. ...
  16. }

huangapple
  • 本文由 发表于 2021年8月12日 12:17:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/68751548.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定