Adicionar recursos de extensão

Os recursos definem o que uma extensão da CLI do Desenvolvedor do Azure (azd) pode fazer, desde a adição de comandos personalizados até a conexão no ciclo de vida da implantação. Este artigo mostra como adicionar recursos à extensão de exemplo contoso Resource Tagger do início rápido de compilação de uma extensão de exemplo. Você pode aplicar os mesmos padrões a qualquer extensão.

Cada funcionalidade requer duas coisas: uma entrada na capabilities matriz do manifesto de extensão e a implementação correspondente em seu código de extensão.

Note

azd as extensões estão atualmente na versão beta.

Funcionalidades disponíveis

azd as extensões podem declarar os seguintes recursos:

  • custom-commands: adiciona novos comandos e grupos de comandos ao azd namespace da sua extensão. Por exemplo, a extensão de exemplo adiciona azd tagger show. Use essa funcionalidade para expor tarefas que os usuários executam diretamente da linha de comando.
  • lifecycle-events: Assina os eventos que azd aciona durante a execução, como preprovision, postprovision ou postdeploy. Sua extensão executa a lógica personalizada nesses pontos sem que o usuário a chame diretamente. Por exemplo, a extensão de exemplo verifica a presença das tags necessárias em preprovision antes que qualquer recurso seja criado.
  • service-target-provider: registra um novo destino de implantação para que azd saiba como empacotar e implantar um serviço em um host ao qual ele não oferece suporte nativamente. Um destino de serviço corresponde ao valor host em azure.yaml. Por exemplo, você pode adicionar um provedor que implanta um serviço a uma plataforma de terceiros ou a um ambiente de hospedagem interno.
  • framework-service-provider: registra o suporte para um idioma ou estrutura, portanto azd , sabe como restaurar, compilar e empacotar esse tipo de projeto. Isso corresponde ao valor language em azure.yaml. Por exemplo, você pode adicionar suporte de build para um idioma que azd não reconhece por padrão.
  • provisioning-provider: substitui como azd provisiona a infraestrutura durante azd provision e azd up. Em vez do fluxo integrado do Bicep ou do Terraform, sua extensão define o que acontece. Por exemplo, você pode integrar uma ferramenta de infraestrutura como código diferente ou uma API de implantação personalizada.
  • validation-provider: adiciona verificações ao pipeline de validação azd, que é executado em um projeto ou ambiente. Por exemplo, você pode verificar se as convenções de nomenclatura, as marcas necessárias ou as configurações de segurança estão em vigor antes que uma implantação continue.
  • mcp-server: Expõe os recursos da sua extensão como ferramentas MCP (Protocolo de Contexto do Modelo) que agentes de IA, como o GitHub Copilot, podem descobrir e invocar. Por exemplo, a extensão de exemplo pode expor a ferramenta suggest_tags. Para obter mais informações, consulte Adicionar um servidor MCP a uma extensão.
  • metadata: fornece metadados mais completos sobre comandos e configuração que azd usa para descrever sua extensão, como descrições detalhadas de comandos e dicas de configuração apresentadas na saída da ajuda e no IntelliSense.

Este artigo se concentra nos dois recursos mais comuns: comandos personalizados e eventos de ciclo de vida. Para obter a mcp-server funcionalidade, consulte Adicionar um servidor MCP a uma extensão. Para obter detalhes completos sobre os recursos do provedor, consulte a referência da estrutura de extensão.

Adicionar comandos personalizados

A custom-commands funcionalidade permite que sua extensão registre novos comandos em um namespace em azd. A extensão de exemplo já usa essa funcionalidade para o azd tagger show comando.

  1. Declare a funcionalidade em extension.yaml.

    capabilities:
      - custom-commands
    
  2. Crie seus comandos usando o azdext.NewExtensionRootCommand auxiliar, que registra os sinalizadores padrão azd e a manipulação de variáveis de ambiente para que você não precise declará-los 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 auxiliar retorna um *ExtensionContext que expõe os valores resolvidos dos sinalizadores padrão, como Environment e OutputFormat. Passe o contexto para seus subcomandos e leia a partir dele nos manipuladores RunE deles, em vez de redeclarar as flags padrão.

Inscrever-se em eventos de ciclo de vida

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

  1. Declare a funcionalidade em extension.yaml.

    capabilities:
      - custom-commands
      - lifecycle-events
    
  2. Adicione um listen comando à sua extensão. azd invoca esse comando para estabelecer a conexão bidirecional usada para eventos. Use o azdext.NewExtensionHost builder para registrar 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. Registre o comando listen no comando raiz:

    rootCmd.AddCommand(newListenCommand())
    

Quando um usuário executa azd provision ou azd up, azd invoca sua extensão e chama o manipulador preprovision antes de provisionar recursos.

Filtrar eventos de serviço

Os manipuladores de eventos de serviço dão suporte à filtragem opcional para que você trate apenas tipos de serviço específicos. Por exemplo, você pode lidar com o evento prepackage somente para serviços de aplicativo de contêiner do 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",
        },
    )

Recompilar e testar

Depois de adicionar uma funcionalidade, recompile a extensão e teste o novo comportamento:

  1. Se você estiver usando o observador, suas alterações serão recriadas automaticamente. Caso contrário, crie manualmente:

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