自定义Terraform-Providers(Terraform Plugin Framework)-04

举报
kaliarch 发表于 2022/06/11 12:30:00 2022/06/11
【摘要】 一 前言Terraform插件框架是开发Terraform插件的一种新方法。它具有Terraform插件SDKv2所缺少的特性,包括:确定是否在配置、状态或计划中设置了值。确定值是null、未知还是空值。具有结构化类型,如对象。本机使用嵌套属性。在本教程中,您将使用Terraform插件框架,为一个虚构的咖啡店应用程序(HashiCups)的提供程序添加创建和读取功能。首先,您将回顾pro...

一 前言

Terraform插件框架是开发Terraform插件的一种新方法。它具有Terraform插件SDKv2所缺少的特性,包括:

  • 确定是否在配置、状态或计划中设置了值。
  • 确定值是null、未知还是空值。
  • 具有结构化类型,如对象。
  • 本机使用嵌套属性。

在本教程中,您将使用Terraform插件框架,为一个虚构的咖啡店应用程序(HashiCups)的提供程序添加创建和读取功能。首先,您将回顾provider和resource schema,以了解provider如何使用插件框架将Go结构映射到schema属性。然后,在自己实现资源之前,您将探索与创建和读取资源相关联的步骤。最后,您将测试提供程序。

HashiCups API有不受保护的端点,允许您列出特定咖啡的所有咖啡和成分。经过身份验证后,可以创建、读取、更新和删除(CRUD)订单。HashiCups提供程序通过GoLang客户机库与HashiCups REST API接口。这允许您通过Terraform管理HashiCups订单。

这个框架是实验性的。不要在生产或关键环境中使用。在Terraform插件框架Github存储库中向开发团队提交任何问题。有关反馈和讨论,请访问插件SDK讨论论坛。

二 预置条件

对于本教程,您将需要:

  • 安装并配置Go1.16+。的
  • Terraform V1.0.3+已在本地安装。
  • Docker和Docker组合在本地运行HashiCups实例。
  • 安装了jq。

三 配置开发环境

git clone --branch boilerplate https://github.com/hashicorp/terraform-provider-hashicups-pf
cd terraform-provider-hashicups-pf

四 启动项目

cd docker_compose
docker-compose up -d
curl localhost:19090/health

五 创建用户

$ curl -X POST localhost:19090/signup -d '{"username":"education", "password":"test123"}'
{"UserID":1,"Username":"education","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTQ4MjU4ODYsInVzZXJfaWQiOjEsInVzZXJuYW1lIjoiZWR1Y2F0aW9uIn0.DD1LxrJJL05wKJ56f8FSm-lerdBvyCYaUZCnJM4m4AY"}

$ export HASHICUPS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NTQ4MjU4ODYsInVzZXJfaWQiOjEsInVzZXJuYW1lIjoiZWR1Y2F0aW9uIn0.DD1LxrJJL05wKJ56f8FSm-lerdBvyCYaUZCnJM4m4AY

六 开发HashiCups provider

main.go文件

package main

import (
    "context"
    "github.com/hashicorp/terraform-plugin-framework/tfsdk"
    "terraform-provider-hashicups/hashicups"
)

func main() {
    tfsdk.Serve(context.Background(), hashicups.New, tfsdk.ServeOpts{
        Name: "hashicups",
    })
}

打开hashicups/provider.go。
首先,提供程序调用新函数来调用提供程序的实例。请注意,该文件还定义了一个带有客户端的提供程序结构。像SDKv2一样,Terraform提供程序应该与API客户机接口,而不是直接向API提交请求。

package hashicups

import (
    "context"
    "os"

    "github.com/hashicorp-demoapp/hashicups-client-go"
    "github.com/hashicorp/terraform-plugin-framework/diag"
    "github.com/hashicorp/terraform-plugin-framework/tfsdk"
    "github.com/hashicorp/terraform-plugin-framework/types"
)

var stderr = os.Stderr

func New() tfsdk.Provider {
    return &provider{}
}

type provider struct {
    configured bool
    client     *hashicups.Client
}

接下来,提供程序定义一个模式,Terraform将使用该模式来配置HashiCups API客户机。providerData结构将这些模式属性映射到易于访问的值。

hashicups/provider.go

// GetSchema
func (p *provider) GetSchema(_ context.Context) (tfsdk.Schema, diag.Diagnostics) {
    return tfsdk.Schema{
        Attributes: map[string]tfsdk.Attribute{
            "host": {
                Type:     types.StringType,
                Optional: true,
                Computed: true,
            },
            "username": {
                Type:     types.StringType,
                Optional: true,
                Computed: true,
            },
            "password": {
                Type:      types.StringType,
                Optional:  true,
                Computed:  true,
                Sensitive: true,
            },
        },
    }, nil
}

// Provider schema struct
type providerData struct {
    Username types.String `tfsdk:"username"`
    Host     types.String `tfsdk:"host"`
    Password types.String `tfsdk:"password"`
}

6.1 定义资源和数据源

GetResources和GetDataSources函数定义提供者的资源和数据源。HashiCups提供程序的这个样板版本有一个名为HashiCups\u order的资源,不定义任何数据源。

// GetResources - Defines provider resources
func (p *provider) GetResources(_ context.Context) (map[string]tfsdk.ResourceType, diag.Diagnostics) {
    return map[string]tfsdk.ResourceType{
        "hashicups_order": resourceOrderType{},
    }, nil
}

// GetDataSources - Defines provider data sources
func (p *provider) GetDataSources(_ context.Context) (map[string]tfsdk.DataSourceType, diag.Diagnostics) {
    return map[string]tfsdk.DataSourceType{}, nil
}

6.2 查看Review HashiCups models

package hashicups

import (
	"github.com/hashicorp/terraform-plugin-framework/types"
)

// Order -
type Order struct {
	ID          types.String `tfsdk:"id"`
	Items       []OrderItem  `tfsdk:"items"`
	LastUpdated types.String `tfsdk:"last_updated"`
}

// OrderItem -
type OrderItem struct {
	Coffee   Coffee `tfsdk:"coffee"`
	Quantity int    `tfsdk:"quantity"`
}

// Coffee -
// This Coffee struct is for Order.Items[].Coffee which does not have an
// ingredients field in the schema defined by plugin framework. Since the
// resource schema must match the struct exactly (extra field will return an
// error). This struct has Ingredients commented out.
type Coffee struct {
	ID          int          `tfsdk:"id"`
	Name        types.String `tfsdk:"name"`
	Teaser      types.String `tfsdk:"teaser"`
	Description types.String `tfsdk:"description"`
	Price       types.Number `tfsdk:"price"`
	Image       types.String `tfsdk:"image"`
	// Ingredients []Ingredient   `tfsdk:"ingredients"`
}

// Ingredient -
// type Ingredient struct {
// 	ID       int    `tfsdk:"ingredient_id"`
// 	Name     string `tfsdk:"name"`
// 	Quantity int    `tfsdk:"quantity"`
// 	Unit     string `tfsdk:"unit"`
// }

6.3 实现具体方法

6.2.1 创建方法

  • 检查是否配置了提供程序和API客户端。如果不是,提供程序将以错误响应。
  • 从计划中检索值。该函数将尝试从计划中检索值,并将其转换为Order结构(在models.go中定义)。
  • 从计划值生成API请求正文。该函数循环遍历每个计划项,并将其映射到HashiCups.OrderItem。这就是API客户机创建新订单所需要的。
  • 创建新订单。该函数调用API客户端的CreateOrder方法。
  • 将响应正文映射到资源架构属性。函数创建订单后,它将HashiCups.order响应映射到[]OrderItem,这样提供者就可以更新Terraform状态。
  • 将状态设置为新顺序。

6.2.2 读取方法

  • 获取当前状态。如果不能,则提供程序将以错误进行响应。
  • 从状态检索订单ID。
  • 获取订单的信息。该函数使用订单ID调用API客户机的GetOrder方法。
  • 将响应正文映射到资源架构属性。函数检索订单后,它将HashiCups.order响应映射到[]OrderItem,这样提供者就可以更新Terraform状态。
  • 将状态设置为新顺序。

七 执行构建

go env GOBIN

创建文件

provider_installation {

  dev_overrides {
      "hashicorp.com/edu/hashicups-pf" = "<PATH>"
  }

  # 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 {}
}

go mod tidy
go install

参考链接

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。