Khi học và thực hành Azure DevOps với free tier, có thể bạn sẽ gặp lỗi quen thuộc:
“No hosted parallelism has been purchased or granted”
Lỗi này nghĩa là bạn không có quyền dùng cloud agent miễn phí, nên pipeline không thể chạy được.
Về lý thuyết, bạn có thể gửi đơn xin Microsoft cấp quyền miễn phí — nhưng quá trình này mất thời gian và không đảm bảo được duyệt ngay.
Vì thế, cách đơn giản và chủ động nhất là tự tạo agent của riêng mình trên máy cá nhân. Không chỉ giúp bạn fix được error này, mà bạn còn có nhiều cơ hội:
- Tùy chỉnh môi trường build theo ý muốn
- Học sâu hơn về cách hoạt động của CI/CD
- Tiết kiệm thời gian khi thử nghiệm và học DevOps
Trong bài này, mình sẽ hướng dẫn bạn chi tiết cách thiết lập CI trên máy cá nhân (self-hosted agent), cấu hình pipeline YAML, và chạy script bằng Bash — từ A đến Z.
Tạo Personal Access Token (PAT)
Trước khi cấu hình agent, bạn cần có PAT – Personal Access Token để Azure DevOps xác nhận quyền truy cập của bạn.
PAT đóng vai trò như “chìa khóa” giúp agent của bạn kết nối an toàn tới tổ chức Azure DevOps.
Cách tạo PAT:
- Trong Azure DevOps, chọn User Settings→ Personal access tokens
- Chọn + New Token
- Nhập thông tin:
- Name: LocalAgentToken (hoặc tên tùy chọn)
- Organization: chọn đúng tổ chức của bạn
- Expiration: 90 ngày hoặc 1 năm (tùy nhu cầu)
- Scopes:
- Agent Pools (Read & manage)
- Build (Read & execute)
Nhấn Create, sau đó sao chép token ngay lập tức – bạn sẽ không xem lại được sau khi rời trang.
⚠️ Lưu ý: Giữ PAT ở nơi an toàn, tuyệt đối không commit vào Git hoặc chia sẻ công khai.
Setup new agent
Agent Pool giúp bạn dễ quản lý nhiều agent sau này, đặc biệt nếu bạn có nhiều dự án hoặc nhiều máy build khác nhau.
- Trong Azure DevOps, truy cập Organization Settings → Agent Pools
- Chọn Add Agent
- Trong cửa sổ Get the agent, bấm Download the agent.
💡 Một Agent Pool có thể chứa nhiều agent — mỗi agent là một máy chạy pipeline.
Tạo 1 agent mới
Sau khi download xong, bạn gõ lệnh:
PS C:\> mkdir agent ; cd agent
PS C:\agent> Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::ExtractToDirectory("$HOME\Downloads\vsts-agent-win-x64-4.261.0.zip", "$PWD")
Nếu bạn sử dụng ổ D: (hoặc thư mục khác), bạn có thể tự giải nén file ZIP của agent thủ công mà không cần dùng lệnh PowerShell. Chỉ cần giải nén vào thư mục mà bạn muốn đặt agent, ví dụ D:\agent.
Configure agent
PS C:\agent> .\config.cmd
Hệ thống sẽ hỏi:
Enter server URL > https://dev.azure.com/<your_org>
Enter authentication type (press enter for PAT) > PAT
Enter personal access token > [paste token here]
Khi cấu hình agent (bằng config.cmd hoặc config.sh), bạn có thể đặt tên riêng cho agent, ví dụ MyLocalAgent hoặc Agent-DotNet. Tên này rất quan trọng, vì nó sẽ được dùng trong file YAML pipeline để chỉ định agent cụ thể mà pipeline cần chạy:
pool:
name: MyAgentPool
demands:
- agent.name -equals MyLocalAgent
Chạy Agent ở Interactive Mode
Nếu bạn chưa đăng ký agent chạy dưới dạng service, bạn có thể chạy trực tiếp bằng lệnh sau trong PowerShell hoặc Command Prompt:
PS C:\agent> .\run.cmd
Agent lúc này sẽ bắt đầu lắng nghe các job từ Azure DevOps.
Dưới đây là file Azure pipeline.yaml đã được chỉnh sửa để chạy trên self hosted agent (tiếp theo Part 1)
trigger:
- main
pool:
name: Default
demands:
- docker
- Agent.Name -equals MySelfHostedAgent-ABT
variables:
buildConfiguration: 'Release'
jobs:
- job: BuildDotNetAlpine
displayName: 'Build C# Project (Debian/Ubuntu image)'
container: anbinhtrong/sdk9-node:alpine
steps:
- bash: |
echo "--- Verify Node.js Environment ---" # Start verification log
echo "Node Version:"
node --version # Check Node.js version
echo "NPM Version:"
npm --version # Check NPM version
echo "-----------------------------------"
displayName: '0. Verify Node.js and NPM'
#apt-get update # Update package list
#apt-get install -y nodejs npm # Install Node.js and npm
#displayName: '0. Install Node.js Dependencies'
- bash: dotnet restore
displayName: '1. Restore Dependencies'
# Specify the directory containing your .csproj file
workingDirectory: 'HelloWorldApp'
# 2. Build the C# Application
- bash: dotnet build --configuration $(buildConfiguration) --no-restore
displayName: '2. Build Project'
# '--no-restore' ensures we use the packages restored in the previous step
workingDirectory: 'HelloWorldApp'
# 3. Publish (Compile output files to a ready-to-deploy folder)
- task: DotNetCoreCLI@2
displayName: '3. Publish Application'
inputs:
command: 'publish'
publishWebProjects: false
projects: 'HelloWorldApp/HelloWorldApp.csproj'
# The output path, $(Build.ArtifactStagingDirectory), is the temp location for Artifacts
arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
# 4. Upload the Artifact
- task: PublishBuildArtifacts@1
displayName: '4. Upload Artifact: drop'
inputs:
pathToPublish: '$(Build.ArtifactStagingDirectory)' # Source folder
artifactName: 'drop' # Name of the artifact
Nhận xét
Đăng nhận xét