Back to blog

Di Chuyển Trạng Thái Pulumi từ Pulumi Cloud sang Azure Blob Storage

pulumiazureinfrastructuredevopsiac
Di Chuyển Trạng Thái Pulumi từ Pulumi Cloud sang Azure Blob Storage

Di chuyển trạng thái Pulumi từ dịch vụ cloud sang Azure Blob Storage mang lại cho bạn nhiều quyền kiểm soát hơn, chi phí thấp hơn và tích hợp CI/CD chặt chẽ hơn. Đây là mọi thứ bạn cần biết về quá trình di chuyển.

Tại Sao Nên Di Chuyển?

  • Chi phí: Azure Blob Storage rẻ hơn đáng kể so với Pulumi Cloud cho lưu trữ trạng thái
  • Chủ quyền dữ liệu: Giữ trạng thái hạ tầng của bạn trong subscription Azure riêng của bạn
  • Tích hợp CI/CD: Tích hợp dễ dàng hơn với Azure DevOps pipelines
  • Không phụ thuộc bên ngoài: Loại bỏ nhu cầu về access token Pulumi Cloud

Điều Kiện Tiên Quyết

Trước khi bắt đầu, hãy đảm bảo bạn có:

  • Azure CLI đã cài đặt và đăng nhập (az login)
  • Pulumi CLI đã cài đặt
  • jq để xử lý JSON
  • Quyền truy cập vào cả Pulumi Cloud và Azure subscription
  • PULUMI_ACCESS_TOKEN để truy cập Pulumi Cloud

Tổng Quan Di Chuyển

Quá trình di chuyển bao gồm ba bước quan trọng:

  1. Thiết lập backend Azure Blob Storage
  2. Di chuyển file trạng thái
  3. Mã hóa lại config secret

⚠️ QUAN TRỌNG: Script di chuyển chỉ di chuyển file trạng thái (tài nguyên). Config secret được mã hóa bằng khóa của Pulumi Cloud và phải được thiết lập lại với passphrase mới của bạn.

Bước 1: Thiết Lập Azure Blob Storage

Tạo các tài nguyên Azure cần thiết để lưu trữ trạng thái Pulumi:

./setup-pulumi-azure-backend.sh

Điều này tạo ra:

  • Resource Group (mặc định: rg-pulumi-state)
  • Storage Account (tên duy nhất toàn cầu)
  • Blob Container (mặc định: pulumi-state)

Lưu các giá trị này—bạn sẽ cần chúng cho các bước tiếp theo:

  • Tên Storage Account
  • Khóa Storage Account
  • Tên Container

Bước 2: Di Chuyển Trạng Thái Pulumi

2.1 Thiết Lập Biến Môi Trường

Đầu tiên, lấy khóa Azure Storage Account của bạn:

# Đăng nhập vào Azure CLI
az login
 
# Lấy khóa storage account
AZURE_STORAGE_KEY=$(az storage account keys list \
  --account-name <your-storage-account> \
  --resource-group <your-resource-group> \
  --query '[0].value' -o tsv)
 
# Xác minh khóa đã được lấy
echo "Storage key retrieved: ${AZURE_STORAGE_KEY:0:10}..."

Sau đó thiết lập tất cả các biến môi trường cần thiết:

export AZURE_STORAGE_ACCOUNT=<your-storage-account>
export AZURE_STORAGE_KEY="$AZURE_STORAGE_KEY"
export AZURE_BLOB_CONTAINER=pulumi-state
export PULUMI_CONFIG_PASSPHRASE=<choose-a-strong-passphrase>
export PULUMI_ACCESS_TOKEN=<your-pulumi-cloud-token>

🔑 Nhớ passphrase—bạn sẽ cần nó cho tất cả các thao tác Pulumi trong tương lai!

2.2 Chạy Script Di Chuyển

./migrate-pulumi-to-azure-blob.sh

Khi được nhắc, nhập tên stack đầy đủ từ Pulumi Cloud:

Stack name: <organization>/<project>/<stack>
# Ví dụ: myorg/my-infrastructure/dev

Script sẽ:

  1. Export trạng thái từ Pulumi Cloud (với các secret đã giải mã)
  2. Tạo stack mới trong Azure Blob Storage với mã hóa passphrase
  3. Import trạng thái với các secret được mã hóa lại
  4. Lưu credentials vào .env.pulumi

2.3 Xác Minh Di Chuyển

Sau khi di chuyển, xác minh trạng thái đã được import đúng:

# Tải credentials và login
set -a && source .env.pulumi && set +a && pulumi login "azblob://$AZURE_BLOB_CONTAINER"
 
# Chọn stack và xác minh
pulumi stack select dev
pulumi stack --show-urns

Bước 3: Mã Hóa Lại Config (QUAN TRỌNG)

⚠️ Bước này là bắt buộc! File Pulumi.{stack}.yaml chứa các secret được mã hóa bằng mã hóa của Pulumi Cloud. Chúng không thể được giải mã bằng passphrase mới.

3.1 Kiểm Tra Trạng Thái Hiện Tại

Chạy pulumi preview để xem có thay đổi không mong muốn nào không:

pulumi preview

Cập nhật an toàn (bình thường sau khi di chuyển):

  • [diff: ~osProfile] trên VirtualMachine—mật khẩu được mã hóa lại với passphrase mới
  • Mật khẩu thực tế không thay đổi, chỉ thay đổi mã hóa
  • Chạy pulumi up sẽ cập nhật trạng thái mà không sửa đổi VM

Cập nhật không an toàn (cần sửa config):

  • Tài nguyên được đánh dấu để thay thế, đặc biệt với [diff: ~resourceGroupName]
  • Điều này có nghĩa là giá trị config không khớp với tài nguyên đã triển khai
  • KHÔNG tiếp tục—sửa config trước

3.2 Xem Giá Trị Config Hiện Có

Kiểm tra các giá trị tồn tại trong config cũ:

# Xem config đã backup từ quá trình di chuyển
cat .pulumi-backup-*/Pulumi.dev.yaml

Ghi chú tất cả các giá trị, đặc biệt:

  • resourceGroupName (phải khớp với những gì được triển khai trong Azure!)
  • location
  • Giá trị cấu hình không phải secret
  • Azure subscription/tenant ID

3.3 Xóa và Tạo Lại Config

# Xóa file config cũ
rm Pulumi.dev.yaml
 
# Thiết lập giá trị không phải secret
pulumi config set azure-native:subscriptionId "<subscription-id>"
pulumi config set azure-native:tenantId "<tenant-id>"
pulumi config set location "<your-location>"
pulumi config set resourceGroupName "<exact-resource-group-name>"  # Phải khớp với Azure!
 
# Thiết lập giá trị secret
pulumi config set --secret <secret-key-1> "<secret-value-1>"
pulumi config set --secret <secret-key-2> "<secret-value-2>"

🎯 QUAN TRỌNG: resourceGroupName phải khớp chính xác với những gì được triển khai trong Azure. Kiểm tra Azure Portal hoặc chạy az group list để tìm tên chính xác.

3.4 Xác Minh Không Có Thay Đổi Không Mong Muốn

pulumi preview

Kết quả mong đợi:

Resources:
    8 unchanged

Bước 4: Cập Nhật CI/CD Pipeline

4.1 Thêm Biến Pipeline

Trong Azure DevOps, thêm các biến này:

BiếnGiá trịSecret?
pulumiStorageAccountTên storage account của bạnKhông
pulumiBlobContainerpulumi-stateKhông
PULUMI_CONFIG_PASSPHRASEPassphrase của bạnCó

4.2 Cấu Hình Quyền Truy Cập Service Principal

Pipeline sử dụng xác thực service principal để bảo mật tốt hơn:

# Lấy Object ID của service principal
SP_OBJECT_ID="<service-principal-object-id>"
 
# Lấy resource ID của storage account
STORAGE_ACCOUNT_ID=$(az storage account show \
  --name <your-storage-account> \
  --resource-group <your-resource-group> \
  --query id -o tsv)
 
# Gán vai trò "Storage Blob Data Contributor"
az role assignment create \
  --role "Storage Blob Data Contributor" \
  --assignee-object-id "$SP_OBJECT_ID" \
  --assignee-principal-type ServicePrincipal \
  --scope "$STORAGE_ACCOUNT_ID"

4.3 Xóa Các Biến Cũ

Xóa các biến này (không còn cần thiết):

  • PULUMI_ACCESS_TOKEN - Token Pulumi Cloud
  • PULUMI_STORAGE_KEY - Khóa storage account (được thay thế bằng service principal)

4.4 Cấu Hình Pipeline

Pipeline sử dụng service principal từ AzureCLI task:

env:
  AZURE_STORAGE_ACCOUNT: $(pulumiStorageAccount)
  AZURE_CLIENT_ID: $(servicePrincipalId)
  AZURE_CLIENT_SECRET: $(servicePrincipalKey)
  AZURE_TENANT_ID: $(tenantId)
  PULUMI_CONFIG_PASSPHRASE: $(PULUMI_CONFIG_PASSPHRASE)

Đăng nhập với:

pulumi login "azblob://$(pulumiBlobContainer)"

Quy Trình Phát Triển Local

Tùy Chọn 1: Sử Dụng .env.pulumi (Storage Key)

# Tải biến môi trường và login
set -a && source .env.pulumi && set +a && pulumi login "azblob://$AZURE_BLOB_CONTAINER"
 
# Chọn stack của bạn
pulumi stack select dev
 
# Chạy lệnh bình thường
pulumi preview
pulumi up

Tùy Chọn 2: Lấy Storage Key Thủ Công

# Đăng nhập vào Azure CLI
az login
 
# Lấy storage key
export AZURE_STORAGE_ACCOUNT=<your-storage-account-name>
export AZURE_STORAGE_KEY=$(az storage account keys list \
  --account-name $AZURE_STORAGE_ACCOUNT \
  --resource-group rg-pulumi-state \
  --query '[0].value' -o tsv)
 
# Thiết lập các biến khác
export AZURE_BLOB_CONTAINER=pulumi-state
export PULUMI_CONFIG_PASSPHRASE=<your-passphrase>
 
# Đăng nhập và sử dụng Pulumi
pulumi login "azblob://$AZURE_BLOB_CONTAINER"

Tùy Chọn 3: Sử Dụng Service Principal

# Thiết lập credentials service principal
export AZURE_STORAGE_ACCOUNT=<your-storage-account-name>
export AZURE_CLIENT_ID=<your-sp-client-id>
export AZURE_CLIENT_SECRET=<your-sp-secret>
export AZURE_TENANT_ID=<your-tenant-id>
export PULUMI_CONFIG_PASSPHRASE=<your-passphrase>
 
# Đăng nhập và sử dụng Pulumi
pulumi login "azblob://pulumi-state"

Xử Lý Sự Cố

"7 to replace" - Tài Nguyên Đang Được Tạo Lại

Nguyên nhân: Giá trị config không khớp với tài nguyên đã triển khai (thường là resourceGroupName).

Giải pháp:

  1. Chạy pulumi preview --diff để xem chính xác điều gì khác biệt
  2. Kiểm tra tên tài nguyên thực tế trong Azure Portal
  3. Cập nhật config để khớp: pulumi config set resourceGroupName "<correct-name>"

Lỗi "unable to open bucket azblob://..."

Nguyên nhân: Thiếu biến môi trường.

Giải pháp:

set -a && source .env.pulumi && set +a
# Hoặc export biến thủ công

"could not find access token for https://api.pulumi.com"

Nguyên nhân: File trạng thái vẫn tham chiếu đến secrets manager của Pulumi Cloud.

Giải pháp: Chạy lại script di chuyển hoặc cập nhật thủ công phần secrets_providers của trạng thái.

Secret Không Thể Được Giải Mã

Nguyên nhân: Cố gắng sử dụng file config cũ với passphrase mới.

Giải pháp: Xóa Pulumi.{stack}.yaml cũ và thiết lập lại tất cả giá trị config.

Phương Thức Xác Thực

CI/CD Pipeline

  • Sử dụng xác thực Service Principal (dựa trên RBAC)
  • An toàn hơn với audit trail tốt hơn
  • Yêu cầu vai trò "Storage Blob Data Contributor"
  • Không cần storage key trong biến pipeline

Script Di Chuyển

  • Sử dụng xác thực Storage Account Key
  • Đơn giản hơn cho các thao tác di chuyển một lần
  • Key được lấy tự động qua Azure CLI
  • Được lưu vào .env.pulumi cho phát triển local

Phát Triển Local

  • Có thể sử dụng cả hai phương thức
  • .env.pulumi chứa storage key theo mặc định
  • Chuyển sang service principal bằng cách thiết lập AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID

Thực Hành Bảo Mật Tốt Nhất

  • ✅ Không bao giờ commit .env.pulumi—nó chứa secret (thêm vào .gitignore)
  • ✅ Lưu trữ passphrase an toàn—cần thiết cho tất cả thao tác
  • ✅ Sử dụng service principal cho CI/CD—bảo mật và audit trail tốt hơn
  • ✅ Xoay vòng storage key định kỳ nếu sử dụng xác thực dựa trên key
  • ✅ Sử dụng storage account riêng cho các môi trường khác nhau

Dọn Dẹp (Tùy Chọn)

Sau khi xác minh mọi thứ hoạt động, xóa stack khỏi Pulumi Cloud:

# Đăng nhập vào Pulumi Cloud
pulumi login
 
# Chọn và xóa stack cũ
pulumi stack select <org>/<project>/<stack>
pulumi stack rm <org>/<project>/<stack> --yes

Kết Luận

Di chuyển từ Pulumi Cloud sang Azure Blob Storage mang lại cho bạn nhiều quyền kiểm soát hơn đối với trạng thái hạ tầng của mình đồng thời giảm chi phí. Điều quan trọng là hiểu rằng config secret cần được mã hóa lại sau khi di chuyển. Làm theo các bước cẩn thận, đặc biệt là việc mã hóa lại config, và bạn sẽ có một quá trình chuyển đổi suôn sẻ sang quản lý trạng thái tự lưu trữ.

Nhớ giữ passphrase của bạn an toàn và ghi lại lựa chọn phương thức xác thực của bạn cho nhóm của bạn!

📬 Đăng ký nhận bản tin

Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.

💬 Comments

Đăng nhập để bình luận

Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.