mcpbeat

Azqr Developer

azure/azqr-developer

Expert guidance for developing and contributing to Azure Quick Review (azqr) - A Go-based CLI tool for Azure resource compliance analysis

5k tokens
context cost
the whole folder, loaded on every use
2
files
instructions only
0
copies elsewhere
how many repositories repackaged it
783
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/Azure/azqr --skill azqr-developer

What comes with it

6 128 bytes besides the instruction
knowledge/go-idioms.md

The instruction itself

37 sections, as written by the author

Azure Quick Review (azqr) Development Skill

Expert guidance for autonomous agents and developers contributing to the Azure Quick Review (azqr) project.

Project Overview

Azure Quick Review (azqr) is a CLI tool written in Go that analyzes Azure resources for compliance with Azure's best practices and recommendations. The tool scans Azure resources using:

  • Azure Resource Graph (ARG) queries from the Azure Proactive Resiliency Library v2 (APRL)
  • Azure Resource Manager (ARM) rules built with the Azure Golang SDK

Quick Start

Prerequisites

  • Go 1.23.3 or higher
  • Valid Azure authentication (Service Principal, Managed Identity, or Azure CLI)

Essential Commands

# Build the project
make build

# Run all tests (REQUIRED before submitting pull requests)
make test

# Clean build artifacts
make clean

# View all available targets
make help

Project Structure

azqr/
├── cmd/azqr/               # Main CLI application entry point
│   ├── main.go            # Application entry point
│   └── commands/          # CLI command implementations (one file per Azure service)
├── cmd/server/            # Server mode implementation
├── internal/              # Internal packages
│   ├── scanner.go         # Main scanning logic
│   ├── models/            # Data models and filters
│   ├── renderers/         # Output formatters (Excel, CSV, JSON)
│   ├── scanners/          # Service-specific scanners (one per Azure service)
│   ├── graph/             # Azure Resource Graph queries
│   └── aigov/             # AI Governance utilities
├── data/                  # Static data files
│   └── recommendations.json # Generated recommendations data
├── examples/              # Example configurations and CI/CD pipelines
├── docs/                  # Documentation website (Hugo-based)
└── Makefile              # Build automation

Code Style and Standards

Naming Conventions

  • Variables: Use camelCase for all variable names
  • Functions: Use MixedCaps for exported functions, mixedCaps for unexported
  • Packages: Use lowercase, single-word package names (avoid underscores)
  • Interfaces: Name with -er suffix when possible (e.g., Scanner, Renderer)

Documentation

  • Always add code comments using godoc style for exported functions
  • Document why, not what, unless the what is complex
  • Start comments with the name of the thing being described
  • Write comments in complete sentences

Authentication

All code must support multiple authentication methods:

  • Service Principal (environment variables: AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID)
  • Azure Managed Identity
  • Azure CLI authentication

Error Handling

  • Follow Go idiomatic error handling patterns
  • Check errors immediately after the function call
  • Wrap errors with context using fmt.Errorf with %w verb
  • Keep error messages lowercase and don't end with punctuation
  • Name error variables err

Development Workflow

1. Adding Support for New Azure Services

When adding a new Azure service, follow this systematic approach:

  • Create scanner in internal/scanners/<service>/
  • Implement the scanner interface
  • Support both ARM-based and ARG-based recommendations
  • Include appropriate error handling and logging
  • Add command in cmd/azqr/commands/<service>.go
  • Follow the existing command pattern
  • Use appropriate service abbreviation (see README.md)
  • Update models in internal/models/
  • Add service-specific models if needed
  • Ensure models support JSON serialization
  • Add comprehensive tests
  • Include unit tests for scanner logic
  • Test both success and error cases
  • Use table-driven tests for multiple scenarios
  • Update documentation
  • Add service to supported services list in README.md
  • Document any service-specific requirements

2. Testing Requirements

CRITICAL: Always run make test before submitting pull requests. This is non-negotiable.

The test command includes:

  • Linting (golangci-lint) - Code quality checks
  • Go vet checks - Static analysis
  • Module tidiness verification - Dependency management
  • Unit tests with race condition detection
  • Coverage reporting
# Run the full test suite (ALWAYS run before PR)
make test

# Individual test components
make lint    # Run linter
make vet     # Run go vet
make tidy    # Check module tidiness

3. Building and Distribution

# Build for current platform
make build

# Build for specific OS/architecture
GOOS=linux GOARCH=amd64 make build
GOOS=windows GOARCH=amd64 make build

# Build Docker image
make build-image

# Build with version information
PRODUCT_VERSION=1.0.0 make build

# Update recommendations.json after adding rules
make json

Common Development Tasks

Adding a New Recommendation Rule

  • Identify the target Azure service
  • Locate the appropriate scanner in internal/scanners/<service>/
  • Add the rule logic following existing patterns:
  • Use consistent naming conventions
  • Include clear comments explaining the rule
  • Reference official Azure documentation
  • Update tests to cover the new rule
  • Run make json to update recommendations.json
  • Verify with make test

Fixing Bugs

  • Reproduce the issue with a minimal test case
  • Add regression test if missing
  • Implement fix following project patterns
  • Verify fix with make test
  • Update documentation if the bug revealed unclear behavior

Performance Optimization

  • Use the throttling utilities in internal/throttling/ for rate limiting
  • Implement concurrent scanning where appropriate (use goroutines wisely)
  • Cache expensive operations when possible
  • Profile using Go's built-in tools before optimizing
  • Focus on algorithmic improvements first

Scanner Implementation Patterns

Scanner Interface

// internal/scanners/<service>/<service>.go
package <service>

import (
    "context"
    "github.com/Azure/azqr/internal/models"
)

// Scanner implements the service scanner interface
type Scanner struct {
    // Scanner fields (config, client, etc.)
}

// Scan performs the compliance scan for the service
func (s *Scanner) Scan(ctx context.Context) ([]models.Recommendation, error) {
    // Implementation
    // 1. Fetch resources
    // 2. Apply recommendation rules
    // 3. Return findings
}

Command Implementation

// cmd/azqr/commands/<service>.go
package commands

import (
    "github.com/spf13/cobra"
)

func init() {
    // Register command with root command
}

var <service>Cmd = &cobra.Command{
    Use:   "<service>",
    Short: "Scan <Service Name>",
    Long:  "Detailed description of what this scanner does",
    Run:   <service>Run,
}

func <service>Run(cmd *cobra.Command, args []string) {
    // Command implementation
    // 1. Parse flags
    // 2. Initialize scanner
    // 3. Run scan
    // 4. Output results
}

Testing Patterns

Table-Driven Tests

func TestScanner_Scan(t *testing.T) {
    tests := []struct {
        name    string
        setup   func() // setup test environment
        want    int    // expected number of recommendations
        wantErr bool
    }{
        {
            name:    "success case",
            setup:   func() { /* setup */ },
            want:    5,
            wantErr: false,
        },
        {
            name:    "error case",
            setup:   func() { /* setup */ },
            want:    0,
            wantErr: true,
        },
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            tt.setup()
            // test implementation
        })
    }
}

Runtime Debugging and Troubleshooting

Enable Debug Mode

# Set environment variable for detailed logging
export AZURE_SDK_GO_LOGGING=all

# Run with debug flag
./azqr scan --debug

Common Issues and Solutions

  • Authentication Failures
  • Verify Azure credentials are set correctly
  • Check permissions (requires Reader on Subscription/Management Group)
  • Test with az account show if using Azure CLI auth
  • Rate Limiting
  • Use appropriate throttling settings
  • Implement exponential backoff for retries
  • Consider batching requests when possible
  • Memory Usage
  • Monitor for large subscriptions with many resources
  • Use streaming or pagination for large datasets
  • Profile memory usage with pprof
  • Network Connectivity
  • Ensure access to Azure APIs
  • Check firewall and proxy settings
  • Verify DNS resolution

Environment Variables

Authentication

# Service Principal
AZURE_CLIENT_ID="<service-principal-id>"
AZURE_CLIENT_SECRET="<service-principal-secret>"  
AZURE_TENANT_ID="<tenant-id>"

# Credential Chain Configuration
AZURE_TOKEN_CREDENTIALS="dev"   # Use Azure CLI/Azure Developer CLI
AZURE_TOKEN_CREDENTIALS="prod"  # Use env vars/workload identity/managed identity

Debugging

AZURE_SDK_GO_LOGGING="all"      # Enable detailed SDK logging

Contributing Guidelines

Pull Request Requirements

  • Testing: Run make test and ensure all tests pass (100% required)
  • Code Quality: Follow the existing code style and patterns
  • Documentation: Update relevant documentation (README, code comments)
  • Commit Messages: Use clear, descriptive commit messages
  • Dependencies: Minimize new dependencies; justify if necessary

Supported Azure Services

The project currently supports 50+ Azure services including:

  • Compute: VMs, AKS, Azure Functions, App Service, etc.
  • Storage: Storage Accounts, Disks, NetApp Files, etc.
  • Networking: Virtual Networks, Load Balancers, Application Gateway, etc.
  • Databases: SQL, Cosmos DB, PostgreSQL, MySQL, etc.
  • And many more...

When adding new services:

  • Use appropriate abbreviations (see README.md for existing conventions)
  • Implement both ARM-based and ARG-based recommendations where applicable
  • Follow the scanner interface pattern
  • Include appropriate error handling and logging

Output Formats

azqr generates reports in multiple formats:

  • Excel (default): Multi-sheet workbook with recommendations, impacted resources, inventory, etc.
  • CSV: Same data as Excel but in CSV format (use --csv flag)
  • JSON: Machine-readable format for automation

Key Resources and References

Support and Community

  • Issues: Use GitHub Issues for bug reports and feature requests
  • Discussions: Use GitHub Discussions for questions and support
  • Security: Report security issues following the SECURITY.md guidelines
  • Code of Conduct: Follow the Microsoft Open Source Code of Conduct

Critical Reminders

  • Always run make test before submitting a pull request - This is the most important rule
  • Use camelCase for variable names
  • Add godoc-style comments to all exported functions
  • Support all authentication methods (Service Principal, Managed Identity, Azure CLI)
  • Follow Go idiomatic error handling
  • Keep code simple and readable
  • Update recommendations.json with make json after adding rules
  • Reference APRL documentation when implementing ARG-based rules
  • Test both success and error paths

10. Keep scanner implementations consistent with existing patterns

How to use it

Copy the folder

Take azure/azqr-developer from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.