尝试调试 terraform-provider-azurerm,以便我可以为社区做出贡献但是地形计划崩溃了

问题描述

简介

大家好,我正在尝试开始为 terraform-provider-azurerm 做出贡献。我注意到 azurerm_firewall_network_rule_collection 有问题,我已报告它 here。我想我应该以此为契机,看看我是否可以参与并尝试解决我报告的问题!如果我可以调试提供程序并查看代码如何工作,那么我不仅可以学习 go,还可以找出并帮助修复错误/功能增强。
你们可以为我提供的任何帮助并引导我朝着正确的方向前进,我们将不胜感激。我知道你的时间很宝贵,在来寻求帮助之前我已经尽力了。
我尝试执行以下操作的摘要

  • 分叉 terraform-provider-azurerm 存储库。
  • 将分叉的 repo 克隆到我的本地。我在 WSL 中使用 Ubuntu 20.04
  • 运行 vscode 版本 1.54.3
  • 使用 terraform 0.14.9,使用 tfenv 安装和管理不同的版本。
  • 在 vscode 中安装 golang 和相关的 go 工具。我在go version go1.16.2 linux/amd64。使用 linuxbrew 安装 go。
  • 安装gcc5。使用 linuxbrew 进行安装。
  • 安装 delve 调试器。使用 linuxbrew 进行安装。
  • 创建一个非常简单的 terraform main.tf,它只是将一个资源组部署到我的 Azure 订阅
  • 创建一个 .terraformrc 文件(将其设置在位置 /home/rahul/.terraformrc 中)以向提供程序提供 dev_overrides 路径。
  • 修改 main.go(位置 /usr/local/go/src/github.com/terraform-providers/terraform-provider-azurerm/main.go)以使用调试语句。
  • 使用调试代码编译提供程序并创建新的二进制文件
  • 以无头模式将 dlv 附加到此二进制文件
  • 使用上一步中的数据将其设置在变量 TF_REATTACH_PROVIDERS 中
  • 运行 terraform 计划 - 希望计划成功运行。
  • 关闭调试模式并编译提供程序,然后运行 ​​terraform plan。
  • 使用本地提供程序成功运行计划。

问题

  • 计划因

    而崩溃
    terraform crashed! This is always indicative of a bug within terraform.
    A crash log has been placed at "crash.log" relative to your current
    working directory. It would be immensely helpful if you Could please
    report the crash with terraform[1] so that we can fix this.
    
  • 来自日志输出内容

  2021/04/05 06:09:50 [INFO] terraform version: 0.14.9  
  2021/04/05 06:09:50 [INFO] Go runtime version: go1.15.6
  2021/04/05 06:09:50 [INFO] CLI args: []string{"/home/rahul/.tfenv/versions/0.14.9/terraform","plan"}
  2021/04/05 06:09:50 [DEBUG] Attempting to open CLI config file: /home/rahul/.terraformrc
  2021/04/05 06:09:50 Loading CLI configuration from /home/rahul/.terraformrc
  2021/04/05 06:09:50 [DEBUG] Explicit provider installation configuration is set
  2021/04/05 06:09:50 [TRACE] Selected provider installation method cliconfig.ProviderInstallationDirect with includes [] and     excludes []
  2021/04/05 06:09:50 [INFO] CLI command args: []string{"plan"}
  2021/04/05 06:09:50 [TRACE] Meta.Backend: built configuration for "local" backend with hash value 666019178
  2021/04/05 06:09:50 [TRACE] Preserving existing state lineage "8773571c-7605-2553-b418-08cbb37374a4"
  2021/04/05 06:09:50 [TRACE] Preserving existing state lineage "8773571c-7605-2553-b418-08cbb37374a4"
  2021/04/05 06:09:50 [TRACE] Meta.Backend: working directory was prevIoUsly initialized for "local" backend
  2021/04/05 06:09:50 [TRACE] Meta.Backend: using already-initialized,unchanged "local" backend configuration
  2021/04/05 06:09:50 [TRACE] Meta.Backend: instantiated backend of type *local.Local
  2021/04/05 06:09:50 [TRACE] providercache.fillMetaCache: scanning directory .terraform/providers
  2021/04/05 06:09:50 [TRACE] getproviders.SearchLocalDirectory: .terraform/providers is a symlink to .terraform/providers
  2021/04/05 06:09:50 [TRACE] getproviders.SearchLocalDirectory: found registry.terraform.io/hashicorp/azurerm v2.53.0 for    linux_amd64 at .terraform/providers/registry.terraform.io/hashicorp/azurerm/2.53.0/linux_amd64
  2021/04/05 06:09:50 [TRACE] providercache.fillMetaCache: including .terraform/providers/registry.terraform.io/hashicorp/    azurerm/2.53.0/linux_amd64 as a candidate package for registry.terraform.io/hashicorp/azurerm 2.53.0
  2021/04/05 06:09:50 [DEBUG] Provider registry.terraform.io/hashicorp/azurerm is overridden to load from /usr/local/go/bin
  2021/04/05 06:09:50 [DEBUG] checking for provisioner in "."
  2021/04/05 06:09:50 [DEBUG] checking for provisioner in "/home/rahul/.tfenv/versions/0.14.9"
  2021/04/05 06:09:50 [INFO] Failed to read plugin lock file .terraform/plugins/linux_amd64/lock.json: open .terraform/   plugins/linux_amd64/lock.json: no such file or directory
  2021/04/05 06:09:50 [TRACE] Meta.Backend: backend *local.Local supports operations
  2021/04/05 06:09:50 [INFO] backend/local: starting Plan operation
  2021/04/05 06:09:50 [TRACE] backend/local: requesting state manager for workspace "default"
  2021/04/05 06:09:50 [TRACE] backend/local: state manager for workspace "default" will:
  - read initial snapshot from terraform.tfstate
  - write new snapshots to terraform.tfstate
  - create any backup at terraform.tfstate.backup
  2021/04/05 06:09:50 [TRACE] backend/local: requesting state lock for workspace "default"
  2021/04/05 06:09:50 [TRACE] statemgr.Filesystem: preparing to manage state snapshots at terraform.tfstate
  2021/04/05 06:09:50 [TRACE] statemgr.Filesystem: no prevIoUsly-stored snapshot exists
  2021/04/05 06:09:50 [TRACE] statemgr.Filesystem: locking terraform.tfstate using fcntl flock
  2021/04/05 06:09:50 [TRACE] statemgr.Filesystem: writing lock Metadata to .terraform.tfstate.lock.info
  2021/04/05 06:09:50 [TRACE] backend/local: reading remote state for workspace "default"
  2021/04/05 06:09:50 [TRACE] statemgr.Filesystem: reading latest snapshot from terraform.tfstate
  2021/04/05 06:09:50 [TRACE] statemgr.Filesystem: snapshot file has nil snapshot,but that's okay
  2021/04/05 06:09:50 [TRACE] statemgr.Filesystem: read nil snapshot
  2021/04/05 06:09:50 [TRACE] backend/local: retrieving local state snapshot for workspace "default"
  2021/04/05 06:09:50 [TRACE] backend/local: building context for current working directory
  2021/04/05 06:09:50 [TRACE] terraform.NewContext: starting
  2021/04/05 06:09:50 [TRACE] terraform.NewContext: loading provider schemas
  2021/04/05 06:09:50 [TRACE] LoadSchemas: retrieving schema for provider type "registry.terraform.io/hashicorp/azurerm"
  panic: runtime error: invalid memory address or nil pointer dereference
  [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x20f82d2]

  goroutine 52 [running]:
  github.com/hashicorp/terraform/plugin.(*GRPCProviderPlugin).Client(0xc00054ef60,0xc00054e560,0xc0003321e0,0x7f73af739388,0xc00094a180,0x0,0xc000817a6c)
      <autogenerated>:1 +0x32
  github.com/hashicorp/go-plugin.(*RPcclient).dispense(0xc00073ce40,0x289bfc5,0x8,0x29cd9d8,0xc0003a6b30)
      /go/pkg/mod/github.com/hashicorp/go-plugin@v1.3.0/rpc_client.go:159 +0x254
  github.com/hashicorp/terraform/command.unmanagedProviderFactory.func1(0x24b0360,0xc000575950,0xc0003a6c08,0xc00000b270)
      /home/circleci/project/project/command/Meta_providers.go:448 +0x248
  github.com/hashicorp/terraform/terraform.(*basicComponentFactory).ResourceProvider(0xc00017d4b0,0xc000578d8a,0x7,0xc000578d80,0x9,0x28bc2ba,0x15,0x2892906,0x1,...)
      /home/circleci/project/project/terraform/context_components.go:55 +0x351
  github.com/hashicorp/terraform/terraform.loadProviderSchemas.func1(0xc000578d8a,0x15)
      /home/circleci/project/project/terraform/schemas.go:103 +0x36e
  github.com/hashicorp/terraform/terraform.loadProviderSchemas(0xc000731ec0,0xc0002c11e0,0x2ce93a0,0xc00017d4b0,0xc0000f2080,0x3dcafe0,0xc0000f2050)
      /home/circleci/project/project/terraform/schemas.go:174 +0x250
  github.com/hashicorp/terraform/terraform.LoadSchemas(0xc0002c11e0,0x2,0x7f73afb6b400)
      /home/circleci/project/project/terraform/schemas.go:84 +0xc6
  github.com/hashicorp/terraform/terraform.NewContext(0xc0003a79d0,0xc00098b900,0x1)
      /home/circleci/project/project/terraform/context.go:205 +0x2ea
  github.com/hashicorp/terraform/backend/local.(*Local).contextDirect(0xc00015ef70,0xc0008e2700,0xc000731d10,0xc000421120,...)
      /home/circleci/project/project/backend/local/backend_local.go:178 +0x2ff
  github.com/hashicorp/terraform/backend/local.(*Local).context(0xc00015ef70,0x0)
      /home/circleci/project/project/backend/local/backend_local.go:111 +0xf18
  github.com/hashicorp/terraform/backend/local.(*Local).opPlan(0xc00015ef70,0x2ce83a0,0xc00073cb40,0xc00073cb80,0xc00073cb00)
      /home/circleci/project/project/backend/local/backend_plan.go:70 +0x2cb
  github.com/hashicorp/terraform/backend/local.(*Local).Operation.func1(0xc00017d130,0xc00017d140,0xc00017d150,0xc00015ef70,0xc00017d120,...)
      /home/circleci/project/project/backend/local/backend.go:340 +0xe8
  created by github.com/hashicorp/terraform/backend/local.(*Local).Operation
      /home/circleci/project/project/backend/local/backend.go:334 +0x36d

包含源代码的详细步骤。

我已按照 Terraform Docs - Debugger based debugging

中记录的步骤进行操作
  • Go 安装路径 => /usr/local/go

  • terraform-provider-azurerm 克隆到 => /usr/local/go/src/github.com/terraform-providers

  • terraform-provider-azurerm 源路径 => /usr/local/go/src/github.com/terraform-providers/terraform-provider-azurerm

  • terraform main.tf 源路径 => ~/Code/terraform

  • 我的地形代码

      locals {
      location      = "australiaeast"
      resourcegroup = "rg-azfw"
    }
    
    terraform {
      backend "local" {}
    }
    
    terraform {
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "2.53.0"
        }
      }
    }
    
    provider "azurerm" {
      tenant_id                  = "xxxxxx-xxxxx-xxxxx-xxxxx-xxxx"
      skip_provider_registration = true
      features {}
    }
    
    resource "azurerm_resource_group" "resourcegroup" {
      name     = local.resourcegroup
      lo
    
  • 我的 .terraformrc

      provider_installation {
    
      # Use /home/developer/go/bin as an overridden package directory
      # for the hashicorp/azurerm provider. This disables the version and checksum
      # verifications for this provider and forces terraform to look for the
      # azurerm provider plugin in the given directory.
      dev_overrides {
        "registry.terraform.io/hashicorp/azurerm" = "/usr/local/go/bin"
      }
    
      # For all other providers,install them directly from their origin provider
      # registries as normal. If you omit this,terraform will _only_ use
      # the dev_overrides block,and so no other providers will be available.
       direct {}
      }
    
  • 修改terraform-provider-azurerm 中的 main.go 文件,以便可以在调试器模式下启动提供程序二进制文件。现在主要功能看起来像:

    func main() {
        // remove date and time stamp from log output as the plugin SDK already adds its own
        log.SetFlags(log.Flags() &^ (log.Ldate | log.Ltime))
        var debugMode bool
    
        flag.BoolVar(&debugMode,"debug",true,"set to true to run the provider with support for debuggers like delve")
        flag.Parse()
    
        opts := &plugin.ServeOpts{ProviderFunc: azurerm.Provider}
    
        if debugMode {
            // Todo: update this string with the full name of your provider as used in your configs
            err := plugin.Debug(context.Background(),"registry.terraform.io/hashicorp/azurerm",opts)
            if err != nil {
                log.Fatal(err.Error())
            }
            return
        }
    
        plugin.Serve(opts)
        // plugin.Serve(&plugin.ServeOpts{
        //  ProviderFunc: azurerm.Provider,// })
    }
    
  • vscode 调试器启动配置如下所示:

        {
            // Use IntelliSense to learn about possible attributes.
            // Hover to view descriptions of existing attributes.
            // For more information,visit: https://go.microsoft.com/fwlink/?linkid=830387
            "version": "0.2.0","configurations": [
                {
                    "name": "Connect to server","type": "go","request": "attach","mode": "remote","remotePath": "${workspaceFolder}","port": 36283,"host": "127.0.0.1","apiVersion": 1
                }
            ]
        }
    
  • 运行 make build 来构建二进制文件。它将二进制文件复制到 $GOPATH/bin/ 位置。

  • 使用命令 dlv exec --listen=127.0.0.1:36283 --api-version=1 --headless $GOPATH/bin/terraform-provider-azurerm -- --debug

    启动 delv 无头调试器
    • --listen=127.0.0.1:36283 是我通过谷歌搜索并发现的一个附加参数 - terraform 文档中未提及。这有助于我在每次启动调试器时不更改调试端口。
  • 产生如下输出

      API server listening at: 127.0.0.1:36283
      {"@level":"debug","@message":"plugin address","@timestamp":"2021-04-05T06:08:38.863169+10:00","address":"/tmp/  plugin594405865","network":"unix"}
      Provider server started; to attach terraform,set TF_REATTACH_PROVIDERS to the following:
      {"registry.terraform.io/hashicorp/azurerm":{"Protocol":"netrpc","Pid":16362,"Test":true,"Addr":{"Network":"unix","String":"/    tmp/plugin594405865"}}}
    
  • 设置 TF_REATTACH_PROVIDERS

        export TF_REATTACH_PROVIDERS='{"registry.terraform.io/hashicorp/azurerm":{"Protocol":"netrpc","String":"/tmp/plugin594405865"}}}'
    
  • 在 tf 源代码所在的文件夹中运行 terraform plan。一切顺利。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...