Bicep 파일을 배포하기 전에 발생하는 변경 내용을 미리 볼 수 있습니다. ARM(Azure Resource Manager)은 Bicep 파일을 배포하는 경우 리소스가 어떻게 변경되는지 확인할 수 있는 가상 작업을 제공합니다. what-if 작업은 기존 리소스를 변경하지 않습니다. 대신, 지정된 Bicep 파일이 배포되는 경우 변경 내용을 예측합니다.
Visual Studio Code, Azure PowerShell, Azure CLI 또는 REST API 작업에서 what-if 작업을 사용할 수 있습니다. 가상은 리소스 그룹, 구독, 관리 그룹, 테넌트 수준 배포에 지원됩니다.
가상 작업 중에는 templateLink의 평가 및 확장이 지원되지 않습니다. 따라서 템플릿 사양 참조를 포함하여 중첩된 배포 내의 템플릿 링크를 사용해 배포된 모든 리소스는 가상 작업 결과에 표시되지 않습니다.
필수 조건
필요한 사용 권한
Bicep 파일 또는 ARM(Azure Resource Manager) 템플릿을 배포하려면 배포하는 리소스에 대한 쓰기 액세스 권한과 해당 리소스 유형의 모든 작업에 대한 Microsoft.Resources/deployments 접근 권한이 필요합니다. 예를 들어 가상 머신을 배포하려면 Microsoft.Compute/virtualMachines/write 및 Microsoft.Resources/deployments/* 권한이 필요합니다. 가상 작업에는 동일한 사용 권한 요구 사항이 있습니다.
Azure CLI 버전 2.76.0 이상 및 Azure PowerShell 버전 13.4.0 이상 에서는 이 프로세스 중에 ARM이 Bicep 템플릿의 유효성을 철저히 검사하는 방법을 결정하는 ValidationLevel 스위치를 도입했습니다. 자세한 내용은 What-if 명령을 참조하세요.
역할 및 사용 권한 목록은 Azure 기본 제공 역할을 참조하세요.
Installation
Azure CLI에서 가상을 사용하려면 Azure CLI 2.14.0 이상이 있어야 합니다. 필요한 경우 최신 버전의 Azure CLI를 설치합니다.
제한점
What-if는 다음 제한에 도달할 때까지 중첩된 템플릿을 확장합니다.
- 중첩된 템플릿 500개.
- 리소스 그룹 간 배포의 리소스 그룹 800개.
- 중첩된 템플릿을 확장하는 데 소요되는 5분.
제한 중 하나에 도달하면 나머지 리소스의 변경 유형이 무시로 설정됩니다.
단락
Bicep 배포의 가정 연산은 배포 구조나 외부 상태에 대한 종속성으로 인해 서비스가 모듈이나 리소스를 완전히 분석할 수 없는 시나리오인 "쇼트-서킷 상황"이 발생할 수 있습니다. 개별 리소스의 단락은 리소스 ID 또는 API 버전을 배포 컨텍스트 외부에서 계산할 수 없는 경우에 발생하며, 종종 해결되지 않은 식 또는 외부 종속성으로 인해 발생합니다. 자세한 내용은 평가되지 않은 식을 참조하세요. 드물게 모듈 또는 중첩된 배포 리소스의 단락이 발생할 수 있으므로 모듈 내의 모든 리소스가 가상 분석 결과에서 제외됩니다. 이러한 경우 API 응답에는 문제를 나타내는 진단 메시지가 포함됩니다.
what-if 작업 실행
최신 버전의 Az PowerShell 모듈(13.1.0 이상) 또는 Azure CLI(2.75.0 이상)를 사용하면 what-if 기능이 배포의 일부를 분석할 수 없는 경우, 진단 정보를 제공합니다. 이전 버전의 이러한 도구는 동일한 방식으로 동작하지만 진단은 표시하지 않습니다. 예를 들어 CLI 버전 2.74.0을 사용하는 경우 문제가 계속 발생하며, 이는 눈에 띄지 않게 발생합니다.
가상 명령
Bicep 파일을 배포하기 전에 변경 사항을 미리 보려면 다음을 사용합니다.
- 리소스 그룹 배포의 경우 az deployment group what-if
- 구독 수준 배포의 경우 az deployment sub what-if
- 관리 그룹 배포의 경우 az deployment mg what-if
- 테넌트 배포의 경우 az deployment tenant what-if
Azure CLI 버전 2.76.0 이상 에서는 이 프로세스 중에 ARM이 Bicep 템플릿의 유효성을 철저히 검사하는 방법을 결정하는 스위치를 도입 --validation-level 했습니다. 다음 값을 허용합니다.
- 공급자 (기본값): 템플릿 구문, 리소스 정의, 종속성 및 권한 검사를 포함하여 전체 유효성 검사를 수행하여 템플릿의 모든 리소스를 배포할 수 있는 충분한 권한이 있는지 확인합니다.
- ProviderNoRbac: 공급자와 유사하게 템플릿 및 리소스의 전체 유효성 검사를 수행하지만 전체 배포 권한 대신 각 리소스에 대한 읽기 권한만 확인합니다. 이 기능은 모든 액세스 권한 없이 리소스 구성의 유효성을 검사하려는 경우에 유용합니다.
- 템플릿: 실행 전 검사(예: 리소스 가용성) 및 권한 검사를 건너뛰는 동안 템플릿 구문 및 구조를 검사하여 정적 유효성 검사만 수행합니다. 이는 배포 오류를 일으킬 수 있는 덜 철저하고 잠재적으로 누락된 문제입니다.
--confirm-with-what-if스위치(또는 약식인 -c )를 사용하여 변경 내용을 미리 보고 배포를 계속하라는 프롬프트를 받을 수 있습니다. 다음에 스위치를 추가합니다.
- az 배포 그룹 생성
- az deployment sub create (새 배포를 생성하는 명령)
- az deployment mg create (Azure 배포 관리 그룹 생성)
- az 배포 테넌트 생성
예를 들어 리소스 그룹 배포의 경우 az deployment group create --confirm-with-what-if 또는 -c를 사용합니다.
이전 명령은 수동으로 검사할 수 있는 텍스트 요약을 반환합니다. 프로그래밍 방식으로 변경 내용을 검사할 수 있는 JSON 개체를 가져오려면 --no-pretty-print 스위치를 사용합니다. 예를 들어 리소스 그룹 배포에는 az deployment group what-if --no-pretty-print를 사용합니다.
색 없이 결과를 반환하려는 경우 Azure CLI 구성 파일을 엽니다. no_color를 예로 설정합니다.
REST API의 경우 다음을 사용합니다.
- 리소스 그룹 배포의 경우 Deployments - What If
- 구독 배포의 경우 Deployments - What If At Subscription Scope
- 관리 그룹 배포의 경우 Deployments - What If At Management Group Scope
- 테넌트 배포의 경우 Deployments - What If At Tenant Scope.
Azure SDK를 통해 가상 작업을 사용할 수 있습니다.
- Python의 경우 가상를 사용합니다.
- Java의 경우 DeploymentWhatIf Class를 사용합니다.
- .NET의 경우 DeploymentWhatIf Class를 사용합니다.
환경 설정
가상이 작동하는 방식을 확인하기 위해 일부 테스트를 실행해 보겠습니다. 먼저 가상 네트워크를 만드는 Bicep 파일을 배포합니다. 다음 Bicep 파일을 다음과 같이 what-if-before.bicep저장합니다.
resource vnet 'Microsoft.Network/virtualNetworks@2025-01-01' = {
name: 'vnet-001'
location: resourceGroup().location
tags: {
CostCenter: '12345'
Owner: 'Team A'
}
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
enableVmProtection: false
enableDdosProtection: false
subnets: [
{
name: 'subnet001'
properties: {
addressPrefix: '10.0.0.0/24'
}
}
{
name: 'subnet002'
properties: {
addressPrefix: '10.0.1.0/24'
}
}
]
}
}
Bicep 파일을 배포하려면 다음을 사용합니다.
az group create \
--name ExampleGroup \
--location "Central US"
az deployment group create \
--resource-group ExampleGroup \
--template-file "what-if-before.bicep"
테스트 수정
배포가 완료되면 가상 작업을 테스트할 준비가 된 것입니다. 이번에는 가상 네트워크를 변경하는 Bicep 파일을 배포합니다. 앞의 예제와 비교하여 다음 예제에서는 원래 태그 중 하나를 놓치고 서브넷이 제거되었으며 주소 접두사는 변경되었습니다. 다음 Bicep 파일을 다음과 같이 what-if-after.bicep저장합니다.
resource vnet 'Microsoft.Network/virtualNetworks@2025-01-01' = {
name: 'vnet-001'
location: resourceGroup().location
tags: {
CostCenter: '12345'
}
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/15'
]
}
enableVmProtection: false
enableDdosProtection: false
subnets: [
{
name: 'subnet002'
properties: {
addressPrefix: '10.0.1.0/24'
}
}
]
}
}
변경 내용을 보려면 다음을 사용합니다.
az deployment group what-if \
--resource-group ExampleGroup \
--template-file "what-if-after.bicep"
what-if 출력은 다음과 유사하게 나타납니다.
텍스트 출력은 다음과 같습니다.
Resource and property changes are indicated with these symbols:
- Delete
+ Create
~ Modify
- tags.Owner: "Team A"
+ properties.enableVmProtection: false
~ properties.addressSpace.addressPrefixes: [
- 0: "10.0.0.0/16"
+ 0: "10.0.0.0/15"
]
~ properties.subnets: [
- 0:
name: "subnet001"
properties.addressPrefix: "10.0.0.0/24"
properties.defaultOutboundAccess: false
properties.privateEndpointNetworkPolicies: "Disabled"
properties.privateLinkServiceNetworkPolicies: "Enabled"
]
Resource changes: 1 to modify.
출력의 위쪽에서 색이 변경 형식을 나타내는 것으로 정의됩니다.
출력 아래쪽에는 태그 소유자가 삭제되었음을 표시합니다. 주소 접두사가 10.0.0.0/16에서 10.0.0.0/15로 변경되었습니다. subnet001이라는 서브넷이 삭제되었습니다. 이러한 변경 내용은 배포되지 않았습니다. Bicep 파일을 배포하는 경우 변경 내용의 미리 보기가 표시됩니다.
삭제된 것으로 표시되는 일부 속성은 실제로 변경되지 않습니다. 속성은 Bicep 파일에 없을 때 삭제된 것으로 잘못 보고될 수 있지만, 배포 중에 기본값으로 자동 설정됩니다. 이 결과는 가상 응답에서 "노이즈"로 간주됩니다. 최종 배포된 리소스는 속성에 설정된 값을 갖습니다. 가상 작업이 완성됨에 따라 해당 속성은 결과에서 필터링됩니다.
삭제 확인
Bicep 파일을 배포하기 전에 변경 내용을 미리 보려면 배포 명령에서 confirm switch 매개 변수를 사용합니다. 예상대로 변경되면 배포를 완료하도록 응답합니다.
az deployment group create \
--resource-group ExampleGroup \
--confirm-with-what-if \
--template-file "what-if-after.bicep"
텍스트 출력은 다음과 같습니다.
Resource and property changes are indicated with these symbols:
- Delete
+ Create
~ Modify
The deployment will update the following scope:
Scope: /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/ExampleGroup
~ Microsoft.Network/virtualNetworks/vnet-001 [2024-07-01]
- properties.privateEndpointVNetPolicies: "Disabled"
- tags.Owner: "Team A"
+ properties.enableVmProtection: false
~ properties.addressSpace.addressPrefixes: [
- 0: "10.0.0.0/16"
+ 0: "10.0.0.0/15"
]
~ properties.subnets: [
- 0:
name: "subnet001"
properties.addressPrefix: "10.0.0.0/24"
properties.defaultOutboundAccess: false
properties.privateEndpointNetworkPolicies: "Disabled"
properties.privateLinkServiceNetworkPolicies: "Enabled"
]
Resource changes: 1 to modify.
Are you sure you want to execute the deployment? (y/n):
예상되는 변경 내용을 확인하고 배포를 실행하려는 것을 확인할 수 있습니다.
가상 결과를 프로그래밍 방식으로 평가
이제 명령을 변수에 설정하여 가상 결과를 프로그래밍 방식으로 평가해 보겠습니다.
results=$(az deployment group what-if --resource-group ExampleGroup --template-file "what-if-after.bicep" --no-pretty-print)
가상 시나리오 결과 이해
결과 보기
PowerShell 또는 Azure CLI에서 가상을 사용하는 경우 다양한 형식의 변경 내용을 볼 수 있도록 하는 색으로 구분된 결과가 출력에 포함됩니다.
텍스트 출력은 다음과 같습니다.
Resource and property changes are indicated with these symbols:
- Delete
+ Create
~ Modify
The deployment will update the following scope:
Scope: /subscriptions/./resourceGroups/ExampleGroup
~ Microsoft.Network/virtualNetworks/vnet-001 [2018-10-01]
- tags.Owner: "Team A"
~ properties.addressSpace.addressPrefixes: [
- 0: "10.0.0.0/16"
+ 0: "10.0.0.0/15"
]
~ properties.subnets: [
- 0:
name: "subnet001"
properties.addressPrefix: "10.0.0.0/24"
]
Resource changes: 1 to modify.
참고
가상 작업은 reference 함수를 확인할 수 없습니다. 속성을 reference 함수를 포함하는 템플릿 식으로 설정할 때마다 가상은 속성 변경을 보고합니다. 해당 동작은 가상이 속성(예: 부울 값에 관한 true 또는 false)의 현재 값을 확인되지 않은 템플릿 식과 비교하기 때문에 발생합니다. 분명히 이러한 값은 일치하지 않습니다. Bicep 파일을 배포할 때 속성은 템플릿 식이 다른 값으로 확인되는 경우에만 변경됩니다.
유형 변경
가상 작업은 다음과 같은 7가지 형식의 변경 내용을 나열합니다.
- 만들기: 현재는 리소스가 없지만 Bicep 파일에 정의되어 있습니다. 리소스가 만들어집니다.
- 삭제:해당 변경 형식은 배포에 전체 모드를 사용하는 경우에만 적용됩니다. 리소스가 있지만 Bicep 파일에 정의되어 있지 않습니다. 전체 모드에서는 리소스가 삭제됩니다. 전체 모드 삭제를 지원하는 리소스만 해당 변경 형식에 포함됩니다.
- 무시: 리소스가 있지만 Bicep 파일에 정의되어 있지 않습니다. 리소스는 배포되거나 수정되지 않습니다. 중첩된 템플릿 확장의 한도에 도달하면 이 변경 유형이 표시됩니다. What-if 제한을 참조하세요.
-
변경 안 함: 리소스가 있고 Bicep 파일에 정의되어 있습니다. 리소스가 재배포되지만 리소스의 속성은 변경되지 않습니다. 이 변경 유형은 ResultFormat이 기본값인
FullResourcePayloads로 설정된 경우에 반환됩니다. -
NoEffect: 속성은 준비 전용이며 서비스에서 무시됩니다. 예를 들어
sku.tier속성은 항상sku.name네임스페이스에서Microsoft.ServiceBus과 일치하도록 설정됩니다. -
수정: 리소스가 있고 Bicep 파일에 정의되어 있습니다. 리소스가 재배포되고 리소스의 속성이 변경됩니다. 이 변경 유형은 ResultFormat이 기본값인
FullResourcePayloads로 설정된 경우에 반환됩니다. -
배포: 리소스가 있고 Bicep 파일에 정의되어 있습니다. 리소스가 재배포됩니다. 리소스의 속성은 변경될 수도 있고 변경되지 않을 수도 있습니다. 속성이 변경될지 여부를 결정할 수 있는 정보가 충분하지 않을 때 작업은 이 변경 유형을 반환합니다.
ResultFormat이
ResourceIdOnly로 설정된 경우에만 이 조건이 표시됩니다.
결과 형식
예측된 변경 내용에 관해 반환되는 세부 정보의 수준을 제어합니다. 다음 두 가지 옵션을 사용할 수 있습니다.
- FullResourcePayloads -변경되는 리소스 목록 및 변경되는 속성에 관한 세부 정보를 반환합니다.
- ResourceIDOnly -변경되는 리소스의 목록을 반환합니다.
기본값은 FullResourcePayloads입니다.
PowerShell 배포 명령의 경우 -WhatIfResultFormat 매개 변수를 사용합니다. 프로그래매틱 개체 명령에서 ResultFormat 매개 변수를 사용합니다.
Azure CLI의 경우 --result-format 매개 변수를 사용합니다.
다음 결과는 두 가지 출력 형식을 보여 줍니다.
전체 리소스 페이로드
Resource and property changes are indicated with these symbols: - Delete + Create ~ Modify The deployment will update the following scope: Scope: /subscriptions/./resourceGroups/ExampleGroup ~ Microsoft.Network/virtualNetworks/vnet-001 [2018-10-01] - tags.Owner: "Team A" ~ properties.addressSpace.addressPrefixes: [ - 0: "10.0.0.0/16" + 0: "10.0.0.0/15" ] ~ properties.subnets: [ - 0: name: "subnet001" properties.addressPrefix: "10.0.0.0/24" ] Resource changes: 1 to modify.리소스 ID만 해당
Resource and property changes are indicated with this symbol: ! Deploy The deployment will update the following scope: Scope: /subscriptions/./resourceGroups/ExampleGroup ! Microsoft.Network/virtualNetworks/vnet-001 Resource changes: 1 to deploy.
평가되지 않은 식
평가되지 않은 식이 출력에 나타나면, 이는 배포 컨텍스트 밖에서는 평가할 수 없다는 의미입니다. 식은 배포가 실행될 때 채워질 정보를 나타내기 위해 원형 그대로 표시됩니다.
param now string = utcNow()
resource sa 'Microsoft.Storage/storageAccounts@2025-06-01' = {
name: 'acct'
location: resourceGroup().location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
tags: {
lastDeployedOn: now
lastDeployedBy: deployer().userPrincipalName
}
}
앞의 예제에서 매개 변수는 now 함수를 utcNow() 사용하여 현재 날짜와 시간을 가져옵니다. what-if를 실행하면 이러한 식은 배포 컨텍스트 외부에서 평가할 수 없으므로 as-is 표시됩니다. what-if 출력은 다음과 유사합니다.
Note: The result may contain false positive predictions (noise).
You can help us improve the accuracy of the result by opening an issue here: https://aka.ms/WhatIfIssues
Resource and property changes are indicated with this symbol:
~ Modify
The deployment will update the following scope:
Scope: /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/jgaotest
~ Microsoft.Storage/storageAccounts/acct0808 [2025-01-01]
~ tags.lastDeployedOn: "20250808T200145Z" => "[utcNow()]"
Resource changes: 1 to modify.
다음 식은 what-if 중에 평가되지 않습니다.
- newGuid() 및 utcNow()와 같은 비결정적 함수
- 보안 매개 변수 값에 대한 모든 참조입니다.
- 동일한 템플릿에 배포되지 않은 리소스에 대한 참조입니다.
- 동일한 템플릿에 정의되지 않은 리소스 속성에 대한 참조입니다.
- listKeys()와 같은 모든 리소스 함수입니다.
리소스 정리
예제 리소스가 더 이상 필요하지 않으면 Azure CLI 또는 Azure PowerShell을 사용하여 리소스 그룹을 삭제합니다.
az group delete --name ExampleGroup
다음 단계
- 파이프라인에서 가상 작업을 사용하려면 파이프라인에서 가상을 사용하여 ARM 템플릿 테스트를 참조하세요.
- 가상 작업에서 잘못된 결과가 표시되는 경우 https://aka.ms/whatifissues에서 문제를 보고하세요.