Adding a New Command
April 25, 2026 · View on GitHub
This guide walks through adding a new command to the Azure Developer CLI.
Overview
azd uses an ActionDescriptor pattern to define commands. Each command consists of:
- ActionDescriptor — Declares the command's metadata, flags, and output formats
- Action — Implements
Run(ctx context.Context) (*ActionResult, error) - Flags struct — Defines command-line flags with a
Bind()method - IoC registration — Wires the action and flags into the dependency injection container
Quick Start
1. Create the command file
Create cli/azd/cmd/<command_name>.go:
package cmd
import (
"context"
"github.com/azure/azure-dev/cli/azd/cmd/actions"
"github.com/azure/azure-dev/cli/azd/internal"
"github.com/spf13/pflag"
)
type myCommandFlags struct {
name string
}
func (f *myCommandFlags) Bind(local *pflag.FlagSet, global *internal.GlobalCommandOptions) {
local.StringVar(&f.name, "name", "", "Resource name")
}
type myCommandAction struct {
flags *myCommandFlags
svc *SomeService
}
func newMyCommandAction(flags *myCommandFlags, svc *SomeService) actions.Action {
return &myCommandAction{flags: flags, svc: svc}
}
func (a *myCommandAction) Run(ctx context.Context) (*actions.ActionResult, error) {
// Command logic here
return &actions.ActionResult{
Message: &actions.ResultMessage{Header: "Done!"},
}, nil
}
2. Register the command
Add to the command tree in cli/azd/cmd/root.go:
root.Add("mycommand", &actions.ActionDescriptorOptions{
Command: newMyCommandCmd(),
ActionResolver: newMyCommandAction,
FlagsResolver: newMyCommandFlags,
})
3. Support output formats
If the command produces structured output, add format support in the descriptor and inject output.Formatter in your action:
root.Add("mycommand", &actions.ActionDescriptorOptions{
Command: newMyCommandCmd(),
ActionResolver: newMyCommandAction,
FlagsResolver: newMyCommandFlags,
OutputFormats: []output.Format{output.JsonFormat, output.TableFormat},
})
Note:
OutputFormatsonly registers the--outputand--queryflags. Your action must also injectoutput.Formatteras a dependency and callformatter.Format()to emit structured output.
4. Update snapshots
After adding the command, regenerate CLI snapshots:
UPDATE_SNAPSHOTS=true go test ./cmd -run 'TestFigSpec|TestUsage'
Design Principles
- Verb-first structure: Use simple verbs (
up,add,deploy) with minimal nesting - Build on existing categories: Extend existing command groups rather than creating new ones
- Progressive disclosure: Basic usage should be simple; advanced features discoverable when needed
- Consistent parameters: Reuse established flag patterns (
--subscription,--name,--output)
Detailed Reference
For the full implementation guide including middleware, telemetry integration, and advanced patterns, see: