Pulumi — Infrastructure as Code bằng C# trên .NET 10: Quản lý Cloud như viết phần mềm
Posted on: 4/21/2026 8:21:27 AM
Table of contents
- Tại sao Infrastructure as Code lại quan trọng?
- Pulumi là gì? Kiến trúc tổng quan
- Pulumi vs Terraform vs Bicep: So sánh chi tiết
- Bắt đầu với Pulumi + .NET 10
- Patterns nâng cao cho Production
- Pulumi Neo — AI Agent cho Cloud Engineering
- Kubernetes với Pulumi — Beyond YAML
- CI/CD Integration
- Secrets Management và Security
- Migration từ Terraform sang Pulumi
- Automation API — IaC trong Application Code
- Lộ trình phát triển Pulumi 2026
- Kết luận
Tại sao Infrastructure as Code lại quan trọng?
Trong kỷ nguyên cloud-native, việc quản lý hạ tầng bằng tay qua console là một anti-pattern nghiêm trọng. Một lần click chuột sai trên AWS Console có thể xóa sạch production database. Một thay đổi security group không được track có thể mở cổng cho attacker. Infrastructure as Code (IaC) giải quyết triệt để vấn đề này: mọi thay đổi hạ tầng đều được version control, review, và reproducible.
Tuy nhiên, phần lớn .NET developer vẫn đang phải học thêm HCL (HashiCorp Configuration Language) cho Terraform hoặc Bicep DSL cho Azure — những ngôn ngữ chuyên biệt xa lạ với ecosystem C# quen thuộc. Pulumi thay đổi cuộc chơi: bạn viết infrastructure bằng chính C#, dùng Visual Studio/Rider với IntelliSense, NuGet packages, xUnit tests — mọi thứ bạn đã biết.
Pulumi là gì? Kiến trúc tổng quan
Pulumi là một nền tảng Infrastructure as Code cho phép bạn định nghĩa, deploy và quản lý cloud infrastructure bằng các ngôn ngữ lập trình quen thuộc — TypeScript, Python, Go, Java, và đặc biệt là C# / .NET. Khác với Terraform (dùng HCL) hay Bicep (DSL riêng cho Azure), Pulumi tận dụng toàn bộ sức mạnh của general-purpose programming language.
graph TB
subgraph Developer["Developer Workspace"]
A["C# Program
.NET 10 Project"] --> B["Pulumi SDK
NuGet Packages"]
end
subgraph Engine["Pulumi Engine"]
B --> C["Language Host
dotnet runtime"]
C --> D["Deployment Engine
Resource Graph"]
D --> E["State Backend
Pulumi Cloud / S3 / Azure Blob"]
end
subgraph Providers["Cloud Providers"]
D --> F["AWS Provider"]
D --> G["Azure Native"]
D --> H["Kubernetes"]
D --> I["Cloudflare / GCP / ..."]
end
style A fill:#e94560,stroke:#fff,color:#fff
style D fill:#2c3e50,stroke:#fff,color:#fff
style E fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style F fill:#ff9800,stroke:#fff,color:#fff
style G fill:#0078d4,stroke:#fff,color:#fff
style H fill:#326ce5,stroke:#fff,color:#fff
style I fill:#f48120,stroke:#fff,color:#fff
Điểm mấu chốt
Pulumi không generate Terraform hay ARM template bên dưới. Nó có engine riêng để quản lý resource graph, state, và giao tiếp trực tiếp với cloud provider APIs. Điều này nghĩa là bạn có full control, không bị giới hạn bởi DSL trung gian.
Pulumi vs Terraform vs Bicep: So sánh chi tiết
Đây là câu hỏi mà mọi team DevOps đều phải đối mặt khi chọn IaC tool. Mỗi công cụ có strengths riêng, và lựa chọn phụ thuộc vào context của team.
| Tiêu chí | Pulumi | Terraform | Bicep |
|---|---|---|---|
| Ngôn ngữ | C#, TypeScript, Python, Go, Java | HCL (DSL riêng) | Bicep DSL (Azure-only) |
| Multi-cloud | ✅ AWS, Azure, GCP, K8s, 150+ providers | ✅ 4800+ providers | ❌ Chỉ Azure |
| Testing | xUnit, NUnit, MSTest — unit + integration | Terratest (Go), terraform test | What-if preview, hạn chế |
| IDE support | Full IntelliSense, refactoring, debugging | HCL extension (cơ bản) | VS Code extension (tốt cho Azure) |
| State management | Pulumi Cloud (managed), S3, Azure Blob, local | Terraform Cloud, S3, local | Azure Resource Manager (implicit) |
| Reusability | NuGet packages, OOP, interfaces | Modules (HCL) | Modules (Bicep) |
| Learning curve (.NET dev) | ⭐ Thấp — dùng C# quen thuộc | ⭐⭐⭐ Phải học HCL | ⭐⭐ Phải học Bicep syntax |
| AI Assistant | Pulumi Neo (enterprise agent) | Terraform AI (beta) | Copilot for Azure |
| Open Source | ✅ Apache 2.0 | ⚠️ BSL (OpenTofu fork = true OSS) | ✅ MIT |
Khi nào chọn Pulumi?
Team .NET/C# muốn quản lý multi-cloud infrastructure mà không phải học ngôn ngữ mới. Đặc biệt mạnh khi cần logic phức tạp (loops, conditions, async), testing nghiêm túc, và tái sử dụng code qua NuGet packages. Nếu team đã invest vào Terraform và hạ tầng ổn định, việc migrate có thể không đáng — Pulumi hỗ trợ import từ Terraform state nhưng cost chuyển đổi vẫn tồn tại.
Bắt đầu với Pulumi + .NET 10
Cài đặt và khởi tạo project
Pulumi CLI hoạt động cross-platform trên Windows, macOS, và Linux. Sau khi cài đặt, bạn khởi tạo project C# chỉ với một lệnh:
# Cài Pulumi CLI
curl -fsSL https://get.pulumi.com | sh
# Hoặc trên Windows qua Chocolatey
choco install pulumi
# Khởi tạo project C# cho Azure
pulumi new azure-csharp --name my-infra --stack dev
# Cấu trúc thư mục được tạo:
# my-infra/
# ├── Pulumi.yaml # Project metadata
# ├── Pulumi.dev.yaml # Stack config (dev)
# ├── Program.cs # Entry point
# └── my-infra.csproj # .NET project file
Ví dụ thực tế: Deploy web app lên Azure
Dưới đây là một ví dụ hoàn chỉnh — tạo Resource Group, App Service Plan, và Web App trên Azure, tất cả bằng C# thuần:
using Pulumi;
using Pulumi.AzureNative.Resources;
using Pulumi.AzureNative.Web;
using Pulumi.AzureNative.Web.Inputs;
return await Deployment.RunAsync(() =>
{
var resourceGroup = new ResourceGroup("rg-production", new()
{
ResourceGroupName = "rg-myapp-production",
Location = "southeastasia"
});
var appServicePlan = new AppServicePlan("plan-production", new()
{
ResourceGroupName = resourceGroup.Name,
Kind = "Linux",
Reserved = true,
Sku = new SkuDescriptionArgs
{
Name = "P1v3",
Tier = "PremiumV3"
}
});
var webApp = new WebApp("app-production", new()
{
ResourceGroupName = resourceGroup.Name,
ServerFarmId = appServicePlan.Id,
SiteConfig = new SiteConfigArgs
{
LinuxFxVersion = "DOTNETCORE|10.0",
AlwaysOn = true,
MinTlsVersion = "1.2",
HttpsOnly = true,
AppSettings = new[]
{
new NameValuePairArgs
{
Name = "ASPNETCORE_ENVIRONMENT",
Value = "Production"
}
}
},
HttpsOnly = true
});
return new Dictionary<string, object?>
{
["endpoint"] = webApp.DefaultHostName
.Apply(h => $"https://{h}"),
["resourceGroup"] = resourceGroup.Name
};
});
Nhận thấy sự khác biệt?
Đây là C# thuần túy — var, new(), Dictionary, lambda expressions. Không cần học syntax mới. IntelliSense trong Visual Studio/Rider sẽ auto-complete mọi property, giúp bạn khám phá API mà không cần đọc docs liên tục.
Ví dụ: AWS S3 + CloudFront CDN
Pulumi không giới hạn ở Azure. Đây là ví dụ tạo static website hosting trên AWS với S3 bucket và CloudFront distribution:
using Pulumi;
using Pulumi.Aws.S3;
using Pulumi.Aws.CloudFront;
using Pulumi.Aws.CloudFront.Inputs;
return await Deployment.RunAsync(() =>
{
var bucket = new BucketV2("site-bucket", new()
{
BucketPrefix = "mysite-"
});
var bucketWebsite = new BucketWebsiteConfigurationV2(
"site-config", new()
{
Bucket = bucket.Id,
IndexDocument = new BucketWebsiteConfigurationV2IndexDocumentArgs
{
Suffix = "index.html"
},
ErrorDocument = new BucketWebsiteConfigurationV2ErrorDocumentArgs
{
Key = "404.html"
}
});
var oac = new OriginAccessControl("site-oac", new()
{
OriginAccessControlOriginType = "s3",
SigningBehavior = "always",
SigningProtocol = "sigv4"
});
var cdn = new Distribution("site-cdn", new()
{
Enabled = true,
DefaultRootObject = "index.html",
Origins = new DistributionOriginArgs[]
{
new()
{
OriginId = "s3Origin",
DomainName = bucket.BucketRegionalDomainName,
OriginAccessControlId = oac.Id
}
},
DefaultCacheBehavior = new DistributionDefaultCacheBehaviorArgs
{
TargetOriginId = "s3Origin",
ViewerProtocolPolicy = "redirect-to-https",
AllowedMethods = new[] { "GET", "HEAD" },
CachedMethods = new[] { "GET", "HEAD" },
Compress = true,
CachePolicyId = "658327ea-f89d-4fab-a63d-7e88639e58f6"
},
ViewerCertificate = new DistributionViewerCertificateArgs
{
CloudfrontDefaultCertificate = true
},
Restrictions = new DistributionRestrictionsArgs
{
GeoRestriction = new DistributionRestrictionsGeoRestrictionArgs
{
RestrictionType = "none"
}
}
});
return new Dictionary<string, object?>
{
["cdnUrl"] = cdn.DomainName.Apply(d => $"https://{d}"),
["bucketName"] = bucket.Id
};
});
Patterns nâng cao cho Production
Component Resources — Tái sử dụng như NuGet Package
Sức mạnh thực sự của Pulumi nằm ở khả năng tạo abstraction bằng OOP. Bạn có thể đóng gói một tập hợp resources thành Component Resource, rồi publish lên NuGet cho toàn team sử dụng:
using Pulumi;
using Pulumi.AzureNative.Web;
using Pulumi.AzureNative.Web.Inputs;
public class SecureWebAppArgs : ResourceArgs
{
[Input("resourceGroupName", required: true)]
public Input<string> ResourceGroupName { get; set; } = null!;
[Input("planId", required: true)]
public Input<string> PlanId { get; set; } = null!;
[Input("dotnetVersion")]
public Input<string>? DotnetVersion { get; set; }
[Input("customDomain")]
public Input<string>? CustomDomain { get; set; }
}
public class SecureWebApp : ComponentResource
{
[Output("endpoint")]
public Output<string> Endpoint { get; private set; } = null!;
[Output("principalId")]
public Output<string> PrincipalId { get; private set; } = null!;
public SecureWebApp(string name, SecureWebAppArgs args,
ComponentResourceOptions? options = null)
: base("custom:azure:SecureWebApp", name, options)
{
var dotnetVer = args.DotnetVersion ?? "DOTNETCORE|10.0";
var app = new WebApp($"{name}-app", new()
{
ResourceGroupName = args.ResourceGroupName,
ServerFarmId = args.PlanId,
HttpsOnly = true,
Identity = new ManagedServiceIdentityArgs
{
Type = Pulumi.AzureNative.Web.ManagedServiceIdentityType
.SystemAssigned
},
SiteConfig = new SiteConfigArgs
{
LinuxFxVersion = dotnetVer,
AlwaysOn = true,
MinTlsVersion = "1.2",
FtpsState = "Disabled",
Http20Enabled = true
}
}, new() { Parent = this });
Endpoint = app.DefaultHostName
.Apply(h => $"https://{h}");
PrincipalId = app.Identity
.Apply(i => i?.PrincipalId ?? "");
RegisterOutputs();
}
}
Sử dụng component này giống như dùng một class bình thường:
var api = new SecureWebApp("api-service", new()
{
ResourceGroupName = rg.Name,
PlanId = plan.Id,
DotnetVersion = "DOTNETCORE|10.0"
});
var frontend = new SecureWebApp("frontend", new()
{
ResourceGroupName = rg.Name,
PlanId = plan.Id,
DotnetVersion = "NODE|22-lts"
});
Stack References — Multi-stack Architecture
Trong production, bạn thường tách infrastructure thành nhiều stacks: networking, compute, database, monitoring. Pulumi Stack References cho phép các stacks tham chiếu outputs của nhau:
graph LR
subgraph Network["Stack: Networking"]
A["VNet / VPC
Subnets
NSG / Security Groups"]
end
subgraph Data["Stack: Database"]
B["SQL Server
Connection String
Firewall Rules"]
end
subgraph Compute["Stack: Compute"]
C["App Service
Container Apps
Functions"]
end
subgraph Monitor["Stack: Monitoring"]
D["Application Insights
Log Analytics
Alerts"]
end
A -->|"vnetId, subnetIds"| C
A -->|"subnetId"| B
B -->|"connectionString"| C
C -->|"appId"| D
style A fill:#2c3e50,stroke:#fff,color:#fff
style B fill:#e94560,stroke:#fff,color:#fff
style C fill:#4CAF50,stroke:#fff,color:#fff
style D fill:#ff9800,stroke:#fff,color:#fff
var networkStack = new StackReference("org/networking/production");
var dbStack = new StackReference("org/database/production");
var vnetId = networkStack.RequireOutput("vnetId")
.Apply(v => v.ToString()!);
var subnetId = networkStack.RequireOutput("appSubnetId")
.Apply(v => v.ToString()!);
var connString = dbStack.RequireOutput("connectionString")
.Apply(v => v.ToString()!);
var app = new WebApp("api", new()
{
ResourceGroupName = rg.Name,
ServerFarmId = plan.Id,
VirtualNetworkSubnetId = subnetId,
SiteConfig = new SiteConfigArgs
{
ConnectionStrings = new[]
{
new ConnStringInfoArgs
{
Name = "DefaultConnection",
ConnectionString = connString,
Type = ConnectionStringType.SQLAzure
}
}
}
});
Testing Infrastructure bằng xUnit
Một trong những lợi thế lớn nhất của Pulumi so với Terraform: bạn viết unit test cho infrastructure bằng chính framework test quen thuộc. Pulumi cung cấp mocking framework để test logic mà không cần provision resources thật:
using Pulumi;
using Pulumi.Testing;
public class InfraTests
{
[Fact]
public async Task WebApp_Must_Use_Https()
{
var resources = await Testing.RunAsync<MyStack>();
var webApps = resources
.OfType<Pulumi.AzureNative.Web.WebApp>();
foreach (var app in webApps)
{
var httpsOnly = await app.HttpsOnly
.GetValueAsync(whenUnknown: false);
Assert.True(httpsOnly,
$"WebApp {app.GetResourceName()} must enforce HTTPS");
}
}
[Fact]
public async Task All_Storage_Must_Be_Encrypted()
{
var resources = await Testing.RunAsync<MyStack>();
var accounts = resources
.OfType<Pulumi.AzureNative.Storage.StorageAccount>();
Assert.All(accounts, async account =>
{
var encryption = await account.Encryption
.GetValueAsync(whenUnknown: null);
Assert.NotNull(encryption);
});
}
}
Policy as Code
Ngoài unit tests, Pulumi còn có CrossGuard — hệ thống Policy as Code chạy trước mỗi deployment. Bạn viết policies bằng C# để enforce standards: "mọi S3 bucket phải enable encryption", "không được tạo public subnet", "tag 'environment' là bắt buộc". Policies chạy ở Pulumi Cloud, block deployment nếu vi phạm.
Pulumi Neo — AI Agent cho Cloud Engineering
Đầu năm 2026, Pulumi ra mắt Pulumi Neo — AI agent chuyên biệt cho infrastructure management, kế thừa và vượt xa Pulumi Copilot trước đó. Không giống các AI coding assistant thông thường, Neo hiểu sâu về infrastructure dependencies và governance policies.
Pulumi Neo có thể làm gì?
- Generate infrastructure code — "Tạo cho tôi một AKS cluster với 3 node pools, autoscaling, và Azure CNI" → Neo sinh ra C# code hoàn chỉnh
- Debug deployment failures — phân tích error, đề xuất fix dựa trên context của stack
- Cost optimization — quét resources đang chạy, gợi ý right-sizing và reserved instances
- Drift detection — phát hiện khi cloud resources bị thay đổi ngoài Pulumi
- Migration assistant — chuyển Terraform HCL sang Pulumi C# tự động
Pulumi Agent Skills cho AI Coding Assistants
Từ tháng 1/2026, Pulumi phát hành Agent Skills — tích hợp vào Claude Code, GitHub Copilot, Cursor, VS Code, và các AI coding tools khác. Skills cung cấp cho AI assistants kiến thức chuyên sâu về infrastructure patterns, giúp sinh code Pulumi chính xác hơn so với dùng AI vanilla.
# Cài Pulumi Agent Skills cho Claude Code
pulumi plugin install skills
# Trong Claude Code, bạn có thể hỏi:
# "Tạo Pulumi stack cho 3-tier architecture trên Azure
# với App Service, SQL Database, và Redis Cache"
Kubernetes với Pulumi — Beyond YAML
Một use case đặc biệt mạnh của Pulumi là quản lý Kubernetes. Thay vì viết hàng trăm dòng YAML, bạn dùng C# với full type safety:
using Pulumi.Kubernetes.Apps.V1;
using Pulumi.Kubernetes.Core.V1;
using Pulumi.Kubernetes.Types.Inputs.Apps.V1;
using Pulumi.Kubernetes.Types.Inputs.Core.V1;
using Pulumi.Kubernetes.Types.Inputs.Meta.V1;
var appLabels = new InputMap<string> { { "app", "my-api" } };
var deployment = new Deployment("api-deployment", new DeploymentArgs
{
Spec = new DeploymentSpecArgs
{
Replicas = 3,
Selector = new LabelSelectorArgs
{
MatchLabels = appLabels
},
Template = new PodTemplateSpecArgs
{
Metadata = new ObjectMetaArgs { Labels = appLabels },
Spec = new PodSpecArgs
{
Containers = new ContainerArgs[]
{
new()
{
Name = "api",
Image = "myregistry.azurecr.io/api:latest",
Ports = new ContainerPortArgs[]
{
new() { ContainerPortValue = 8080 }
},
Resources = new ResourceRequirementsArgs
{
Requests =
{
{ "cpu", "250m" },
{ "memory", "256Mi" }
},
Limits =
{
{ "cpu", "500m" },
{ "memory", "512Mi" }
}
}
}
}
}
}
}
});
var service = new Service("api-service", new ServiceArgs
{
Spec = new ServiceSpecArgs
{
Selector = appLabels,
Ports = new ServicePortArgs[]
{
new() { Port = 80, TargetPort = 8080 }
},
Type = "LoadBalancer"
}
});
CI/CD Integration
Pulumi tích hợp seamlessly vào CI/CD pipeline. Đây là workflow tiêu biểu cho GitHub Actions:
graph LR
A["git push"] --> B["PR Created"]
B --> C["pulumi preview
Show diff"]
C --> D["Code Review
+ Infra Review"]
D --> E["Merge to main"]
E --> F["pulumi up
Apply changes"]
F --> G["Stack Outputs
Update DNS/Config"]
style A fill:#f8f9fa,stroke:#e94560,color:#2c3e50
style C fill:#ff9800,stroke:#fff,color:#fff
style F fill:#4CAF50,stroke:#fff,color:#fff
style G fill:#2c3e50,stroke:#fff,color:#fff
name: Infrastructure
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
id-token: write # OIDC auth
contents: read
jobs:
preview:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- uses: pulumi/actions@v6
with:
command: preview
stack-name: org/dev
comment-on-pr: true
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- uses: pulumi/actions@v6
with:
command: up
stack-name: org/production
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
Secrets Management và Security
Pulumi có built-in secrets management — mọi secret được mã hóa trong state file. Bạn không bao giờ lưu plaintext password trong code hay config:
# Set secret cho stack
pulumi config set --secret dbPassword "S3cur3P@ss!"
# Trong C# code, đọc secret
var cfg = new Config();
var dbPassword = cfg.RequireSecret("dbPassword");
// Output<string> — luôn được mask trong logs
Pulumi hỗ trợ nhiều encryption providers: Pulumi Cloud (mặc định), AWS KMS, Azure Key Vault, Google Cloud KMS, hoặc passphrase-based encryption cho self-hosted state.
Lưu ý bảo mật
Khi dùng Pulumi với CI/CD, luôn sử dụng OIDC authentication (OpenID Connect) thay vì static credentials. GitHub Actions, GitLab CI, và Azure DevOps đều hỗ trợ OIDC — không cần lưu access keys dạng long-lived secrets. Pulumi ESC (Environments, Secrets, and Configuration) giúp centralize secrets management cross-stack.
Migration từ Terraform sang Pulumi
Nếu team đã có Terraform codebase, Pulumi cung cấp công cụ migration:
# Convert Terraform HCL sang Pulumi C#
pulumi convert --from terraform --language csharp
# Import existing Terraform state
pulumi import --from terraform ./terraform.tfstate
# Pulumi cũng có Terraform Bridge — wrap bất kỳ
# Terraform provider nào thành Pulumi provider
Quá trình migration thường diễn ra theo phases: bắt đầu bằng resources mới dùng Pulumi, rồi dần import existing resources từ Terraform state. Không cần big-bang migration.
Automation API — IaC trong Application Code
Đây là tính năng độc đáo chỉ có ở Pulumi: Automation API cho phép bạn nhúng Pulumi engine vào trong application code. Use cases: multi-tenant SaaS tự động provision infrastructure cho mỗi tenant, internal developer platform, hoặc self-service portals.
using Pulumi.Automation;
// Tạo hoặc chọn stack
var stack = await LocalWorkspace.CreateOrSelectStackAsync(
new InlineProgramArgs("org", "tenant-infra", "tenant-123",
PulumiFn.Create(() =>
{
var rg = new ResourceGroup($"rg-tenant-123");
var db = new Database($"db-tenant-123", new()
{
ResourceGroupName = rg.Name,
// ... tenant-specific config
});
return new Dictionary<string, object?>
{
["connectionString"] = db.ConnectionString
};
})));
// Preview trước
var preview = await stack.PreviewAsync();
Console.WriteLine($"Changes: {preview.ChangeSummary}");
// Deploy
var result = await stack.UpAsync();
var connStr = result.Outputs["connectionString"].Value;
Console.WriteLine($"Tenant DB: {connStr}");
Lộ trình phát triển Pulumi 2026
Kết luận
Pulumi mang đến một paradigm shift cho .NET developer: infrastructure IS software. Thay vì học thêm DSL mới, bạn tận dụng toàn bộ kiến thức C# — từ OOP và generics đến testing và NuGet ecosystem — để quản lý cloud infrastructure. Với sự xuất hiện của Pulumi Neo và Agent Skills, ranh giới giữa "viết code ứng dụng" và "viết code hạ tầng" ngày càng mờ nhạt.
Nếu bạn là .NET developer và đang bắt đầu hành trình IaC, Pulumi là lựa chọn tự nhiên nhất. Nếu team đã dùng Terraform ổn định, hãy cân nhắc dùng Pulumi cho projects mới thay vì migrate big-bang. Trong cả hai trường hợp, tư duy "infrastructure as software" sẽ nâng tầm cách bạn thiết kế và vận hành hệ thống cloud.
Bắt đầu nhanh
Truy cập pulumi.com/docs/iac/get-started để tạo project đầu tiên trong 10 phút. Pulumi có free tier không giới hạn cho individual developers, bao gồm state management trên Pulumi Cloud và 1 stack cho mỗi project.
Tài liệu tham khảo
Vue 3.6 Vapor Mode — Loại bỏ Virtual DOM, hiệu năng ngang Solid.js
Tối ưu chi phí Kubernetes 2026: Karpenter, Spot Instances và Right-Sizing giảm 55% bill cloud
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.