dataflows-save-as-authoring-cli

작성자: microsoft

업데이트 확인 — 세션당 한 번 (필수) 이 스킬이 세션에서 처음 사용될 때, 진행 전에 업데이트 확인 스킬을 실행하십시오.

npx skills add https://github.com/microsoft/skills-for-fabric --skill dataflows-save-as-authoring-cli

Update Check — ONCE PER SESSION (mandatory) The first time this skill is used in a session, run the check-updates skill before proceeding.

  • GitHub Copilot CLI / VS Code: invoke the check-updates skill.
  • Claude Code / Cowork / Cursor / Windsurf / Codex: compare local vs remote package.json version.
  • Skip if the check was already performed earlier in this session.

CRITICAL NOTES

  1. To find the workspace details (including its ID) from workspace name: list all workspaces and, then, use JMESPath filtering
  2. To find the item details (including its ID) from workspace ID, item type, and item name: list all items of that type in that workspace and, then, use JMESPath filtering

dataflows-save-as-authoring-cli — Dataflow Save-As Gen1 → Gen2.1 CI/CD via CLI

A save-as companion for creating upgraded Gen2.1 copies from Power BI Gen1 dataflows using readiness assessment and guarded execution.

We currently cannot perform an in-place migration of your dataflow. We can use save-as to create an upgraded Gen2.1 copy while preserving the original Gen1 dataflow.

Table of Contents

TaskReferenceNotes
Finding Workspaces and Items in FabricCOMMON-CLI.md § Finding Workspaces and ItemsMandatoryREAD link first
Fabric Topology & Key ConceptsCOMMON-CORE.md § Fabric Topology
Environment URLsCOMMON-CORE.md § Environment URLs
Authentication & Token AcquisitionCOMMON-CORE.md § AuthenticationWrong audience = 401
Core Control-Plane REST APIsCOMMON-CORE.md § Core REST APIsPagination, LRO polling, rate limits
Tool Selection RationaleCOMMON-CLI.md § Tool Selection
Authentication RecipesCOMMON-CLI.md § Auth Recipesaz login flows and token acquisition
Fabric Control-Plane API via az restCOMMON-CLI.md § az restAlways pass --resource
Gotchas & Troubleshooting (CLI)COMMON-CLI.md § Gotchasaz rest audience, shell escaping
Quick ReferenceCOMMON-CLI.md § Quick RefToken audience / tool matrix
Dataflow Definition StructureDATAFLOWS-AUTHORING-CORE.md § Definition3-part format for Gen2 CI/CD
Consumption Capability MatrixDATAFLOWS-CONSUMPTION-CORE.md § CapabilitiesRead-only discovery patterns
Upgrade CLI Quick Referenceupgrade-cli-quickref.mdAll az rest one-liners for scanning & save-as
Risk Assessment Guiderisk-assessment-guide.mdRisk signal detection logic & API calls

Tool Stack

ToolRoleInstall
az CLIPrimary: Auth (az login), REST API calls (az rest) against both Fabric and Power BI APIs.Pre-installed in most dev environments
jqParse and filter JSON responses (dataflow lists, risk signal extraction).Pre-installed or trivial
base64Decode dataflow definitions for inspection.Built into bash / [Convert]::ToBase64String() in PowerShell

Agent check — verify before first operation:

az --version 2>/dev/null || echo "INSTALL: https://aka.ms/install-azure-cli"
jq --version 2>/dev/null || echo "INSTALL: apt-get install jq OR brew install jq"

Authentication & API Audiences

This skill uses two distinct API audiences. Using the wrong audience returns 401.

APIAudience (--resource)Use For
Fabric Items APIhttps://api.fabric.microsoft.comList Gen2 dataflows (Fabric-native), workspace discovery
Power BI REST APIhttps://analysis.windows.net/powerbi/apiGen1 dataflow discovery, saveAsNativeArtifact, data sources, upstream dataflows, Admin API scanning
# Fabric Items API — list Gen2 dataflows in a workspace
az rest --method get \
  --resource "https://api.fabric.microsoft.com" \
  --url "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/dataflows"

# Power BI REST API — list all dataflows (Gen1 + Gen2) in a workspace
az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows"

# Power BI Admin API — list all dataflows tenant-wide (requires admin role)
az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/admin/dataflows"

Phase 1 — Awareness & Readiness

Goal: "Should I use save-as, and what will happen when I create a Gen2.1 copy?"

Agentic Workflow: Discover → Assess → Classify → Report

Follow this sequence for every save-as assessment:

  1. Discover — Scan workspace(s) to inventory all dataflows, identifying Gen1 vs Gen2
  2. Assess — For each Gen1 dataflow, check seven risk signals
  3. Classify — Assign a readiness category: ✅ Safe / ⚠️ Manual followups / ❌ Blocked
  4. Report — Output a Save-As Readiness Snapshot (markdown table + JSON)

Step 1: Discover — Identify Gen1 Dataflows

The Power BI REST API returns a generation property (value 1 or 2) on each dataflow. This is the preferred detection method — a single API call per workspace.

Non-Admin Path (per workspace)

WS_ID="<workspaceId>"
RESOURCE_PBI="https://analysis.windows.net/powerbi/api"

# List all dataflows — the `generation` property distinguishes Gen1 from Gen2
ALL_DATAFLOWS=$(az rest --method get \
  --resource "$RESOURCE_PBI" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows" \
  --query "value[].{id:objectId, name:name, generation:generation, modelUrl:modelUrl, configuredBy:configuredBy}" -o json)

# Filter Gen1 dataflows
echo "$ALL_DATAFLOWS" | jq '[.[] | select(.generation == 1)]'

# Filter Gen2 dataflows
echo "$ALL_DATAFLOWS" | jq '[.[] | select(.generation == 2)]'

Tip: A modelUrl pointing to dfs.core.windows.net additionally indicates BYOSA (customer-managed storage) — a save-as blocker.

Admin Path (tenant-wide)

Requires Fabric administrator role or service principal with Tenant.Read.All scope. Rate limited to 200 requests/hour.

RESOURCE_PBI="https://analysis.windows.net/powerbi/api"

# List ALL dataflows in the tenant
ADMIN_DATAFLOWS=$(az rest --method get \
  --resource "$RESOURCE_PBI" \
  --url "https://api.powerbi.com/v1.0/myorg/admin/dataflows" \
  --query "value[].{id:objectId, name:name, workspaceId:workspaceId, modelUrl:modelUrl, configuredBy:configuredBy}" \
  -o json)

# Filter Gen1 dataflows — those with a modelUrl indicate CDM/Gen1 storage
# Note: Admin API may not expose the `generation` property; use modelUrl as fallback
echo "$ADMIN_DATAFLOWS" | jq '[.[] | select(.modelUrl != null and .modelUrl != "")]'

Note: The Admin API supports $filter, $top, and $skip for pagination on large tenants.

Step 2: Assess — Check Risk Signals

For each Gen1 dataflow found, evaluate seven risk signals. See risk-assessment-guide.md for detailed API calls.

#Risk SignalDetection MethodImpact
1Incremental refreshCheck dataflow definition for incremental refresh policy configuration⚠️ Schedule migrates in disabled state; must re-enable and validate
2BYOSA / Custom ADLS Gen2 storageCheck modelUrl — if points to customer storage account (not Power BI managed)❌ Data stays in old storage; Gen2 CI/CD uses Fabric-managed storage
3Power Automate / API triggersCheck for external orchestration referencing the Gen1 dataflow ID⚠️ All integrations must update to new Gen2 artifact ID
4Downstream pipeline dependenciesCheck Fabric pipelines for dataflow activity references⚠️ Pipeline activities reference dataflow by ID; must re-bind
5Linked / computed entitiesInspect dataflow definition for entity references to other dataflows⚠️/❌ Cross-dataflow references may break if source dataflows are not saved first
6DirectQuery connectionsInspect data source types in definition❌ DirectQuery not supported in Gen2 CI/CD dataflows
7Caller is not owner / insufficient roleCompare configuredBy against az account show --query user.name -o tsv — or attempt call and catch DataflowUnauthorizedErrorsaveAsNativeArtifact requires the caller to be the dataflow owner or have Contributor/Admin in the source workspace; Viewer/Member without ownership cannot execute save-as

Step 3: Classify — Readiness Categories

CategoryCriteriaAction
SafeNo risk signals detectedCreate a Gen2.1 save-as copy with saveAsNativeArtifact
⚠️ Manual followupsRisk signals 1, 3, 4, or 5 (non-blocking)Execute save-as, then remediate flagged issues
BlockedRisk signals 2, 6, or 7 (blocking)Cannot execute save-as until blocker is resolved

Tip — detect ownership before save-as: The configuredBy field in the dataflow list response contains the owner's email. Compare it against the currently logged-in user (az account show --query user.name -o tsv). If they don't match and your workspace role is below Contributor, flag the dataflow as ❌ Blocked (signal 7) and escalate to the owner.

Step 4: Report — Save-As Readiness Snapshot

Markdown Output (terminal)

## Save-As Readiness Snapshot
| Workspace | Dataflow | Type | Readiness | Risk Signals | Recommendation |
|---|---|---|---|---|---|
| Sales Analytics | SalesETL | Gen1 | ✅ Safe | None | Save as Gen2.1 copy now |
| Sales Analytics | CustomerLoad | Gen1 | ⚠️ Manual | Incremental refresh, Pipeline dep | Save as Gen2.1 copy, then re-enable schedule & update pipeline |
| Finance | FinanceDaily | Gen1 | ❌ Blocked | BYOSA storage | Resolve storage dependency first |

JSON Output (automation)

{
  "snapshotDate": "2025-04-13T10:00:00Z",
  "summary": { "total": 3, "safe": 1, "manual": 1, "blocked": 1 },
  "dataflows": [
    {
      "workspaceName": "Sales Analytics",
      "workspaceId": "...",
      "dataflowName": "SalesETL",
      "dataflowId": "...",
      "type": "Gen1",
      "readiness": "safe",
      "riskSignals": [],
      "recommendation": "Save as Gen2.1 copy now",
      "saveAsPath": "saveAsNativeArtifact"
    }
  ]
}

Save JSON to file: pipe to jq '.' > readiness-snapshot.json


Execute with Guardrails

Goal: Invoke save-as and capture outcomes safely.

Gen1 → Gen2.1 CI/CD: saveAsNativeArtifact API

POST https://api.powerbi.com/v1.0/myorg/groups/{groupId}/dataflows/{gen1DataflowId}/saveAsNativeArtifact

This is a Preview API. It creates a new Gen2.1 CI/CD artifact copy while preserving the original Gen1 dataflow.

WS_ID="<workspaceId>"
GEN1_ID="<gen1DataflowId>"

# Write body to a temp file — az rest wraps inline --body in an envelope
# on some platforms, causing "saveAsRequest is a required parameter" errors.
cat > /tmp/save-as-body.json <<'EOF'
{
  "displayName": "MyDataflow_Gen2CICD",
  "description": "Saved as Gen2.1 copy from Gen1",
  "includeSchedule": true,
  "targetWorkspaceId": "<targetWorkspaceId>"
}
EOF

az rest --method post \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows/$GEN1_ID/saveAsNativeArtifact" \
  --headers "Content-Type=application/json" \
  --body @/tmp/save-as-body.json

Gotcha — inline body: Passing JSON inline via --body '{...}' can cause az rest to wrap the payload in an extra envelope, resulting in "saveAsRequest is a required parameter" errors. Always use file-based body (--body @file.json) for this endpoint.

Gotcha — Windows az.cmd: On Windows, omit -o json from saveAsNativeArtifact calls — the flag produces "A value that is not valid (json) was specified for the outputFormat parameter" when routed through az.cmd. Capture output without -o json and parse with ConvertFrom-Json in PowerShell, or pipe to jq in bash.

Gotcha — not idempotent (duplicate artifacts on retry): saveAsNativeArtifact creates a new artifact every time it is called. If a batch is interrupted and re-run, you will end up with multiple copies in the target workspace. To make retries safe: (1) check whether a Gen2 artifact with the intended name already exists before calling, or (2) include a timestamp in displayName and treat each run as a distinct artifact.

Gotcha — owner permissions: You must be the dataflow owner or have Contributor/Admin in the source workspace to call saveAsNativeArtifact. If you are only a Viewer or Workspace Member who does not own the dataflow, the API returns DataflowUnauthorizedError. Ask the dataflow owner or a workspace admin to run the save-as operation for those dataflows.

Request parameters:

ParameterTypeRequiredDescription
displayNamestring (max 200)NoName for new artifact. Auto-generated with _copy1 suffix if omitted
descriptionstring (max 4000)NoDescription. Copied from source if omitted
includeSchedulebooleanNoCopy refresh schedule in disabled state
targetWorkspaceIdstring (uuid)NoTarget workspace. Same workspace if omitted

Response: 200 OK with SaveAsNativeDataflowResponse:

  • artifactMetadata — full metadata of the new Gen2 CI/CD artifact (including objectId, provisionState)
  • errors[] — non-fatal warning codes (save-as succeeds even if these occur):
    • FailedToCopySchedule — schedule could not be copied
    • SetDataflowOriginFailed — origin tracking not set
    • ConnectionsUpdateFailed — connection strings could not be updated to Fabric format

Gen2 → Gen2 CI/CD: In-Place Upgrade

NOT YET AVAILABLE — This API is not available in the current public surface. This skill will be updated when the endpoint is published. Do not attempt to call a non-existent endpoint.

Post-Save-As Validation Checklist

Run these checks after save-as before any Gen1 cleanup:

  • Confirm artifactMetadata.provisionState reaches Active.
  • Review errors[] in SaveAsNativeDataflowResponse and create follow-up tasks for each warning.
  • Confirm the new artifact exists in the target workspace and has expected name/description.
  • Verify dependent orchestration (pipelines, flows, API callers) is updated to the new artifact ID.
  • Only trigger refresh when the user explicitly approves.

Must/Prefer/Avoid

MUST DO

  • Always pass --resource to az rest — use the correct audience per the API table above. Wrong audience = silent 401.
  • Always include --headers "Content-Type=application/json" on POST calls to the Power BI REST API.
  • Use file-based body for saveAsNativeArtifact — pass --body @file.json instead of inline JSON. Inline --body '{...}' can cause az rest to wrap the payload in an extra envelope, producing "saveAsRequest is a required parameter" errors.
  • On Windows, omit -o json on saveAsNativeArtifact calls — use ConvertFrom-Json in PowerShell or pipe to jq instead. The -o json flag fails with "A value that is not valid (json)" error when routed through az.cmd.
  • Verify you are the dataflow owner or Contributor before save-assaveAsNativeArtifact returns DataflowUnauthorizedError for non-owners who are only Workspace Members or Viewers.
  • Check for existing Gen2 artifacts before retryingsaveAsNativeArtifact is not idempotent; interrupted batch runs create duplicate copies on retry. Either verify the target name is absent before calling, or use a unique timestamped displayName per run.
  • Scan before save-as — always run the readiness scan before execution.
  • Never refresh without explicit user consent — the Gen2 CI/CD artifact schedule is created in disabled state for safety.
  • Check errors[] in saveAsNativeArtifact response — save-as may succeed with non-fatal warnings.
  • Verify provisionState is Active after save-as — poll the artifact metadata until terminal state.
  • Preserve the original Gen1 dataflowsaveAsNativeArtifact leaves the Gen1 intact. Do not delete it until post-save-as validation passes.

PREFER

  • Admin API for tenant-wide scanning — more efficient than workspace-by-workspace for large tenants.
  • JSON output for automation — markdown is for human review, JSON for scripting and CI/CD integration.
  • Topological save-as order — save upstream dataflows (with linked entities) before downstream consumers.
  • Readiness-first execution — do not skip readiness assessment before save-as.
  • generation property for Gen1 detection — the Power BI REST API returns generation: 1 or generation: 2 on each dataflow. Use this single-API-call approach over cross-API comparison.
  • modelUrl check as secondary signal — dataflows with a modelUrl pointing to dfs.core.windows.net are Gen1 using customer storage (BYOSA blocker).

AVOID

  • Saving blocked (❌) dataflows — resolve BYOSA storage and DirectQuery issues first.
  • Batch save-as without review — always review the readiness snapshot before saving multiple dataflows.
  • Hardcoded workspace/dataflow IDs — resolve dynamically via REST API.
  • Ignoring non-fatal errorsFailedToCopySchedule, ConnectionsUpdateFailed, etc. require manual follow-up.
  • Calling the Gen2→Gen2 CI/CD in-place save-as API — it does not exist yet. Do not fabricate endpoints.
  • Deleting Gen1 artifacts without explicit user consent — never delete Gen1 dataflows unless the user explicitly approves deletion, even after post-save-as validation confirms data integrity.
  • Using -o json with saveAsNativeArtifact on Windows — omit the flag; capture raw output and parse it explicitly.
  • Re-running batch save-as scripts without idempotency checks — always verify the target artifact doesn't already exist to avoid duplicate copies in the workspace.

Examples

Example 1: Full Phase 1 — Readiness Scan for a Single Workspace

Prompt: "Scan my Sales workspace for Gen1 dataflows and show me a readiness snapshot"

Agent response:

# Step 1 — Resolve workspace ID
WS_ID=$(az rest --method get \
  --resource "https://api.fabric.microsoft.com" \
  --url "https://api.fabric.microsoft.com/v1/workspaces" \
  --query "value[?displayName=='Sales'].id" -o tsv)

# Step 2 — List all dataflows with generation property
ALL_DFS=$(az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows" -o json)

# Step 3 — Filter Gen1 dataflows by generation property
GEN1_DFS=$(echo "$ALL_DFS" | jq '[.value[] | select(.generation == 1) |
  {id: .objectId, name: .name, generation: .generation, modelUrl: .modelUrl}]')

echo "Gen1 dataflows found: $(echo $GEN1_DFS | jq length)"
echo "$GEN1_DFS" | jq '.'

Example 2: Save-As a Gen1 Dataflow to Gen2.1

Prompt: "Migrate or upgrade the SalesETL Gen1 dataflow in my Sales workspace"

Agent response:

WS_ID="<workspaceId>"
GEN1_ID="<gen1DataflowId>"

# Write body to file (avoids az rest envelope wrapping)
cat > /tmp/save-as-body.json <<'EOF'
{"displayName": "SalesETL_Gen2CICD", "includeSchedule": true}
EOF

# Execute save-as
RESPONSE=$(az rest --method post \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/groups/$WS_ID/dataflows/$GEN1_ID/saveAsNativeArtifact" \
  --headers "Content-Type=application/json" \
  --body @/tmp/save-as-body.json)

# Check result
echo "$RESPONSE" | jq '{
  newId: .artifactMetadata.objectId,
  state: .artifactMetadata.provisionState,
  errors: .errors
}'

Example 3: Tenant-Wide Admin Scan

Prompt: "Show me all Gen1 dataflows across the entire tenant"

Agent response:

# Requires Fabric administrator role
ALL_DFS=$(az rest --method get \
  --resource "https://analysis.windows.net/powerbi/api" \
  --url "https://api.powerbi.com/v1.0/myorg/admin/dataflows" -o json)

# Gen1 dataflows have a modelUrl
echo "$ALL_DFS" | jq '[.value[] | select(.modelUrl != null and .modelUrl != "") |
  {id: .objectId, name: .name, workspace: .workspaceId, 
   owner: .configuredBy, storage: .modelUrl}]'

microsoft의 다른 스킬

oss-growth
microsoft
OSS 성장 해커 페르소나
official
microsoft-foundry
microsoft
Foundry 에이전트를 엔드투엔드로 배포, 평가 및 관리: Docker 빌드, ACR 푸시, 호스팅/프롬프트 에이전트 생성, 컨테이너 시작, 배치 평가, 지속적 평가, 프롬프트 최적화 워크플로, agent.yaml, 트레이스에서 데이터셋 큐레이션. 용도: Foundry에 에이전트 배포, 호스팅 에이전트, 에이전트 생성, 에이전트 호출, 에이전트 평가, 배치 평가 실행, 지속적 평가, 지속적 모니터링, 지속적 평가 상태, 프롬프트 최적화, 프롬프트 개선, 프롬프트 최적화 도구, 에이전트 지침 최적화, 에이전트 개선...
officialdevelopmentdevops
azure-ai
microsoft
Azure AI: Search, Speech, OpenAI, Document Intelligence에 사용됩니다. 검색, 벡터/하이브리드 검색, 음성-텍스트 변환, 텍스트-음성 변환, 전사, OCR을 지원합니다. 사용 시점: AI Search, 쿼리 검색, 벡터 검색, 하이브리드 검색, 의미 검색, 음성-텍스트 변환, 텍스트-음성 변환, 전사, OCR, 텍스트를 음성으로 변환.
officialdevelopmentapi
azure-deploy
microsoft
이미 준비된 애플리케이션에 대해 기존 .azure/deployment-plan.md 및 인프라 파일이 있는 경우 Azure 배포를 실행합니다. 사용자가 새 애플리케이션 생성을 요청할 때는 이 스킬을 사용하지 말고 azure-prepare를 사용하세요. 이 스킬은 azd up, azd deploy, terraform apply, az deployment 명령을 내장된 오류 복구 기능과 함께 실행합니다. azure-prepare의 .azure/deployment-plan.md와 azure-validate의 검증 상태가 필요합니다. 사용 시점: "run azd up", "run azd deploy", "execute deployment",...
officialdevopsaws
azure-storage
microsoft
Azure Storage Services는 Blob Storage, File Shares, Queue Storage, Table Storage, Data Lake를 포함합니다. 스토리지 액세스 계층(hot, cool, cold, archive), 각 계층 사용 시기 및 계층 비교에 대한 질문에 답변합니다. 객체 스토리지, SMB 파일 공유, 비동기 메시징, NoSQL 키-값, 빅데이터 분석을 제공합니다. 수명 주기 관리를 포함합니다. 사용 용도: blob 스토리지, 파일 공유, 큐 스토리지, 테이블 스토리지, 데이터 레이크, 파일 업로드, blob 다운로드, 스토리지 계정, 액세스 계층,...
officialdevelopmentdatabase
azure-diagnostics
microsoft
Azure에서 AppLens, Azure Monitor, 리소스 상태 및 안전한 트라이지를 사용하여 Azure 프로덕션 문제를 디버그합니다. 사용 시기: 프로덕션 문제 디버그, 앱 서비스 문제 해결, 앱 서비스 높은 CPU, 앱 서비스 배포 실패, 컨테이너 앱 문제 해결, 함수 문제 해결, AKS 문제 해결, kubectl 연결 불가, kube-system/CoreDNS 오류, pod 보류 중, crashloop, 노드 준비 안 됨, 업그레이드 실패, 로그 분석, KQL, 인사이트, 이미지 풀 실패, 콜드 스타트 문제, 상태 프로브 실패,...
officialdevopsdevelopment
azure-prepare
microsoft
Azure 앱을 배포용으로 준비합니다(인프라 Bicep/Terraform, azure.yaml, Dockerfiles). 생성/현대화 또는 생성+배포에 사용하며, 크로스 클라우드 마이그레이션에는 사용하지 않습니다(azure-cloud-migrate 사용). 다음에는 사용하지 마십시오: copilot-sdk 앱(azure-hosted-copilot-sdk 사용). 사용 시점: "앱 생성", "웹 앱 빌드", "API 생성", "서버리스 HTTP API 생성", "프론트엔드 생성", "백엔드 생성", "서비스 빌드", "애플리케이션 현대화", "애플리케이션 업데이트", "인증 추가", "캐싱 추가", "Azure에 호스팅", "생성 및...
officialdevelopmentdevops
azure-validate
microsoft
Azure 배포 전 준비 상태 검증. 구성, 인프라(Bicep 또는 Terraform), RBAC 역할 할당, 관리 ID 권한, 사전 요구 사항에 대한 심층 점검을 실행합니다. 사용 시점: 내 앱 검증, 배포 준비 상태 확인, 사전 점검 실행, 구성 확인, 배포 가능 여부 확인, azure.yaml 검증, Bicep 검증, 배포 전 테스트, 배포 오류 문제 해결, Azure Functions 검증, 함수 앱 검증, 서버리스 검증...
officialdevopstesting