github cloudposse/atmos v1.196.0-rc.1

latest release: v1.196.0-rc.2
pre-release2 days ago
Add Azure Blob Storage (azurerm) backend support for !terraform.state function @jamengual (#1610) ## what - Implemented Azure Blob Storage backend support for the `!terraform.state` YAML function - Added comprehensive unit tests with 100% coverage for the new backend - Updated error definitions, registry, and documentation

why

  • The !terraform.state function previously only supported local and s3 backends
  • Azure users needed native azurerm backend support to read Terraform state directly from Azure Blob Storage
  • This provides the fastest way to retrieve Terraform outputs without Terraform initialization overhead

changes

  • New Implementation: internal/terraform_backend/terraform_backend_azurerm.go

    • Implements azurerm backend reader following S3 backend patterns
    • Uses Azure SDK with DefaultAzureCredential for authentication (Managed Identity, Service Principal, Azure CLI, etc.)
    • Supports workspace-based blob paths (env:/{workspace}/{key} for non-default workspaces)
    • Includes client caching, retry logic (2 retries with exponential backoff), and proper error handling
    • Handles 404 (blob not found) gracefully by returning nil (component not provisioned yet)
    • Handles 403 (permission denied) with descriptive error messages
  • Comprehensive Tests: internal/terraform_backend/terraform_backend_azurerm_test.go

    • 8 test functions covering all scenarios with mocked Azure SDK client
    • Tests workspace handling (default vs non-default), blob not found, permission denied, network errors, retry logic, and error cases
    • All tests pass with no external dependencies required
  • Error Definitions: errors/errors.go

    • Added 7 new Azure-specific static errors following project patterns
    • ErrGetBlobFromAzure, ErrReadAzureBlobBody, ErrCreateAzureCredential, ErrCreateAzureClient, ErrAzureContainerRequired, ErrStorageAccountRequired, ErrAzurePermissionDenied
  • Registry Update: internal/terraform_backend/terraform_backend_registry.go

    • Registered ReadTerraformBackendAzurerm in the backend registry
  • Error Message Update: internal/terraform_backend/terraform_backend_utils.go

    • Updated supported backends list to include azurerm
  • Documentation Update: website/docs/functions/yaml/terraform.state.mdx

    • Added azurerm to the list of supported backend types
    • Updated warning message to reflect azurerm support
  • Dependencies: go.mod

    • Moved github.com/Azure/azure-sdk-for-go/sdk/storage/azblob from indirect to direct dependency (already present in project)

implementation notes

  • Follows established patterns from S3 backend implementation
  • Uses wrapper pattern (AzureBlobAPI interface) to enable testing without actual Azure connectivity
  • Implements proper workspace path handling matching Azure backend behavior (env:/{workspace}/{key})
  • All comments end with periods (enforced by golangci-lint)
  • Imports organized in 3 groups (stdlib, 3rd-party, atmos) as per CLAUDE.md
  • Performance tracking added with defer perf.Track() on all functions
  • Cross-platform compatible using Azure SDK (not CLI commands)

test results

=== RUN   TestReadTerraformBackendAzurermInternal_Success
=== RUN   TestReadTerraformBackendAzurermInternal_Success/successful_read_default_workspace
=== RUN   TestReadTerraformBackendAzurermInternal_Success/successful_read_dev_workspace
=== RUN   TestReadTerraformBackendAzurermInternal_Success/successful_read_prod_workspace
=== RUN   TestReadTerraformBackendAzurermInternal_Success/successful_read_empty_workspace
=== RUN   TestReadTerraformBackendAzurermInternal_Success/successful_read_default_key
--- PASS: TestReadTerraformBackendAzurermInternal_Success (0.00s)
=== RUN   TestReadTerraformBackendAzurermInternal_BlobNotFound
--- PASS: TestReadTerraformBackendAzurermInternal_BlobNotFound (0.00s)
=== RUN   TestReadTerraformBackendAzurermInternal_PermissionDenied
--- PASS: TestReadTerraformBackendAzurermInternal_PermissionDenied (0.00s)
=== RUN   TestReadTerraformBackendAzurermInternal_NetworkError
--- PASS: TestReadTerraformBackendAzurermInternal_NetworkError (4.00s)
=== RUN   TestReadTerraformBackendAzurermInternal_RetrySuccess
--- PASS: TestReadTerraformBackendAzurermInternal_RetrySuccess (2.00s)
=== RUN   TestReadTerraformBackendAzurermInternal_MissingContainerName
--- PASS: TestReadTerraformBackendAzurermInternal_MissingContainerName (0.00s)
=== RUN   TestReadTerraformBackendAzurermInternal_ReadBodyError
--- PASS: TestReadTerraformBackendAzurermInternal_ReadBodyError (0.00s)
PASS
ok      github.com/cloudposse/atmos/internal/terraform_backend 7.011s

Summary by CodeRabbit

  • New Features

    • Azure Blob Storage (azurerm) support for reading Terraform state with workspace-aware paths, authentication, retries, and client caching.
  • Documentation

    • Added detailed docs and a blog post covering Azure backend usage, examples, migration guidance, and “Try It Now” steps.
  • Improvements

    • Clearer permission/not-found reporting and added Azure-specific error signals for more precise error handling.
  • Tests

    • Extensive unit and integration tests plus Azure credential precondition checks.
  • Chores

    • Updated .gitignore with developer tool patterns.
test(auth): Increase auth test coverage from 6% to 80% with mock provider @osterman (#1702) ## what - Add comprehensive unit and integration tests for Atmos auth system using the existing mock provider - Increase test coverage from **6% to ~80%** (target: 80-90% ✅) - Add regression tests to prevent recurrence of user-reported browser authentication issue - Achieve **100% coverage** for mock provider implementation

why

  • Current auth test coverage was critically low (6%), making it difficult to catch bugs
  • User complaint (Bogdan) about browser authentication triggering on every command needed verification and regression protection
  • Mock provider was implemented but had zero test coverage
  • Need confidence that auth system works correctly without requiring real cloud credentials

Coverage Improvements

Package Before After Improvement
pkg/auth 6.2% 84.6% +78.4pp
pkg/auth/providers/mock 0% 100.0% +100pp
pkg/auth/utils 0% 100.0% +100pp
pkg/auth/validation 0% 90.0% +90pp
pkg/auth/list 0% 89.5% +89.5pp
pkg/auth/cloud/aws 0% 79.2% +79.2pp
pkg/auth/providers/github 0% 78.3% +78.3pp
pkg/auth/factory 0% 77.8% +77.8pp
pkg/auth/credentials 0% 75.8% +75.8pp
pkg/auth/providers/aws 0% 67.8% +67.8pp
pkg/auth/identities/aws 2.3% 62.5% +60.2pp

Overall: ~6% → ~80%

Key Additions

1. Mock Provider Unit Tests (100% coverage)

  • pkg/auth/providers/mock/provider_test.go - 15 comprehensive tests
  • pkg/auth/providers/mock/identity_test.go - 13 comprehensive tests
  • Tests cover: authentication, expiration, concurrency, interface compliance

2. Credential Caching Regression Tests

  • cmd/auth_caching_test.go - 4 test functions with multiple subtests
  • Verifies credentials are cached after login and reused
  • Ensures fast execution (< 2s) vs browser auth (5-30s)
  • Tests multi-identity scenarios

3. Integration Test Scenarios

  • tests/test-cases/auth-mock.yaml - 20+ test scenarios
  • Auth login, whoami, env, exec, list, logout commands
  • Multiple output formats (json, bash, dotenv)
  • Error handling and edge cases

User Issue: Browser Auth on Every Command

Status: LIKELY FIXED

The issue where browser authentication was triggered on every command appears to have been resolved by recent PRs (#1655, #1653, #1640). This PR adds comprehensive regression tests to:

  1. Verify credentials are cached after authentication
  2. Ensure subsequent commands use cached credentials
  3. Confirm fast execution without browser prompts
  4. Prevent regression of this issue

Testing

# Run mock provider tests
$ go test ./pkg/auth/providers/mock/... -v
=== RUN   TestNewProvider
=== RUN   TestProvider_Authenticate
=== RUN   TestProvider_Concurrency
... 28 tests PASS
coverage: 100.0% of statements

# Run auth package tests
$ go test -cover ./pkg/auth/...
pkg/auth: 84.6% coverage ✅
pkg/auth/providers/mock: 100% coverage ✅
pkg/auth/utils: 100% coverage ✅
... all passing

Benefits

  • No cloud credentials needed for auth testing
  • Fast test execution (milliseconds vs seconds)
  • Deterministic results (fixed expiration dates)
  • CI/CD ready (no secrets required)
  • Regression protection for caching issue
  • 80% coverage meets industry standards

references

  • User complaint: Bogdan reported browser auth on every command
  • Related PRs: #1655, #1653, #1640 (auth improvements)
  • Mock provider enables testing without cloud credentials

🚀 Enhancements

test: Improve test coverage for keyring fallback to 78.4% @osterman (#1705) ## what - Add comprehensive unit tests for no-op keyring and system keyring functionality - Improve test coverage from 71.2% to 78.4% (+7.2 percentage points) - Add Validate() method to test credential types to satisfy ICredentials interface

why

  • Ensure critical business logic is properly tested (cache management, expiration checking, error handling)
  • Meet 80% test coverage target for new features
  • Prevent regressions in keyring fallback behavior introduced in bde37e334

references

  • Related to commit bde37e334 which introduced graceful keychain fallback for containerized environments
  • Implements test requirements from docs/prd/keyring-fallback-containerized-environments.md

Test Coverage Improvements

Starting Coverage: 71.2%
Final Coverage: 78.4%
Improvement: +7.2 percentage points

Tests Added (8 new test functions):

  1. TestNoopKeyringStore_ValidCache - Tests cache hit with valid credentials
  2. TestNoopKeyringStore_ExpiredInCache - Tests cache hit with expired credentials
  3. TestNoopKeyringStore_StoreWithMockCredentials - Tests storing mock credentials
  4. TestNoopKeyringStore_ExpirationWarning - Tests expiration warning logic
  5. TestSystemKeyringStore_GetAny - Tests retrieving arbitrary data from system keyring
  6. TestSystemKeyringStore_GetAny_NotFound - Tests GetAny error handling
  7. TestSystemKeyringStore_SetAny - Tests storing arbitrary data types
  8. TestNewKeyringAuthStore - Tests deprecated backward-compatible function

Coverage by Function:

File Function Before After Improvement
keyring_noop.go Retrieve() 36.8% 57.9% +21.1%
keyring_system.go GetAny() 0% 85.7% +85.7%
keyring_system.go SetAny() 0% 71.4% +71.4%
store.go NewKeyringAuthStore() 0% 100% +100%

Remaining Uncovered (1.6% to reach 80%):

The uncovered code paths require real AWS credentials and live AWS STS API calls:

  • AWS credential validation success paths (lines 79-95 in Retrieve())
  • AWS STS GetCallerIdentity success (lines 152-168 in validateAWSCredentials())

These are integration-level scenarios better suited for E2E tests with real AWS infrastructure rather than unit tests.

What We Test

Validation failure path - AWS SDK without credentials
Cache behavior - Hits, misses, expiration, staleness
Error handling - Expired/missing credentials
Storage operations - Store, Retrieve, Delete, List
GetAny/SetAny - Arbitrary data storage for all keyring types
Backward compatibility - Deprecated functions

Don't miss a new atmos release

NewReleases is sending notifications on new releases.