Adicionar capacidades de extensão

As capacidades definem o que uma extensão Azure Developer CLI (azd) pode fazer, desde adicionar comandos personalizados até à integração no ciclo de vida da implementação. Este artigo mostra-lhe como adicionar funcionalidades à extensão de exemplo Contoso Resource Tagger a partir do quickstart da extensão Build a sample. Podes aplicar os mesmos padrões a qualquer extensão.

Cada funcionalidade requer duas coisas: uma entrada no capabilities array do teu manifesto de extensão e a implementação correspondente no teu código de extensão.

Note

azd As extensões estão atualmente em versão beta.

Capacidades disponíveis

azd As extensões podem declarar as seguintes capacidades:

  • custom-commands: Adiciona novos comandos e grupos de comandos no azd namespace da sua extensão. Por exemplo, a extensão de exemplo adiciona azd tagger show. Use esta funcionalidade para expor tarefas que os utilizadores executam diretamente a partir da linha de comandos.
  • lifecycle-events: Subscreve os eventos que azd gera durante a execução, como preprovision, postprovision ou postdeploy. A tua extensão corre lógica personalizada nesses pontos sem que o utilizador a chame diretamente. Por exemplo, a extensão de exemplo verifica se preprovision tem as etiquetas necessárias antes de quaisquer recursos serem criados.
  • service-target-provider: Regista um novo destino de implantação para que azd saiba como empacotar e implementar um serviço num host que não suporta de origem. Um alvo de serviço corresponde ao valor host em azure.yaml. Por exemplo, pode adicionar um fornecedor que implemente um serviço numa plataforma de terceiros ou num ambiente de alojamento interno.
  • framework-service-provider: Regista suporte para uma linguagem ou framework para saber azd como restaurar, construir e empacotar esse tipo de projeto. Isto corresponde ao valor language em azure.yaml. Por exemplo, podes adicionar suporte de build para uma linguagem que azd não reconhece por defeito.
  • provisioning-provider: Substitui a forma como azd fornece infraestruturas durante azd provision e azd up. Em vez do fluxo Bicep ou Terraform incorporado, a sua extensão define o que acontece. Por exemplo, pode integrar uma ferramenta de infraestrutura como código diferente ou uma API de implementação personalizada.
  • validation-provider: Adiciona verificações ao pipeline de validação do azd que são executadas num projeto ou ambiente. Por exemplo, pode verificar se as convenções de nomenclatura, etiquetas obrigatórias ou definições de segurança estão em vigor antes de avançar a implementação.
  • mcp-server: Expõe as funcionalidades da sua extensão como ferramentas do protocolo Model Context Protocol (MCP) que agentes de IA, como o GitHub Copilot, podem descobrir e invocar. Por exemplo, a extensão de exemplo pode disponibilizar uma suggest_tags ferramenta. Para mais informações, consulte Adicionar um servidor MCP a uma extensão.
  • metadata: Fornece metadados de comandos e de configuração mais completos, que são utilizados por azd para descrever a sua extensão, como descrições detalhadas de comandos e sugestões de configuração disponibilizadas na saída da ajuda e no IntelliSense.

Este artigo foca-se nas duas capacidades mais comuns: comandos personalizados e eventos do ciclo de vida. Para a mcp-server capacidade, veja Adicionar um servidor MCP a uma extensão. Para detalhes completos sobre as capacidades do fornecedor, consulte a referência do framework de extensão.

Adicionar comandos personalizados

A custom-commands funcionalidade permite que a sua extensão registre novos comandos num namespace em azd. A extensão de exemplo já utiliza esta capacidade para o azd tagger show comando.

  1. Declare a capacidade em extension.yaml.

    capabilities:
      - custom-commands
    
  2. Constrói os teus comandos usando o azdext.NewExtensionRootCommand helper, que regista as flags padrão azd e o tratamento das variáveis de ambiente para não teres de os declarar manualmente:

    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
    }
    

    O helper devolve um *ExtensionContext que expõe os valores resolvidos das flags padrão, como Environment e OutputFormat. Passa o contexto para os teus subcomandos e lê-o dentro dos teus manipuladores RunE, em vez de redeclarares as opções padrão.

Subscreva eventos do ciclo de vida

A lifecycle-events funcionalidade permite que a sua extensão execute lógica personalizada durante eventos do ciclo de vida do projeto e do serviço, como preprovision ou postdeploy. Para a extensão de exemplo, use um preprovision evento para verificar se as etiquetas necessárias estão definidas antes de azd provisionar quaisquer recursos.

  1. Declare a capacidade em extension.yaml.

    capabilities:
      - custom-commands
      - lifecycle-events
    
  2. Adiciona um listen comando à tua extensão. azd invoca este comando para estabelecer a ligação bidirecional usada nos eventos. Utilize o azdext.NewExtensionHost builder para registar os seus manipuladores de eventos:

    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. Regista o listen comando no teu comando raiz:

    rootCmd.AddCommand(newListenCommand())
    

Quando um utilizador executa azd provision ou azd up, azd invoca a sua extensão e chama o preprovision handler antes de provisionar recursos.

Filtrar eventos de serviço

Os processadores de eventos de serviço suportam filtragem opcional para que sejam processados apenas tipos de serviço específicos. Por exemplo, pode processar o evento prepackage apenas para serviços de aplicações de contentor em Python:

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",
        },
    )

Reconstrução e teste

Depois de adicionar uma capacidade, reconstrua a extensão e teste o novo comportamento:

  1. Se estiveres a usar o modo de monitorização, as tuas alterações são recompiladas automaticamente. Caso contrário, constrói manualmente:

    azd x build
    
  2. Teste a funcionalidade. Para eventos do ciclo de vida, execute um comando que desencadeie o evento, como azd provision.