v1.2.2
A lightweight, high-performance CLI utility for validating Azure resource moveability without performing the actual move operation.
โ ๏ธ NOTE: THIS TOOL PERFORMS READ-ONLY VALIDATION AND WILL NOT PERFORM ANY ACTUAL MOVE OPERATIONS. IT GENERATES A DETAILED VALIDATION REPORT FOR ANALYSIS.
ARMV is a production-ready Go CLI utility that validates whether Azure resources can be moved between resource groups and subscriptions. It acts as a comprehensive wrapper around Azure's Validate Move Resources API, providing intelligent polling, detailed error reporting, and secure file operations.
This tool is a complete rewrite of the deprecated pyazvalidatemoveresources Python utility, now delivered as a fully standalone, self-contained Go binary with zero external dependencies.
- Non-Destructive Validation: Tests moveability without making any changes
- Cross-Subscription Support: Validate moves across different subscriptions (same tenant only)
- Intelligent Polling: Long-running operation polling with timeout protection (max 30 minutes)
- Comprehensive Error Reporting: Detailed JSON diagnostics including tracking IDs and timestamps
- Progress Visualization: Real-time progress bar during validation operations
- Secure File Operations: Timestamped output files with secure permissions
- Debug Mode: Optional verbose logging and timing information
- Production-Ready: Fully tested, optimized memory usage, and comprehensive error handling
- Multi-Platform Support: Cross-platform binaries for Linux, Windows, and macOS
- Security Focused: Vulnerability scanning (govulncheck), static analysis (staticcheck), and comprehensive testing
- Continuous Integration: Automated builds, tests, and security checks on every commit
- Input Validation: Validates subscription IDs and resource group references
- Authentication: Uses Azure CLI's stored credentials (
az logincontext) - Resource Discovery: Enumerates all resources in the source resource group
- Validation: Calls Azure's Validate Move Resources API
- Polling: Polls the long-running operation with visual progress indication
- Output Generation: Writes timestamped results to the output directory
- HTTP 204 (Success): All resources are eligible for move
- HTTP 409 (Conflict): One or more resources cannot be moved - detailed error report is generated
When validation fails, a detailed JSON report is generated:
{
"error": {
"code": "ResourceMoveValidationFailed",
"message": "The resource batch move request has '1' validation errors. Diagnostic information: timestamp '20240520T034539Z', tracking Id '8f53448f-e108-4f51-85d4-259e2137761d', request correlation Id '0a88b427-06ea-4045-98f1-7d2c4aaf2867'.",
"details": [
{
"code": "ResourceMoveNotSupported",
"target": "/subscriptions/<subID>/resourceGroups/src-rsg/providers/Microsoft.ContainerInstance/containerGroups/aciresource",
"message": "Resource move is not supported for resource types 'Microsoft.ContainerInstance/containerGroups'."
}
]
}
}ARMV follows a clean, layered architecture for maintainability and extensibility:
| Layer | Location | Responsibility |
|---|---|---|
| CLI Layer | cmd/armv/app/ |
Command-line interface, flag parsing, orchestration |
| Authentication | internal/pkg/auth/ |
Azure credential management and SDK clients |
| Validation | internal/pkg/validation/ |
Resource move validation API wrapper |
| Resource Management | internal/pkg/resourcegroups/, internal/pkg/resources/ |
Azure resource group and resource operations |
| Polling | cmd/armv/poller/ |
Long-running operation polling and result handling |
| Utilities | pkg/utils/ |
Input validation, error handling, file I/O, JSON processing |
armv/
โโโ cmd/armv/ # Application entry points
โ โโโ main.go # CLI entry point with version embedding
โ โโโ app/ # Application logic
โ โ โโโ root.go # Cobra CLI command setup
โ โ โโโ command.go # Main validation workflow orchestration
โ โ โโโ login.go # Azure authentication verification
โ โ โโโ resourcegroup.go # Resource group operations
โ โโโ poller/ # Long-running operation handling
โ โโโ pollapi.go # API polling logic with timeout
โ โโโ pollresponse.go # Response handling and output
โ โโโ pollerresponsedata.go # Response data structures
โ โโโ progressbar.go # Progress bar visualization
โ โโโ constants.go # Configuration constants
โ
โโโ internal/pkg/ # Private internal packages
โ โโโ auth/ # Azure authentication
โ โ โโโ auth.go # Credential and client creation
โ โโโ validation/ # Resource move validation
โ โ โโโ azureresourcemoveinfo.go # Validation parameters struct
โ โ โโโ validatemove.go # Validation API wrapper
โ โโโ resourcegroups/ # Resource group operations
โ โ โโโ resourcegroups.go # RG client and operations
โ โโโ resources/ # Resource operations
โ โโโ resources.go # Resource enumeration and filtering
โ
โโโ pkg/utils/ # Public utility functions
โ โโโ args.go # CLI argument structures
โ โโโ validateinput.go # UUID/subscription ID validation
โ โโโ errorhandler.go # Error handling utilities
โ โโโ output.go # Console output formatting
โ โโโ outputfile.go # File I/O with secure permissions
โ โโโ jsonutils.go # JSON marshaling/unmarshaling
โ
โโโ test/ # Comprehensive test suite
โ โโโ args_test.go
โ โโโ validateinput_test.go
โ โโโ azureresourcemoveinfo_test.go
โ โโโ command_test.go
โ โโโ pollerresponsedata_test.go
โ โโโ jsonutils_test.go
โ โโโ outputfile_test.go
โ
โโโ go.mod # Go module definition
โโโ go.sum # Dependency checksums
โโโ Taskfile.yml # Build task automation
โโโ README.md # This file
โโโ LICENSE # MIT License
โโโ CHANGELOG.md # Version history
โโโ TODO.md # Future enhancements
The project uses the following key Go packages:
| Package | Version | Purpose |
|---|---|---|
github.com/Azure/azure-sdk-for-go/sdk/azcore |
v1.19.1 | Azure SDK core functionality |
github.com/Azure/azure-sdk-for-go/sdk/azidentity |
v1.13.0 | Azure credential authentication |
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources |
v1.2.0 | Azure resources API client |
github.com/spf13/cobra |
v1.10.1 | CLI command framework |
github.com/schollz/progressbar/v3 |
v3.18.0 | Progress bar visualization |
- Go: v1.25.3 or later for building from source
- Azure CLI: v2.50 or later
- Taskfile: v3.0+ for build automation (optional but recommended)
- Azure Credentials: Valid Azure CLI login context (
az login)
The project uses comprehensive GitHub Actions workflows for:
- Multi-Platform Testing: Automated builds and tests on Ubuntu, Windows, and macOS
- Multi-Architecture Support: Cross-platform binary releases for amd64, arm64, armv7, and 386
- Code Quality: Automated vulnerability scanning, static analysis, and linting
- Release Automation: GoReleaser for building and publishing multi-platform binaries
All commits run through:
- โ govulncheck: Vulnerability scanning
- โ staticcheck: Advanced static code analysis
- โ go vet: Go's built-in static analysis
- โ go test: Comprehensive unit tests (38+ test cases, 100% pass rate)
Before using ARMV, you must authenticate with Azure:
# Log in to Azure
az login
# Set the active subscription (replace XXXX-XXXX-XXXX-XXXX with your subscription ID)
az account set --subscription "XXXX-XXXX-XXXX-XXXX"ARMV uses the DefaultAzureCredential chain from the Azure SDK, which will use your authenticated Azure CLI context.
This project uses Taskfile for build automation. All build commands are defined in Taskfile.yml.
build # Build debug version for your platform
clean # Remove builds and debug artifacts
debug # Run debug version with environment variables
deploy # Deploy test Azure resources using Bicep
destroy # Destroy test Azure resources
deps # Fetch and update dependencies
generate # Update binary version using go:generate
goreleaser # Build cross-platform release binaries
lint # Format, lint, and tidy code
release # Build optimized release binary (outputs to /bin)
run # Build and run the application
seccheck # Security vulnerability scanner
staticcheck # Static code analysis
test # Run unit tests
version # Display Go version
vet # Examine code for suspicious constructs
watch # Enable hot reload with air# 1. Fetch dependencies
task deps
# 2. Build debug version
task build
# 3. Build release version (outputs to ./bin)
task release# Run all unit tests
task test
# Run tests with verbose output
go test ./... -v
# Run tests with coverage report
go test ./... -cover./armv --SourceSubscriptionId <SOURCE_SUB_ID> \
--SourceResourceGroup <SOURCE_RG> \
--TargetSubscriptionId <TARGET_SUB_ID> \
--TargetResourceGroup <TARGET_RG>| Flag | Description | Example |
|---|---|---|
--SourceSubscriptionId |
Source Azure subscription ID (UUID format) | 00000000-0000-0000-0000-000000000000 |
--SourceResourceGroup |
Source resource group name | my-source-rg |
--TargetSubscriptionId |
Target Azure subscription ID (UUID format) | 00000000-0000-0000-0000-000000000001 |
--TargetResourceGroup |
Target resource group name | my-target-rg |
| Flag | Description | Default |
|---|---|---|
--outpath |
Directory path for output files | ./output |
--debug |
Enable debug mode with timing information | false |
--help |
Display help information | - |
--version |
Display version information | - |
./armv \
--SourceSubscriptionId "12345678-1234-1234-1234-123456789012" \
--SourceResourceGroup "rg-prod-east" \
--TargetSubscriptionId "87654321-4321-4321-4321-210987654321" \
--TargetResourceGroup "rg-dev-west"./armv \
--SourceSubscriptionId "12345678-1234-1234-1234-123456789012" \
--SourceResourceGroup "source-rg" \
--TargetSubscriptionId "12345678-1234-1234-1234-123456789012" \
--TargetResourceGroup "target-rg" \
--outpath "/var/log/armv-reports"./armv \
--SourceSubscriptionId "12345678-1234-1234-1234-123456789012" \
--SourceResourceGroup "source-rg" \
--TargetSubscriptionId "12345678-1234-1234-1234-123456789012" \
--TargetResourceGroup "target-rg" \
--debugWhen validation completes, a timestamped report file is created in the output directory:
./output/output-2024-10-30-14-30-45.txt
Success Output (HTTP 204):
Validation succeeded with HTTP code: 204
All resources are eligible for move
Failure Output (HTTP 409): The output file contains a detailed JSON error report with:
- Error code and message
- Diagnostic information (timestamp, tracking ID, correlation ID)
- Per-resource validation failures with specific reasons
The project includes comprehensive unit tests with 38+ test cases covering:
| Test File | Focus | Test Cases |
|---|---|---|
validateinput_test.go |
UUID/subscription ID validation | 8 tests |
args_test.go |
Command-line argument parsing | 3 tests |
azureresourcemoveinfo_test.go |
Validation parameter initialization | 5 tests |
command_test.go |
Cobra command configuration | 10 tests |
pollerresponsedata_test.go |
API response processing | 4 tests |
jsonutils_test.go |
JSON serialization/deserialization | 14 tests |
outputfile_test.go |
File I/O and permissions | 7 tests |
Test Status: โ 100% Pass Rate
Run tests with:
# Run all tests
task test
# Verbose output
go test ./... -v
# With coverage
go test ./... -cover
# Run security checks
task seccheck # govulncheck
task staticcheck # Static analysis
task vet # go vet- Single Tenant: Currently supports only subscriptions and resource groups within the same Azure tenant
- Source Resource Group: All resources to be moved must be in the same source resource group
- Target Flexibility: Target resource group can be in a different subscription (within the same tenant)
Error: No credentials found
Solution: Ensure you're logged in to Azure CLI:
az login
az account show # Verify active subscriptionError: Invalid subscription ID format
Solution: Ensure subscription IDs are valid UUIDs:
Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Example: 12345678-1234-1234-1234-123456789012
Error: Resource group not found
Solution:
- Verify the resource group exists in the specified subscription
- Ensure you have permissions to access the resource group
- Check that you're using the correct subscription context
Error: Validation operation timed out after 30 minutes
Solution:
- This indicates the Azure API is taking longer than expected
- Check Azure service health: https://status.azure.com/
- Retry the validation operation
- Consider validating smaller batches of resources
Found a bug or have a feature request? Please report it on GitHub:
๐ Report Issues Here
Include the following information:
- ARMV version (
./armv --version) - Go version (
go version) - Error message and output file
- Steps to reproduce
The project maintains high code quality standards:
# Format and lint
task lint
# Security vulnerability scan
task seccheck
# Static analysis
task staticcheck
# Vet (examines code for suspicious constructs)
task vet- Create a feature branch:
git checkout -b feature/my-feature - Make changes and commit:
git commit -am "Add new feature" - Push to remote:
git push origin feature/my-feature - Create a pull request
The project includes automated CI/CD workflows:
Runs on every push and pull request to main:
- Multi-platform matrix testing (Ubuntu, Windows, macOS)
- Dependency verification
- Code quality checks (go vet, staticcheck, govulncheck)
- Comprehensive unit tests
- Binary build verification
Runs on release creation:
- Pre-release multi-platform testing
- Cross-platform binary compilation (amd64, arm64, armv7, 386)
- Automatic release notes generation
- Binary artifact publishing
Pre-compiled binaries are available for multiple platforms:
| OS | Architectures |
|---|---|
| Linux | amd64, arm64, armv7, 386 |
| Windows | amd64, 386 |
| macOS | amd64, arm64 |
Download latest binaries from GitHub Releases
This project is licensed under the MIT License - see the LICENSE file for details.
- Original Tool: pyazvalidatemoveresources (Python, deprecated)
- Azure Documentation: Validate Move Resources API
- Azure Go SDK: Azure SDK for Go
Questions or feedback? Please open an issue or check the project repository