On this page
CI/CD Integration
CI/CD Integration
Learn how to integrate Entra Auth Cli into your CI/CD pipelines for automated authentication.
GitHub Actions
Basic Example
name: Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Entra Auth Cli
run: |
dotnet tool install --global EntraAuthCli
- name: Create Profile
env:
CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
run: |
# Create profile non-interactively
cat > profile.json <<EOF
{
"name": "cicd",
"clientId": "$CLIENT_ID",
"tenantId": "$TENANT_ID",
"scope": "https://management.azure.com/.default",
"useClientSecret": true
}
EOF
entra-auth-cli config import -f profile.json
# Store secret (implementation depends on tool capabilities)
- name: Deploy to Azure
run: |
TOKEN=$(entra-auth-cli get-token -p cicd --silent)
# Use token for deployment
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d @deployment.json \
"https://management.azure.com/..."
With Matrix Strategy
name: Multi-Environment Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
strategy:
matrix:
environment: [dev, staging, prod]
steps:
- uses: actions/checkout@v3
- name: Setup Entra Auth Cli
run: dotnet tool install --global EntraAuthCli
- name: Deploy to ${{ matrix.environment }}
env:
CLIENT_ID: ${{ secrets[format('{0}_CLIENT_ID', matrix.environment)] }}
TENANT_ID: ${{ secrets[format('{0}_TENANT_ID', matrix.environment)] }}
CLIENT_SECRET: ${{ secrets[format('{0}_CLIENT_SECRET', matrix.environment)] }}
run: |
# Create environment-specific profile
entra-auth-cli config create --name ${{ matrix.environment }} \
--client-id "$CLIENT_ID" \
--tenant-id "$TENANT_ID"
TOKEN=$(entra-auth-cli get-token -p ${{ matrix.environment }} --silent)
./deploy.sh "$TOKEN" "${{ matrix.environment }}"
Azure Pipelines
Basic Example
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- script: |
dotnet tool install --global EntraAuthCli
displayName: 'Install Entra Auth Cli'
- task: AzureCLI@2
inputs:
azureSubscription: 'MyServiceConnection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# Create profile
entra-auth-cli config create --non-interactive \
--name cicd \
--client-id $(ClientId) \
--tenant-id $(TenantId) \
--client-secret $(ClientSecret) \
--scope "https://management.azure.com/.default"
# Get token
TOKEN=$(entra-auth-cli get-token -p cicd --silent)
# Deploy
./deploy.sh "$TOKEN"
With Deployment Job
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
stages:
- stage: Build
jobs:
- job: BuildJob
steps:
- script: dotnet build
displayName: 'Build Application'
- stage: Deploy
dependsOn: Build
jobs:
- deployment: DeployJob
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- script: dotnet tool install --global EntraAuthCli
displayName: 'Install CLI'
- script: |
entra-auth-cli config create --name prod \
--client-id $(ClientId) \
--tenant-id $(TenantId)
TOKEN=$(entra-auth-cli get-token -p prod --silent)
./deploy-to-production.sh "$TOKEN"
displayName: 'Deploy'
GitLab CI
stages:
- deploy
deploy:
stage: deploy
image: mcr.microsoft.com/dotnet/sdk:8.0
script:
- dotnet tool install --global EntraAuthCli
- export PATH="$PATH:/root/.dotnet/tools"
# Create profile
- |
cat > profile.json <<EOF
{
"name": "gitlab-ci",
"clientId": "$AZURE_CLIENT_ID",
"tenantId": "$AZURE_TENANT_ID",
"scope": "https://management.azure.com/.default"
}
EOF
- entra-auth-cli config import -f profile.json
# Deploy
- TOKEN=$(entra-auth-cli get-token -p gitlab-ci --silent)
- ./deploy.sh "$TOKEN"
only:
- main
Jenkins
pipeline {
agent any
environment {
CLIENT_ID = credentials('azure-client-id')
TENANT_ID = credentials('azure-tenant-id')
CLIENT_SECRET = credentials('azure-client-secret')
}
stages {
stage('Setup') {
steps {
sh 'dotnet tool install --global EntraAuthCli'
}
}
stage('Deploy') {
steps {
sh '''
# Create profile
entra-auth-cli config create --name jenkins \
--client-id "$CLIENT_ID" \
--tenant-id "$TENANT_ID"
# Get token
TOKEN=$(entra-auth-cli get-token -p jenkins --silent)
# Deploy
./deploy.sh "$TOKEN"
'''
}
}
}
}
Best Practices
Use Service Principals
Create dedicated service principals for CI/CD:
az ad sp create-for-rbac --name "cicd-deployment" \
--role "Contributor" \
--scopes "/subscriptions/YOUR_SUBSCRIPTION_ID"
Store Secrets Securely
- GitHub Actions: Use GitHub Secrets
- Azure Pipelines: Use Variable Groups
- GitLab CI: Use CI/CD Variables
- Jenkins: Use Credentials Plugin
Separate Profiles per Environment
# Create environment-specific profiles
- name: Configure Dev Profile
run: entra-auth-cli config create --name dev ...
- name: Configure Prod Profile
run: entra-auth-cli config create --name prod ...
Use Silent Mode
Always use --silent flag in CI/CD to get clean token output:
TOKEN=$(entra-auth-cli get-token -p cicd --silent)
Validate Tokens
Test token validity before use:
TOKEN=$(entra-auth-cli get-token -p cicd --silent)
if entra-auth-cli inspect <<< "$TOKEN" &>/dev/null; then
echo "Token valid"
# Proceed with deployment
else
echo "Token invalid"
exit 1
fi
Troubleshooting
“Tool not found”
Ensure .NET tools are in PATH:
export PATH="$PATH:$HOME/.dotnet/tools"
“Profile not found”
Profile creation may have failed. Check logs and recreate:
entra-auth-cli config list
entra-auth-cli config create ...
“Authentication failed”
Verify secrets are correctly configured:
echo "Client ID: $CLIENT_ID"
echo "Tenant ID: $TENANT_ID"
# Don't echo secrets!