使用Golang开发自定义Terraform Provider指南

使用Golang开发自定义Terraform Provider指南 我尝试基于以下仓库使用Go工具链为ServiceNow构建自定义Terraform提供程序: GitHub - tylerhatton/terraform-provider-servicenow: 一个用于管理ServiceNow资源的Terraform提供程序。。 我根据文档构建插件 >> 编写自定义Terraform提供程序

但是,当我使用go工具链构建插件时,执行我刚刚创建的二进制文件会收到错误。

./terraform-provider-example
./terraform-provider-example: line 1: syntax error near unexpected token `newline'
./terraform-provider-example: line 1: `!'

我使用的Go版本是 go1.21.10 (Red Hat 1.21.10-1.el9_4) linux/amd64

上一次,大约一年前我构建插件时,没有遇到这样的错误。唯一的区别是,之前我使用Docker(不记得当时的具体版本)进行编译,而现在我使用Podman。 能否请求支持并指导我应该如何做才能消除这个问题?


更多关于使用Golang开发自定义Terraform Provider指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于使用Golang开发自定义Terraform Provider指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


根据错误信息,这看起来是二进制文件构建不正确导致的。问题可能出现在构建过程或环境配置上。以下是具体排查步骤和解决方案:

1. 检查构建命令和文件完整性

首先验证构建命令是否正确:

// 检查当前目录结构
ls -la

// 正确的构建命令
go build -o terraform-provider-servicenow

// 或者指定完整路径
go build -o terraform-provider-servicenow_v1.0.0

2. 验证二进制文件类型

# 检查文件类型
file terraform-provider-example

# 期望输出应该是:
# terraform-provider-example: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

# 如果是文本文件,会显示类似:
# terraform-provider-example: ASCII text

3. 完整的构建和安装流程

# 清理之前的构建
rm -f terraform-provider-*

# 设置正确的模块名称
export GO111MODULE=on

# 构建插件(假设在项目根目录)
go build -o terraform-provider-servicenow

# 验证构建
./terraform-provider-servicenow

4. 如果问题仍然存在,检查go.mod文件

确保go.mod文件正确配置:

module github.com/yourusername/terraform-provider-servicenow

go 1.21

require (
    github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0
    // 其他依赖...
)

5. 使用标准Terraform Provider项目结构

参考官方模板创建正确的项目结构:

# 创建新的provider项目
mkdir -p terraform-provider-servicenow
cd terraform-provider-servicenow

# 初始化Go模块
go mod init terraform-provider-servicenow

# 添加Terraform SDK依赖
go get github.com/hashicorp/terraform-plugin-sdk/v2

6. 最小化复现代码

创建一个简单的provider测试文件:

package main

import (
    "context"
    "fmt"
    
    "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
    "github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
)

func main() {
    plugin.Serve(&plugin.ServeOpts{
        ProviderFunc: func() *schema.Provider {
            return &schema.Provider{
                Schema: map[string]*schema.Schema{},
                ResourcesMap: map[string]*schema.Resource{},
                DataSourcesMap: map[string]*schema.Resource{},
            }
        },
    })
}

7. 使用正确的构建标志

# 使用静态链接构建
CGO_ENABLED=0 go build -a -ldflags '-extldflags "-static"' -o terraform-provider-servicenow

# 或者使用标准构建
go build -trimpath -o terraform-provider-servicenow

8. 检查Podman环境问题

如果使用Podman,确保构建环境正确:

# 使用Podman构建
podman run --rm -v $(pwd):/app -w /app golang:1.21 go build -o terraform-provider-servicenow

# 或者使用Docker构建对比
docker run --rm -v $(pwd):/app -w /app golang:1.21 go build -o terraform-provider-servicenow

9. 验证构建后的插件

构建成功后,应该能正常输出Terraform provider信息:

./terraform-provider-servicenow
# 期望输出类似:
# This binary is a plugin. These are not meant to be executed directly.
# Please execute the program that consumes these plugins, which will
# load any plugins automatically

如果仍然遇到!字符错误,很可能是构建过程中文件被截断或损坏。检查磁盘空间、文件权限,并确保构建过程没有中断。

回到顶部