回调函数返回terraform提供程序中apply的结果。

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

callback with results of apply in terraform provider

问题

我正在编写一个自定义的 Terraform 提供程序。我需要在调用后端 API 时包装一个“会话”,在进行任何调用之前打开它,然后在所有 Terraform 调用完成后关闭它。

打开会话很简单,我可以在 schema.Provider 的 ConfigureContextFunc 中完成。是否有一种方法可以在应用程序结束时设置一个回调(或其他方式),以便我可以关闭/“完成”会话?我可以想象一些特定于我的资源的方法,但那似乎有些笨拙。在我理想的情况下,如果关闭会话时出现错误,我还可以使应用程序失败。

如果没有一个好的“完成”调用,是否有一种方法可以访问计划,以确定当前调用是否是应用程序所需的最后一次调用?

更新:我以为可以使用 StopContext:

stopCtx, ok := schema.StopContext(ctx)
    ...
	go func(ctx context.Context) {
		// Wait for stop context cancellation
		<-stopCtx.Done()
        ...
    }

然而,这个方法已被弃用,并且似乎只在由外部触发器(如 SIGINT)引起的停止时调用,而不是正常退出(至少我看到的是这样)。

英文:

I'm writing a custom terraform provider. I need to wrap the calls to the backed API in a "session", opening it before any calls are made and then closing it once all the terraform calls have completed.

Opening the session is straightforward, I can do that in the ConfigureContextFunc of the schema.Provider. Is there a way to set up a callback (or something) at the end of the application so I can close/"finalize" the session? I can imagine something specific to my resources, but that seems hacky. In my dream world I'd also be able to fail the apply if the close had an error.

Absent a nice finalize call is there a way to access the plan that I could use to determine that the current call is the last needed for the apply?

Update: I thought I could use a StopContext:

stopCtx, ok := schema.StopContext(ctx)
    ...
	go func(ctx context.Context) {
		// Wait for stop context cancellation
		<-stopCtx.Done()
        ...
    }

However, this is both deprecated and seems to only get called when stopping due to some outside trigger, like SIGINT, and not a regular exit (at least that's what I've been seeing).

答案1

得分: 0

在一番摸索之后,我找到了一个我认为是合理的解决方案,甚至与@Ben Hoyt的评论相匹配。我们可以在main函数中延迟执行和拆除。

func main() {
	var prov *schema.Provider
	defer func() {
		xyz.ProviderTeardown(prov)
	}()
	plugin.Serve(&plugin.ServeOpts{
		ProviderFunc: func() *schema.Provider {
			prov = xyz.Provider()
			return prov
		},
	})
}

我要注意一下,我在关于提供程序创建时不在场的问题上的评论是错误的。提供程序是在提供程序代码的main函数中创建的。在我(站不住脚的)辩解中,我使用了示例脚手架,所以那段代码是预先编写好的。

有一件事让我困惑的是plugin.Serve的文档。

Serve用于提供插件服务。此函数永远不会返回,并且应该是插件的main函数中的最后一个调用的函数。

事实证明,当terraform操作完成并且不再需要插件时,Serve确实会返回并允许我们的延迟函数运行。我确实需要在Serve处于活动状态时跟踪所有调用的成功或失败,以便在ProviderTeardown中了解状态,但它正在工作。

英文:

After a fair amount of floundering I have what I believe to be a reasonable solution, and it even matches @Ben Hoyt's comment. We can defer and teardown in main.


func main() {
	var prov *schema.Provider
	defer func() {
		xyz.PrividerTeardown(prov)
	}()
	plugin.Serve(&plugin.ServeOpts{
		ProviderFunc: func() *schema.Provider {
			prov = xyz.Provider()
			return prov
		},
	})
}

I'll note that my comment on the question about not being around when the provider is made is incorrect. The provider is made in a main function in the provider code. In my (flimsy) defense I used the example scaffolding so that code came pre-written.

One thing that threw me was the docs for plugin.Serve

> Serve serves a plugin. This function never returns and should be the final function called in the main function of the plugin.

It turns out that when the terraform action is done and the plugin is no longer needed, Serve does return and allows our defer to run. I did need to keep track of success or failure of all the calls that were made while Serve was active to know the status in my ProviderTeardown, but it is working.

huangapple
  • 本文由 发表于 2022年7月14日 05:28:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/72972827.html
匿名

发表评论

匿名网友

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

确定