添加扩展功能

功能用于定义 Azure Developer CLI (azd) 扩展可执行的操作,从添加自定义命令到挂接到部署生命周期。 本文介绍如何为创建示例扩展快速入门中的 Contoso 资源标记器示例扩展添加功能。 可以将相同的模式应用于任何扩展。

每个功能都需要两件事:capabilities数组中的条目,以及扩展代码中的相应实现。

Note

azd 扩展框架现已正式可用。 单个扩展或功能可能具有自己的预览状态。 有关正式发布的详细信息,请参阅正式发布:Azure 开发人员 CLI (azd) 扩展框架

可用功能

azd 扩展可以声明以下功能:

  • custom-commands:在您的扩展命名空间下,向 azd 添加新命令和命令组。 例如,示例扩展添加 azd tagger show。 使用此功能公开用户直接从命令行运行的任务。
  • lifecycle-events:订阅 azd 在运行时引发的事件,例如 preprovisionpostprovisionpostdeploy。 扩展在这些点运行自定义逻辑,而无需用户直接调用它。 例如,示例扩展会在创建任何资源之前检查 preprovision 上是否具有所需的标记。
  • service-target-provider:注册新的部署目标,因此 azd 知道如何将服务打包并部署到它不支持的主机。 服务目标映射到 azure.yaml 中的 host 值。 例如,可以添加将服务部署到第三方平台或内部托管环境的提供程序。
  • framework-service-provider:注册对语言或框架的支持,因此 azd 知道如何还原、生成和打包该项目类型。 这对应于 azure.yaml 中的 language 值。 例如,可以添加对默认无法识别的语言 azd 的生成支持。
  • provisioning-provider:替代 azdazd provisionazd up 期间预配基础设施的方式。 你的扩展自行定义执行逻辑,而非使用内置的 Bicep 或 Terraform 流程。 例如,可以集成不同的基础结构即代码工具或自定义部署 API。
  • validation-provider:向 azd 验证管道提供检查项,这些检查项可针对项目或环境运行。 例如,可以在部署继续进行之前验证命名约定、所需的标记或安全设置是否已到位。
  • mcp-server:将扩展的功能公开为模型上下文协议(MCP)工具,AI 代理(如 GitHub Copilot)可以发现和调用。 例如,示例扩展可以公开工具 suggest_tags 。 有关详细信息,请参阅 将 MCP 服务器添加到扩展
  • metadata:提供更丰富的命令和配置元数据,供 azd 用于描述你的扩展,例如详细的命令说明和配置提示,这些内容会显示在帮助输出和 IntelliSense 中。

本文重点介绍两种最常见的功能:自定义命令和生命周期事件。 对于 mcp-server 功能,请参阅将 MCP 服务器添加到扩展中。 有关提供程序功能的完整详细信息,请参阅 扩展框架参考

添加自定义命令

此功能 custom-commands 允许扩展在 azd命名空间下注册新命令。 示例扩展已对 azd tagger show 命令使用此功能。

  1. extension.yaml中声明功能。

    capabilities:
      - custom-commands
    
  2. 使用 azdext.NewExtensionRootCommand 帮助程序生成命令,该帮助程序注册标准 azd 标志和环境变量处理,因此无需手动声明它们:

    import "github.com/azure/azure-dev/cli/azd/pkg/azdext"
    
    func NewRootCommand() *cobra.Command {
        rootCmd, extCtx := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{
            Name:  "tagger",
            Use:   "tagger <command> [options]",
            Short: "Standardize and report Azure resource tags.",
        })
    
        rootCmd.AddCommand(newShowCommand(extCtx))
        // Add other subcommands here.
        return rootCmd
    }
    

    辅助程序返回一个 *ExtensionContext,它提供对标准标志(例如 EnvironmentOutputFormat)的已解析值的访问。 将上下文传递给各个子命令,并在其 RunE 处理函数中从中读取,而不是重新声明标准标志。

订阅生命周期事件

此功能 lifecycle-events 允许扩展在项目和服务生命周期事件(例如 preprovisionpostdeploy)期间运行自定义逻辑。 对于示例扩展,请使用事件 preprovision 来验证预配任何资源之前 azd 是否设置了所需的标记。

  1. extension.yaml中声明功能。

    capabilities:
      - custom-commands
      - lifecycle-events
    
  2. listen 命令添加到扩展。 azd 调用此命令以建立用于事件的双向连接。 使用 azdext.NewExtensionHost 构建器注册事件处理程序:

    func newListenCommand() *cobra.Command {
        return &cobra.Command{
            Use:    "listen",
            Short:  "Starts the extension and listens for azd events.",
            Hidden: true,
            RunE: func(cmd *cobra.Command, args []string) error {
                ctx := azdext.WithAccessToken(cmd.Context())
    
                azdClient, err := azdext.NewAzdClient()
                if err != nil {
                    return fmt.Errorf("failed to create azd client: %w", err)
                }
                defer azdClient.Close()
    
                host := azdext.NewExtensionHost(azdClient).
                    WithProjectEventHandler(
                        "preprovision",
                        func(ctx context.Context, args *azdext.ProjectEventArgs) error {
                            fmt.Printf("Verifying required tags for project: %s\n", args.Project.Name)
                            // Add your tag validation logic here.
                            return nil
                        },
                    )
    
                // Run blocks until azd closes the connection.
                if err := host.Run(ctx); err != nil {
                    return fmt.Errorf("failed to run extension: %w", err)
                }
    
                return nil
            },
        }
    }
    
  3. listen 命令注册到根命令中:

    rootCmd.AddCommand(newListenCommand())
    

当用户运行 azd provisionazd up 时,azd 会调用您的扩展,并在预配资源之前调用 preprovision 处理程序。

筛选服务事件

服务事件处理程序支持可选筛选,因此你仅处理特定的服务类型。 例如,您只能为 Python 的容器应用服务处理 prepackage 事件:

host := azdext.NewExtensionHost(azdClient).
    WithServiceEventHandler(
        "prepackage",
        func(ctx context.Context, args *azdext.ServiceEventArgs) error {
            fmt.Printf("Packaging service: %s\n", args.Service.Name)
            return nil
        },
        &azdext.ServiceEventOptions{
            Host:     "containerapp",
            Language: "python",
        },
    )

重新生成和测试

添加功能后,重新生成扩展并测试新行为:

  1. 如果你使用监视器,你所做的更改会自动重新构建。 否则,请手动生成:

    azd x build
    
  2. 测试该能力。 对于生命周期事件,请运行触发事件的命令,例如 azd provision