---
id: iac-bicep
title: "Bicep"
shortTitle: "Bicep"
track: iac
trackTitle: "Infrastructure as Code"
order: 2
level: important
status: published
estimatedMinutes: 35
prerequisites:
  - iac-terraform
next: iac-cloudformation
reviewedAgainst: 2026-10-12
sources:
  - title: "Bicep documentation"
    url: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview
  - title: "Deploy a Bicep file"
    url: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deploy-cli
---

# Bicep

Bicep là ngôn ngữ cho Azure Resource Manager. File `.bicep` biên dịch thành JSON template. Terraform trong bài trước chạy được nhiều cloud. Bicep chỉ Azure.

## Để làm gì

Bạn đọc một resource storage account trong Bicep, và biết lệnh deploy mà không chạy lên subscription.

## Gồm những gì

- `param`, `resource`, API version trong chuỗi type.
- `az deployment group what-if`: in diff, chưa ghi resource. Lab không chạy lệnh này.
- Khác Terraform: state không nằm trong file local của Bicep. ARM giữ deployment.

Bài này không đụng module registry, cũng không tạo resource group.

## Dùng khi nào

Team Azure đã chuẩn hóa Bicep, hoặc một template ARM cần viết lại cho dễ đọc. Repo đang là Terraform thì đừng thêm một file Bicep tạo cùng một resource group. Hai công cụ cùng quản lý một resource sẽ ghi đè nhau.

## Kiến thức cốt lõi

Một resource có type kèm version, ví dụ `Microsoft.Storage/storageAccounts@2023-05-01`. Đổi version API là đổi schema, không phải đổi tên cho vui. `param` là đầu vào. `resourceGroup().location` lấy location của nhóm bạn đang deploy vào.

Deploy ở scope resource group:

```bash
az deployment group create --resource-group lab-rg --template-file main.bicep
```

`what-if` in thay đổi dự kiến, chưa ghi xuống Azure. Dùng nó trước `create` trên subscription thật. Bài này không gọi Azure.

Tên storage account là toàn cục, chỉ chữ thường và số, 3 đến 24 ký tự. `uniqueString(resourceGroup().id)` giúp tên lab khỏi đụng người khác. Production đặt tên theo quy ước, đừng dựa vào chuỗi ngẫu nhiên rồi không ghi lại.

## Lệnh và code mẫu

`main.bicep`:

```bicep
param location string = resourceGroup().location

resource sa 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: 'stlab${uniqueString(resourceGroup().id)}'
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    allowBlobPublicAccess: false
  }
}
```

Nếu đã cài Bicep hoặc Azure CLI:

```bash
az bicep build --file main.bicep
```

Lệnh này tạo JSON cạnh file, không đụng Azure. Không có CLI thì chỉ đọc file.

## Thực hành

1. Chỉ property nào tắt public blob.
2. Build JSON nếu có `az`. Mở vài dòng `resources` trong JSON rồi xóa file JSON.
3. Không `az login` và không `deployment group create`.

## Kết quả mong đợi

`allowBlobPublicAccess` là `false`. Build local thì có file JSON. Subscription không đổi.

## Checklist

- [ ] `what-if` trước khi create trên resource group dùng chung.
- [ ] Không để Bicep và Terraform cùng sở hữu một resource.
- [ ] Public access của storage là tắt trừ khi bài toán cố ý phát file tĩnh.

## Lỗi thường gặp

**Gọi `resourceGroup()` khi deployment không ở scope resource group.** Scope sai thì hàm đó không có. Resource group tạo bằng deployment ở scope subscription. File đó khác file tạo tài nguyên bên trong group.

**Tên storage viết hoa.** ARM từ chối. Tên chỉ chữ thường và số.

## Nguồn

1. [Bicep overview](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) — ngôn ngữ và ARM.
2. [Deploy with Azure CLI](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deploy-cli) — `deployment group` và `what-if`.

## Tiếp theo

[CloudFormation](./12-cloudformation.md)
