Native Azure Authentication Support
We're thrilled to announce native Azure authentication support in Atmos! You can now authenticate to Azure using atmos auth login with device code flow, OIDC, and service principals - working identically to az login with full Terraform provider compatibility.
What's New
Atmos now provides first-class Azure authentication with three authentication methods:
- Device Code Flow: Browser-based authentication for interactive developer sessions
- OIDC: Workload identity for GitHub Actions, GitLab CI, and Azure DevOps pipelines
- Service Principals: Client credential authentication for automation and service accounts
All authentication methods write credentials to the Azure CLI MSAL cache (~/.azure/msal_token_cache.json), ensuring 100% compatibility with Terraform's Azure providers: azurerm, azuread, and azapi.
Quick Start
Configure Azure device code authentication in your atmos.yaml:
auth:
providers:
azure-dev:
kind: azure/device-code
tenant_id: "12345678-1234-1234-1234-123456789012"
subscription_id: "87654321-4321-4321-4321-210987654321"
location: "eastus"
identities:
azure-dev-subscription:
default: true
kind: azure/subscription
via:
provider: azure-dev
principal:
subscription_id: "87654321-4321-4321-4321-210987654321"
location: "eastus"
Then authenticate:
atmos auth login
Atmos will:
- Display a device code and verification URL
- Open your browser to https://microsoft.com/devicelogin
- Prompt you to enter the code and sign in
- Cache credentials for all Azure providers
Now you can use Terraform with Azure:
atmos terraform plan my-component -s my-stack
atmos terraform apply my-component -s my-stack
Why This Matters
Works Exactly Like az login
Atmos Azure authentication is designed to work identically to az login. When you run atmos auth login, it:
- Writes credentials to
~/.azure/msal_token_cache.json(Azure CLI MSAL cache) - Updates
~/.azure/azureProfile.jsonwith subscription configuration - Sets
ARM_USE_CLI=truefor Terraform providers - Provides all three token scopes required for full Azure functionality:
https://management.azure.com/.default(Azure Resource Manager)https://graph.microsoft.com/.default(Azure AD operations)https://vault.azure.net/.default(Azure KeyVault operations)
This means your existing Terraform code works without any changes - Atmos authentication is a drop-in replacement for az login.
Full Terraform Provider Compatibility
All three major Terraform Azure providers work seamlessly:
azurerm Provider - Including KeyVault operations:
provider "azurerm" {
features {}
# Atmos automatically sets ARM_USE_CLI=true
}
resource "azurerm_key_vault" "example" {
name = "my-keyvault"
location = "eastus"
# KeyVault operations work because Atmos provides KeyVault token scope
}
azuread Provider - For Azure Active Directory:
provider "azuread" {
# Uses Graph API token from Atmos
}
resource "azuread_group" "example" {
display_name = "My Group"
security_enabled = true
}
azapi Provider - Alternative Azure management:
provider "azapi" {
# Works with Atmos authentication out of the box
}
CI/CD with OIDC
Use workload identity federation for passwordless authentication in pipelines:
auth:
providers:
azure-ci:
kind: azure/oidc
tenant_id: "YOUR_TENANT_ID"
client_id: "YOUR_APP_CLIENT_ID"
subscription_id: "YOUR_SUBSCRIPTION_ID"
identities:
azure-prod-ci:
kind: azure/subscription
via:
provider: azure-ci
principal:
subscription_id: "YOUR_SUBSCRIPTION_ID"
GitHub Actions Example:
name: Deploy Infrastructure
on:
push:
branches: [main]
permissions:
id-token: write # Required for OIDC
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Atmos
uses: cloudposse/github-action-setup-atmos@v2
- name: Authenticate to Azure
run: atmos auth login --identity azure-prod-ci
env:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Deploy
run: atmos terraform apply my-component -s prod
Service Principals for Automation
Service principals provide non-interactive authentication for automated workflows, CI/CD pipelines, and scheduled jobs:
auth:
providers:
azure-automation:
kind: azure/service-principal
tenant_id: "YOUR_TENANT_ID"
client_id: "YOUR_SERVICE_PRINCIPAL_CLIENT_ID"
subscription_id: "YOUR_SUBSCRIPTION_ID"
location: "eastus"
identities:
azure-automation-prod:
kind: azure/subscription
via:
provider: azure-automation
principal:
subscription_id: "YOUR_SUBSCRIPTION_ID"
Create a service principal:
# Create service principal and assign Contributor role
az ad sp create-for-rbac \
--name "atmos-automation" \
--role Contributor \
--scopes /subscriptions/YOUR_SUBSCRIPTION_ID
# Output includes:
# {
# "appId": "YOUR_CLIENT_ID",
# "displayName": "atmos-automation",
# "password": "YOUR_CLIENT_SECRET",
# "tenant": "YOUR_TENANT_ID"
# }
Authenticate using environment variables:
# Set credentials in environment
export AZURE_CLIENT_ID="YOUR_CLIENT_ID"
export AZURE_CLIENT_SECRET="YOUR_CLIENT_SECRET"
export AZURE_TENANT_ID="YOUR_TENANT_ID"
export AZURE_SUBSCRIPTION_ID="YOUR_SUBSCRIPTION_ID"
# Authenticate
atmos auth login --identity azure-automation-prod
# Run Terraform
atmos terraform apply my-component -s prod
Common use cases:
- Scheduled Jobs: Cron jobs or Azure DevOps scheduled pipelines
- CI/CD Pipelines: Jenkins, GitLab CI, CircleCI (when OIDC not available)
- Automation Scripts: Python/Go scripts for infrastructure management
- Multi-tenant SaaS: Isolated credentials per customer environment
Security best practices:
- Store
client_secretin secure secret management (Azure Key Vault, HashiCorp Vault) - Use least-privilege RBAC roles (avoid Owner, prefer specific roles like Network Contributor)
- Rotate credentials regularly (90-day rotation recommended)
- Use certificate-based authentication for production (more secure than secrets)
- Prefer OIDC over service principals when available (passwordless)
Multi-Subscription Workflows
Work with multiple Azure subscriptions seamlessly:
auth:
providers:
azure-main:
kind: azure/device-code
tenant_id: "YOUR_TENANT_ID"
subscription_id: "DEV_SUBSCRIPTION_ID"
identities:
azure-dev:
kind: azure/subscription
via:
provider: azure-main
principal:
subscription_id: "DEV_SUBSCRIPTION_ID"
location: "eastus"
azure-staging:
kind: azure/subscription
via:
provider: azure-main
principal:
subscription_id: "STAGING_SUBSCRIPTION_ID"
location: "westus"
azure-prod:
kind: azure/subscription
via:
provider: azure-main
principal:
subscription_id: "PROD_SUBSCRIPTION_ID"
location: "eastus2"
Switch between subscriptions effortlessly:
# Deploy to dev
atmos terraform apply my-component -s dev --identity azure-dev
# Deploy to staging
atmos terraform apply my-component -s staging --identity azure-staging
# Deploy to prod
atmos terraform apply my-component -s prod --identity azure-prod
Implementation Details
Complete Token Support
One of the key challenges in implementing Azure authentication was ensuring we provide all the token scopes that az login provides. Many implementations only provide the Azure Resource Manager token, which breaks KeyVault operations.
Atmos Azure authentication provides all three required token scopes:
-
Management Token (
https://management.azure.com/.default)- Used by: azurerm, azapi providers
- Purpose: Azure Resource Manager operations (VMs, networks, storage, etc.)
-
Graph API Token (
https://graph.microsoft.com/.default)- Used by: azuread provider
- Purpose: Azure Active Directory operations (users, groups, service principals)
-
KeyVault Token (
https://vault.azure.net/.default)- Used by: azurerm provider for KeyVault operations
- Purpose: Azure KeyVault secrets, keys, and certificates management
This comprehensive token support ensures that all Terraform resources work correctly, including KeyVault certificate contacts, secret management, and AD group operations.
MSAL Cache Compatibility
Atmos writes credentials to the same MSAL cache format that the Azure CLI uses, with proper token entries for each scope:
{
"AccessToken": {
"homeAccountId-login.microsoftonline.com-accesstoken-clientId-tenantId-https://management.azure.com/.default": {
"credential_type": "AccessToken",
"secret": "eyJ0eXAi...",
"home_account_id": "objectId.tenantId",
"environment": "login.microsoftonline.com",
"client_id": "04b07795-8ddb-461a-bbee-02f9e1bf7b46",
"target": "https://management.azure.com/.default",
"token_type": "Bearer"
},
"homeAccountId-login.microsoftonline.com-accesstoken-clientId-tenantId-https://graph.microsoft.com/.default": {
...
},
"homeAccountId-login.microsoftonline.com-accesstoken-clientId-tenantId-https://vault.azure.net/.default": {
...
}
},
"Account": {
...
}
}
This ensures perfect compatibility with Terraform providers that read from the Azure CLI credential cache.
Migration from az login
Already using az login? Atmos is a drop-in replacement:
Before:
az login
az account set --subscription "YOUR_SUBSCRIPTION_ID"
terraform apply
After:
atmos auth login --identity azure-dev
atmos terraform apply my-component -s my-stack
Both write to the same files, so your Terraform code needs zero changes.
Security Features
Secure Credential Storage
- Credentials are cached in your system keyring (Keychain on macOS, Secret Service on Linux, Credential Manager on Windows)
- Tokens are also written to Azure CLI MSAL cache for Terraform compatibility
- Both storages are secured by your operating system
Token Expiration Handling
- Azure tokens typically expire after 1 hour
- Atmos automatically caches valid tokens and reuses them
- Re-authenticate when expired:
atmos auth login - Check status anytime:
atmos auth whoami
Least Privilege Access
Configure appropriate RBAC roles for your identities:
# Example: Grant Contributor role to a service principal
az role assignment create \
--assignee YOUR_APP_CLIENT_ID \
--role Contributor \
--scope /subscriptions/YOUR_SUBSCRIPTION_ID
Documentation
We've created comprehensive documentation for Azure authentication:
- Azure Authentication Guide - Complete tutorial covering all authentication methods
- Auth Login Command - Updated with Azure examples
- Auth Commands Reference - All authentication commands
What's Next
This is just the beginning of Azure support in Atmos. Future enhancements include:
- Azure Managed Identity support
- Azure Government Cloud support
- Azure CLI credential migration tools
- Enhanced Azure-specific debugging and logging
Try It Out
Update to the latest version of Atmos and try Azure authentication:
# Configure Azure authentication in atmos.yaml
# (See examples above)
# Authenticate to Azure
atmos auth login
# Check your authentication status
atmos auth whoami
# Use with Terraform
atmos terraform plan my-component -s my-stack
# List all configured identities
atmos auth list
# Get environment variables for an identity
atmos auth env --identity azure-dev
# Spawn a shell with Azure credentials
atmos auth shell azure-dev
We're excited to bring Azure authentication to Atmos and look forward to seeing how you use it in your multi-cloud infrastructure workflows!
Feedback
Have feedback or issues? Please let us know:
Special thanks to the community for requesting Azure support and providing feedback during development!
