練習 - 轉換和遷移資源
重要
您必須有自己的 Azure 訂用帳戶才能執行本練習,且可能會產生費用。 如果您還沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
您的玩具公司已收購一家製作受歡迎玩具卡車的競爭對手。 該玩具會連線到 Azure 中裝載的虛擬機器,以接收韌體更新。 虛擬機器的所有資源都是透過 Azure 入口網站手動建立。 在此單元中,您將開始進行將資源移轉至 Bicep 檔案的程序。
在此過程期間,您將執行下列工作:
- 使用 Azure 入口網站部署虛擬機器。
- 將虛擬機器資源匯出至 JSON 範本。
- 將 JSON 範本反向組譯為 Bicep。
- 建立新的 Bicep 檔案,並從反向組譯的範本移動資源。
此練習使用適用於 Visual Studio Code 的 Bicep 延伸模組。 請務必在 Visual Studio Code 中安裝此延伸模組。
使用 Azure 入口網站建立虛擬機器
為了模擬範例情節中的情況,首先要使用 Azure 入口網站來部署虛擬機器。
登入 Azure 入口網站。
在 Azure 首頁的 [Azure 服務] 下,選取 [建立資源]:
Azure Marketplace 會出現在 [建立資源] 窗格中。
在 [Ubuntu Server 20.04 LTS] 下,選取 [建立]:
重要
如果沒看到 [Ubuntu Server 20.04 LTS],請直接移至 Azure Marketplace 中的 Ubuntu Server 20.04 LTS。
在 [基本] 索引標籤上,為每個設定輸入下列值。 針對所有其他設定,請使用預設值。
設定 值 專案詳細資料 資源群組 選取 [新建],然後輸入 ToyTruck [執行個體詳細資料] 虛擬機器名稱 ToyTruckServer 區域 (美國) 美國西部 3 可用性選項 不需要基礎結構備援 映像 Ubuntu Server 20.04 LTS - x64 Gen2 大小 Standard_D2s_v3 系統管理員帳戶 驗證類型 密碼 使用者名稱 toytruckadmin 密碼 輸入密碼 輸入連接埠規則 公用輸入連接埠 無 在 [管理] 索引標籤上,確定未選取 [啟用自動關機]。
選取 [檢閱 + 建立] 。 Azure 會驗證您的設定。 您可能須視映像需求,輸入或選取更多資訊。
選取 [建立] 以部署和建立 VM。
Azure 入口網站會顯示正在部署。
部署完畢時,請選取資源群組名稱以開啟資源群組:
資源群組現在包含虛擬機器及其相依性:
將資源群組內容匯出至 JSON 範本
在左側功能表中,選取位於 [自動化] 下方的 [匯出範本]:
此時會產生 JSON 範本。 程序可能需要一兩分鐘時間才能完成。
選取 [下載] 按鈕:
JSON 範本和參數檔案會以 .zip 檔案的形式下載到您的電腦。
將檔案解壓縮到您可以輕鬆存取的資料夾,例如桌面。
打開 Visual Studio Code。
準備本機環境
在 [終端機] 功能表上,選取 [新增終端機]。 終端機視窗通常隨即在畫面的下半部開啟。
如果終端機視窗在右側顯示 bash,表示已開啟正確的殼層。 或者,如果您在右側看到 Bash 殼層圖示,則可以選取它來啟動殼層。
如果出現 bash 以外的殼層,請選取殼層下拉式清單箭號,然後選取 [Git Bash]。
在終端機中,前往您儲存範本的目錄。 例如,若將範本儲存於 templates 資料夾,則可使用此命令:
cd templates
安裝 Bicep
執行以下命令,確保您有最新版本 Bicep:
az bicep install && az bicep upgrade
在 [終端機] 功能表上,選取 [新增終端機]。 終端機視窗通常隨即在畫面的下半部開啟。
如果終端機視窗在右側顯示 pwsh 或 powershell,表示已開啟正確的殼層。 或者,如果您在右側看到 PowerShell 殼層圖示,則可以選取它來啟動殼層。
如果出現 pwsh 或 powershell 以外的殼層,則請選取該殼層下拉式清單箭號,然後選取 [PowerShell]。
在終端機中,前往您儲存範本的目錄。 例如,若將範本儲存在 templates 資料夾,則可使用此命令:
Set-Location -Path templates
安裝 Bicep CLI
若要從 Azure PowerShell 使用 Bicep,請安裝 Bicep CLI。
將 JSON 範本反向組譯為 Bicep
使用 decompile
命令,從範本建立 Bicep 檔案:
az bicep decompile --file template.json
反向組譯作業會產生類似以下的警告:
WARNING: Decompilation is a best-effort process, as there is no guaranteed mapping from ARM JSON
to Bicep.
You might need to fix warnings and errors in the generated bicep file(s), or decompilation might fail
entirely if an accurate conversion is not possible.
If you would like to report any issues or inaccurate conversions,
please see https://github.com/Azure/bicep/issues.
使用 decompile
命令,從範本建立 Bicep 檔案:
bicep decompile template.json
反向組譯作業會產生類似以下的警告:
WARNING: Decompilation is a best-effort process, as there is no guaranteed mapping from ARM JSON
to Bicep.
You might need to fix warnings and errors in the generated bicep file(s), or decompilation might fail
entirely if an accurate conversion is not possible.
If you would like to report any issues or inaccurate conversions,
please see https://github.com/Azure/bicep/issues.
檢查反向組譯的 Bicep 檔案
在 Visual Studio Code 中開啟 template.bicep 檔案並瀏覽完整內容。 請注意,這是有效的 Bicep 檔案,但其有幾個問題,包括:
- 提供給參數和資源的符號名稱包括底線,不易理解。
location
屬性已硬式編碼在所有資源定義中。- 此範本包含硬式編碼值,但應該為參數或由 Azure 自動設定。
您將會在此課程模組的其餘部分修正這些問題。
建立新的 Bicep 檔案
在 Visual Studio Code 中建立名為 main.bicep 的新檔案。
儲存空檔案,讓 Visual Studio Code 載入 Bicep 工具。
您可以選取 [檔案]>[另存新檔],或在 Windows 中選取 Ctrl+S (在 macOS 中為 ⌘+S)。
分割編輯器,讓您可以同時看到這兩個檔案 (左窗格中的 template.bicep 檔案和右窗格中的 main.bicep 檔案)。
- 選取 main.bicep 索引標籤。
- 選取 [檢視]>[編輯器配置]>[分割右側],以在右窗格中開啟 main.bicep 索引標籤。
- 關閉左窗格中的 main.bicep 索引標籤。
將每個元素複製到新的 Bicep 檔案
從 template.bicep 檔案中,將名為
networkSecurityGroups_ToyTruckServer_nsg_name_resource
的資源複製到 main.bicep 檔案。複製時,請注意
securityRules
屬性是空的。 稍後在此課程模組中,您將重構檔案以移除多餘的屬性。Visual Studio Code 指出錯誤,因為遺漏
networkSecurityGroups_ToyTruckServer_nsg_name
參數:將參數複製到 main.bicep 檔案。
針對下列資源及其相關聯的參數,重複此流程:
publicIPAddresses_ToyTruckServer_ip_name_resource
virtualMachines_ToyTruckServer_name_resource
virtualNetworks_ToyTruck_vnet_name_resource
virtualNetworks_ToyTruck_vnet_name_default
networkInterfaces_toytruckserver890_name_resource
注意
您部署中的資源名稱可能不同於此處所列的資源。 尋找與這些名稱相似的資源。
複製每個資源時,請檢查其屬性。 稍後在本課程模組中,您將更新每個資源的屬性和設定,以符合 Bicep 最佳做法。
提示
轉換或匯出自己的範本時,您可以更新資源,以遵循最佳做法來進行複製。 在此課程模組中,我們會另外更新資源,讓您更容易了解移轉流程的每個階段。
檢查是否遺漏資源
在 Azure 入口網站中,開啟 ToyTruck 資源群組。
檢閱資源清單,並與 Bicep 檔案中的資源清單進行比較。 請注意,資源群組包含 Bicep 檔案中未定義為
resource
的 [磁碟] 資源:在 Bicep 中使用虛擬機器時,您不需要明確定義受控磁碟資源。 相反地,請定義虛擬機器的屬性,Azure 會自動為您建立受控磁碟。 在此範例中,您不必擔心 Bicep 檔案中未定義磁碟資源。
驗證範本
移轉階段結束時,main.bicep 檔案應如以下範例所示:
param virtualNetworks_ToyTruck_vnet_name string = 'ToyTruck-vnet'
param virtualMachines_ToyTruckServer_name string = 'ToyTruckServer'
param networkInterfaces_toytruckserver154_name string = 'toytruckserver154'
param publicIPAddresses_ToyTruckServer_ip_name string = 'ToyTruckServer-ip'
param networkSecurityGroups_ToyTruckServer_nsg_name string = 'ToyTruckServer-nsg'
resource networkSecurityGroups_ToyTruckServer_nsg_name_resource 'Microsoft.Network/networkSecurityGroups@2022-05-01' = {
name: networkSecurityGroups_ToyTruckServer_nsg_name
location: 'westus3'
properties: {
securityRules: []
}
}
resource publicIPAddresses_ToyTruckServer_ip_name_resource 'Microsoft.Network/publicIPAddresses@2022-05-01' = {
name: publicIPAddresses_ToyTruckServer_ip_name
location: 'westus3'
sku: {
name: 'Standard'
tier: 'Regional'
}
properties: {
ipAddress: '1.2.3.4'
publicIPAddressVersion: 'IPv4'
publicIPAllocationMethod: 'Static'
idleTimeoutInMinutes: 4
ipTags: []
}
}
resource virtualMachines_ToyTruckServer_name_resource 'Microsoft.Compute/virtualMachines@2022-08-01' = {
name: virtualMachines_ToyTruckServer_name
location: 'westus3'
properties: {
hardwareProfile: {
vmSize: 'Standard_D2s_v3'
}
storageProfile: {
imageReference: {
publisher: 'canonical'
offer: '0001-com-ubuntu-server-focal'
sku: '20_04-lts-gen2'
version: 'latest'
}
osDisk: {
osType: 'Linux'
name: '${virtualMachines_ToyTruckServer_name}_disk1_23e6a144c4ea4049b3e2be24b78a9e81'
createOption: 'FromImage'
caching: 'ReadWrite'
managedDisk: {
storageAccountType: 'Premium_LRS'
id: resourceId('Microsoft.Compute/disks', '${virtualMachines_ToyTruckServer_name}_disk1_23e6a144c4ea4049b3e2be24b78a9e81')
}
deleteOption: 'Delete'
diskSizeGB: 30
}
dataDisks: []
}
osProfile: {
computerName: virtualMachines_ToyTruckServer_name
adminUsername: 'toytruckadmin'
linuxConfiguration: {
disablePasswordAuthentication: false
provisionVMAgent: true
patchSettings: {
patchMode: 'ImageDefault'
assessmentMode: 'ImageDefault'
}
enableVMAgentPlatformUpdates: false
}
secrets: []
allowExtensionOperations: true
requireGuestProvisionSignal: true
}
networkProfile: {
networkInterfaces: [
{
id: networkInterfaces_toytruckserver154_name_resource.id
properties: {
deleteOption: 'Detach'
}
}
]
}
diagnosticsProfile: {
bootDiagnostics: {
enabled: true
}
}
}
}
resource virtualNetworks_ToyTruck_vnet_name_resource 'Microsoft.Network/virtualNetworks@2022-05-01' = {
name: virtualNetworks_ToyTruck_vnet_name
location: 'westus3'
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: [
{
name: 'default'
id: virtualNetworks_ToyTruck_vnet_name_default.id
properties: {
addressPrefix: '10.0.0.0/24'
delegations: []
privateEndpointNetworkPolicies: 'Disabled'
privateLinkServiceNetworkPolicies: 'Enabled'
}
type: 'Microsoft.Network/virtualNetworks/subnets'
}
]
virtualNetworkPeerings: []
enableDdosProtection: false
}
}
resource virtualNetworks_ToyTruck_vnet_name_default 'Microsoft.Network/virtualNetworks/subnets@2022-05-01' = {
name: '${virtualNetworks_ToyTruck_vnet_name}/default'
properties: {
addressPrefix: '10.0.0.0/24'
delegations: []
privateEndpointNetworkPolicies: 'Disabled'
privateLinkServiceNetworkPolicies: 'Enabled'
}
dependsOn: [
virtualNetworks_ToyTruck_vnet_name_resource
]
}
resource networkInterfaces_toytruckserver154_name_resource 'Microsoft.Network/networkInterfaces@2022-05-01' = {
name: networkInterfaces_toytruckserver154_name
location: 'westus3'
kind: 'Regular'
properties: {
ipConfigurations: [
{
name: 'ipconfig1'
id: '${networkInterfaces_toytruckserver154_name_resource.id}/ipConfigurations/ipconfig1'
etag: 'W/"6a38849d-bd59-4eae-856e-4909f7ac1fac"'
type: 'Microsoft.Network/networkInterfaces/ipConfigurations'
properties: {
provisioningState: 'Succeeded'
privateIPAddress: '10.0.0.4'
privateIPAllocationMethod: 'Dynamic'
publicIPAddress: {
name: 'ToyTruckServer-ip'
id: publicIPAddresses_ToyTruckServer_ip_name_resource.id
properties: {
provisioningState: 'Succeeded'
resourceGuid: '07079685-0980-4ddf-acc3-3c8797c94b9a'
publicIPAddressVersion: 'IPv4'
publicIPAllocationMethod: 'Dynamic'
idleTimeoutInMinutes: 4
ipTags: []
ipConfiguration: {
id: '${networkInterfaces_toytruckserver154_name_resource.id}/ipConfigurations/ipconfig1'
}
deleteOption: 'Detach'
}
type: 'Microsoft.Network/publicIPAddresses'
sku: {
name: 'Basic'
tier: 'Regional'
}
}
subnet: {
id: virtualNetworks_ToyTruck_vnet_name_default.id
}
primary: true
privateIPAddressVersion: 'IPv4'
}
}
]
dnsSettings: {
dnsServers: []
}
enableAcceleratedNetworking: true
enableIPForwarding: false
disableTcpStateTracking: false
networkSecurityGroup: {
id: networkSecurityGroups_ToyTruckServer_nsg_name_resource.id
}
nicType: 'Standard'
}
}
注意
您的範本中有些內容可能不太一樣,包括一些符號名稱、API 版本和 IP 位址。 沒關係。 您稍後在課程模組中會解決其中一些差異。
您已建立初始 Bicep 檔案來代表資源。 此 Bicep 檔案結構不完善,且未遵循最佳做法。 在下一個單元中,您將了解如何改善所移轉範本的品質。
提示
如果您使用版本控制系統 (例如 Git),這會是認可您工作的好時機。
驗證 main.bicep 檔案之後,請關閉 template.bicep 檔案。