배포에 버그가 발생하는 경우 신속하게 복구할 수 있는 방법이 필요합니다. 이 문서에서는 CI/CD(연속 통합 및 지속적인 배포) 프로세스를 사용하여 잘못된 배포에서 Flex Consumption 함수 앱으로 복구하는 방법을 보여 줍니다. 이 프로세스에는 다음과 같은 복구 방법이 포함됩니다.
| 복구 방법 | 속도 | 사용 시기 | Description |
|---|---|---|---|
| 이전의 성공적인 실행 다시 실행(롤백) | 가장 빠름 | 알려진 좋은 버전이 있거나 버전 간에 데이터 또는 상태 변경이 없습니다. | 이전 실행을 선택하고 다시 실행한 다음 빌드 및 배포를 기다립니다. |
git revert 그리고 그런 다음 git push (롤 포워드) |
Moderate | 수정이 간단하거나 외부 상태를 롤백할 수 없습니다. | 문제를 일으킨 커밋을 식별하고 되돌린 후 푸시하세요. 그런 다음 동일한 빌드 및 배포 시간을 기다립니다. |
git commit 핫픽스를 적용한 후 git push (롤 포워드) |
가장 느린 | 근본 원인은 알려져 있으며 대상 수정이 필요합니다. | 근본 원인을 식별합니다. 수정 사항 만들기, 검토, 테스트 및 병합 빌드 및 배포가 완료되기를 기다립니다. |
이러한 전략은 함수 앱 코드와 앱 설정을 모두 복구하므로 코드 변경으로 구성 변경 내용을 복구할 수 있습니다.
배포를 복구하기 위해 CI/CD가 필요한 이유
Flex Consumption 계획 앱에 코드를 배포하는 경우:
- 코드는 시작 시 탑재되는 Blob Storage 컨테이너에 zip 패키지로 배포됩니다.
- 각 배포는 현재 패키지를 덮어씁니다.
- 플랫폼은 이전 버전을 유지하기 위해 기본 제공 수정 기록을 유지하지 않습니다.
- 배포 슬롯 기능은 현재 지원되지 않습니다.
- 앱 설정은 Azure 포털, CLI 또는 IaC(Infrastructure-as-code)를 통해 별도로 적용되며 플랫폼은 이전 상태로 복원할 수 없습니다.
이러한 배포 동작은 잘못된 배포에서 Flex Consumption 계획 앱을 복구하기 위한 옵션을 제한합니다.
Git 기록 및 CI/CD 프로세스는 지정된 시점에 코드 배포를 추적하는 유일한 방법을 제공합니다. 코드와 구성을 모두 포함한 배포를 만들면 다음 실행이 검증된 정상 커밋을 가리키도록 하여 문제가 있는 릴리스로부터 복구할 수 있습니다.
Flex Consumption 배포 모델에 대한 자세한 내용은 Flex Consumption 계획의 Flex Consumption 계획 및 사이트 업데이트를 참조하세요.
사전 요구 사항
Azure의 Flex Consumption 계획에 배포된 기존 함수 앱입니다.
Git 리포지토리의 소스 코드입니다. 롤백할 항목을 빠르게 식별할 수 있도록 각 릴리스에 대해 Git 태그 또는 레코드 커밋 SHA를 사용합니다.
함수 앱용으로 구성된 배포 설정:
GitHub Actions 사용하여 지속적인 업데이트에 설명된 대로 OIDC 인증으로 구성된 워크플로입니다. 워크플로는
azure/login를 사용해야 합니다. 게시 프로필 인증은 이 가이드에서az cli사용되는 명령을 지원하지 않습니다.
앱 설정을 관리하기 위한 배포 준비
전체 롤백을 수행하려면 먼저 앱 설정을 소스 제어에 넣고 배포의 일부로 적용해야 합니다. 이 방법을 사용하면 코드와 구성을 한 번의 다시 실행으로 복구할 수 있지만 설정 적용, 다시 시작 대기 및 선언되지 않은 값 정리와 같은 추가 단계가 필요합니다.
Tip
배포에 설정이 포함되지 않은 경우 배포된 코드만 롤백할 수 있지만 구성은 롤백할 수 없습니다.
이 섹션에서는 배포의 일부로 앱 설정을 관리하는 두 가지 방법을 자세히 설명합니다.
| Approach | 워크플로에서(Azure CLI) | 서비스 정의(Bicep)에서 |
|---|---|---|
| 작동 방식 | 배포 단계는 다음을 사용하여 az functionapp config appsettingsJSON 파일에서 설정을 적용한 다음, 선언되지 않은 설정을 제거합니다. |
Bicep 템플릿은 siteConfig.appSettings에서 설정을 선언하며, ARM은 배포 시 전체 컬렉션을 대체합니다. |
| 복잡성 | 보통. 워크플로의 JSON 파일 및 추가 CLI 단계 | 높은. Bicep에 대한 지식이 필요합니다 |
| 드리프트 감지 | 아니오 | 예(what-if) |
| 최적입니다 | 소규모 팀 시작하기 | 프로덕션 준비, 다중 환경, 복잡한 인프라 |
앱 설정에 대한 자세한 내용은 Azure Functions 대한 앱 설정 참조를 참조하세요.
앱 설정 고려 사항
앱 설정의 프로그래밍 방식 구성을 사용하는 경우 이러한 고려 사항에 주의하세요.
Important
두 방법 중 하나를 사용하여 필요한 모든 설정을 포함하지 않으면 배포된 앱이 중단될 수 있습니다.
이 섹션의 두 방법 모두 설정 파일을 원하는 전체 상태로 처리합니다. 모든 배포의 앱에서 파일에 선언되지 않은 앱 설정을 제거합니다. 앱을 중단하지 않도록 항상 모든 필수 설정을 포함합니다.
app-settings.json및 Bicep 파일 템플릿의 변경 사항도 코드 변경 사항과 동일한 수준으로 엄격하게 검토하세요. 프로덕션에 반영되기 전에 구성 오류를 포착할 수 있도록 풀 요청의 설정 변경 사항을 검토하세요.최적의 보안을 위해 연결에 대한 다음 지침을 따르세요.
가능한 경우 관리 ID 연결을 사용합니다. 호스트 스토리지(), 배포 스토리지 및 트리거/바인딩 연결에 대한
AzureWebJobsStorage연결을 설정합니다. 자세한 내용은 배포 설정 구성을 참조하세요.- 비밀이 피할 수 없는 경우 Key Vault 참조를 사용합니다. Key Vault 비밀을 안전하게 저장합니다. 비밀을 직접 저장하는 대신 참조를 사용하여 런타임에 필요한 비밀에 안전하게 액세스할 수 있습니다. 자세한 내용은 Key Vault 참조 사용을 참조하세요.
CI/CD를 사용하는 경우 각각 앱 설정 또는 코드로 변경하면 별도의 사이트 업데이트가 트리거됩니다. 기본적으로 이 배포 프로세스는 두 개 이상의 사이트 업데이트를 생성합니다. 먼저 설정이 적용된 경우와 코드가 배포될 때입니다. 무중단 배포의 경우 대신 롤링 업데이트 전략을 사용합니다. 이 전략에서는 인스턴스를 여러 배치로 나누어 트래픽을 비운 뒤 교체합니다. 자세한 내용은 Flex 소비 계획의 사이트 업데이트를 참조하세요.
워크플로에서 앱 설정 구성
다음 기본 단계를 사용하여 프로젝트 배포에 앱 설정 구성 파일을 추가합니다.
리포지토리에 JSON 파일을 만드세요. 예를 들어
infra/app-settings.json에 만들 수 있습니다. 이 파일에는 다음 예제와 같은 JSON 형식의 모든 필수 앱 설정이 포함되어야 합니다.[ { "name": "FUNCTIONS_EXTENSION_VERSION", "value": "~4" }, { "name": "FUNCTIONS_WORKER_RUNTIME", "value": "dotnet-isolated" }, { "name": "APPLICATIONINSIGHTS_CONNECTION_STRING", "value": "InstrumentationKey=00000000-..." }, { "name": "AzureWebJobsStorage__blobServiceUri", "value": "https://mystorageaccount.blob.core.windows.net" }, { "name": "AzureWebJobsStorage__queueServiceUri", "value": "https://mystorageaccount.queue.core.windows.net" }, { "name": "AzureWebJobsStorage__tableServiceUri", "value": "https://mystorageaccount.table.core.windows.net" }, { "name": "MyFeatureFlag", "value": "true" }, { "name": "ServiceBus__fullyQualifiedNamespace", "value": "my-namespace.servicebus.windows.net" } ]특정 배포 정의에서 코드 배포가 발생하기 전에 설정을 적용하는 단계를 추가하고 그 사이에 30초 동안 일시 중지합니다.
다음 섹션에서는 두 방법을 모두 사용하는 특정 배포 예제를 제공합니다.
예: app-settings.json 배포
이 배포 예제에서는 구성을 포함하도록 배포를 구성하는 방법을 보여 줍니다. CI/CD 메서드와 일치하는 탭을 선택합니다.
다음 단계를 워크플로의 deploy 작업에 추가하세요.
infra/app-settings.json을 사용할 수 있도록 actions/checkout@v4을 deploy 작업에 추가하고, RESOURCE_GROUP을 워크플로 수준의 env 블록에 추가하세요. 단계는 먼저 설정을 적용하고, 다시 시작을 기다린 다음, 코드를 배포한 다음, 선언되지 않은 설정을 정리합니다.
deploy:
needs: build
steps:
- name: 'Checkout repository'
uses: actions/checkout@v4
- name: 'Download artifact from build job'
uses: actions/download-artifact@v4
with:
name: ${{ env.BUILD_ARTIFACT_NAME }}
path: ./downloaded-artifact
- name: 'Log in to Azure'
uses: azure/login@v2
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: 'Apply app settings'
run: |
az functionapp config appsettings set \
--name ${{ env.AZURE_FUNCTIONAPP_NAME }} \
--resource-group ${{ env.RESOURCE_GROUP }} \
--settings @infra/app-settings.json
- name: 'Wait for settings restart'
run: sleep 30
- name: 'Deploy code'
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ./downloaded-artifact
- name: 'Remove undeclared app settings'
run: |
DESIRED=$(jq -r '.[].name' infra/app-settings.json)
CURRENT=$(az functionapp config appsettings list \
--name ${{ env.AZURE_FUNCTIONAPP_NAME }} \
--resource-group ${{ env.RESOURCE_GROUP }} \
--query "[].name" -o tsv)
TO_DELETE=""
for setting in $CURRENT; do
if ! echo "$DESIRED" | grep -qx "$setting"; then
TO_DELETE="$TO_DELETE $setting"
fi
done
if [ -n "$TO_DELETE" ]; then
az functionapp config appsettings delete \
--name ${{ env.AZURE_FUNCTIONAPP_NAME }} \
--resource-group ${{ env.RESOURCE_GROUP }} \
--setting-names $TO_DELETE
fi
OIDC 기반 워크플로의 azure/login@v2 단계는 az cli 명령에 필요한 인증을 제공합니다.
Bicep 배포에 설정 정의하기
IaC 배포의 경우 Bicep 템플릿에서 직접 앱 설정을 관리합니다. Bicep 별도의 정리 단계 없이 모든 배포에서 전체 siteConfig.appSettings 컬렉션을 기본적으로 대체합니다. 또한 what-if을 사용하여 드리프트 감지도 지원합니다.
Bicep 파일의 앱 설정 섹션만 업데이트하면 배포 중에 다른 모든 Azure 리소스가 수정되지 않은 상태로 유지됩니다. 이 문서에서는 Bicep 작성 전반을 다루지 않습니다. 전체 Flex Consumption 템플릿은 Azure Functions 코드형 인프라를 참조하세요.
다음은 Bicep 템플릿의 관련 조각입니다(appSettings 부분만 해당).
siteConfig: {
appSettings: [
{
name: 'MyFeatureFlag'
value: 'true'
}
{
name: 'ServiceBus__Connection'
value: '@Microsoft.KeyVault(SecretUri=https://my-vault.vault.azure.net/secrets/sb-conn)'
}
]
}
코드 배포 전에 30초 동안 대기하면서 Bicep 템플릿을 배포하는 단계를 추가합니다. Bicep 통해 앱 설정을 업데이트하는 것은 비동기적입니다. 앱은 새 값을 적용하기 위해 다시 시작되며, 다시 시작하는 동안 코드를 배포하면 실패할 수 있습니다.
- name: 'Deploy infrastructure'
run: |
az deployment group create \
--resource-group ${{ env.RESOURCE_GROUP }} \
--template-file infra/main.bicep \
--parameters appName=${{ env.AZURE_FUNCTIONAPP_NAME }}
- name: 'Wait for settings restart'
run: sleep 30
- name: 'Deploy code'
uses: Azure/functions-action@v1
with:
app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
package: ./downloaded-artifact
배포 롤백하기
롤백은 이전에 성공한 실행을 다시 실행하는 것을 의미합니다. 다시 실행은 현재 분기 HEAD가 아닌 해당 실행을 트리거한 원래 커밋 SHA 를 확인하므로 해당 시점부터 코드 및 설정 파일을 다시 빌드하고 배포합니다. 새 커밋이 필요하지 않습니다.
이전에 성공한 실행을 다시 실행하여 배포를 롤백하려면 다음을 수행합니다.
- GitHub 리포지토리의 작업 탭으로 이동합니다.
- 잘못된 배포 전에 마지막으로 성공한 워크플로 실행을 찾습니다.
- 모든 작업 다시 실행을 선택합니다.
- 워크플로는 실행의 커밋을 확인하고, 코드를 다시 빌드하고, 배포하고, 해당 커밋의
app-settings.json앱 설정을 동기화합니다.
재실행 시 다시 빌드되는 항목
다시 실행하면 이전 커밋의 코드가 다시 작성됩니다. 원본 바이너리 아티팩트를 재사용하지 않습니다. 이 동작은 다음을 의미합니다.
- 고정된 종속성 잠금 파일(
package-lock.jsonrequirements.txt등)에서는 출력이 기능적으로 동일합니다. - 빌드 시간은 일반 배포와 동일합니다. 그것은 즉각적이지 않습니다.
- 빌드 시 가져온 외부 종속성(NuGet, npm, pip)은 계속 사용할 수 있어야 합니다.
롤백 고려 사항
종속성 잠금 파일(
package-lock.jsonrequirements.txt또는 잠긴.csproj버전)을 소스 제어에 고정합니다. 고정된 잠금 파일은 다시 실행이 발생하는 시기에 관계없이 배포를 다시 실행하면 기능적으로 동일한 빌드를 생성하도록 합니다.다시 실행하면 원래 커밋의 워크플로 또는 파이프라인 YAML이 사용됩니다. 그러나 비밀 및 파이프라인 변수는 다시 실행될 때 현재 값으로 확인됩니다. 원래 실행과 다시 실행 간에 비밀을 회전하면 새 비밀 값이 사용됩니다.
다시 실행하면 배포된 앱이 정상 상태로 복원되지만 Git 기록은 변경되지 않습니다. 브랜치의 HEAD는 여전히 문제가 있는 커밋을 가리키고 있습니다.
다시 실행해도 복원되지 않는 기능:
- 호스팅 플랜, 네트워킹 및 ID 할당을 포함한, 배포 외부에서 관리되는 Azure 리소스 구성.
- 데이터베이스, 메시지 큐 및 스토리지와 같은 다운스트림 서비스의 데이터 또는 스키마가 변경됩니다.
- Key Vault 비밀 값 Key Vault 참조만 소스 제어에서 유지 관리됩니다. 비밀 순환은 Key Vault 작업 중 하나입니다.
롤백 프로세스를 정기적으로 테스트합니다. 프로덕션 인시던트가 발생한 후에야 문제가 있다는 것을 알게 되도록 기다리지 마세요.
롤백 후 브랜치 수정
다음 푸시로 트리거된 실행이 문제가 있는 커밋을 다시 배포하므로, 해당 브랜치를 가져오는 다른 개발자들은 여전히 문제가 있는 코드를 보게 됩니다. 다음 작업 중 하나를 사용하여 이 상황을 해결해야 합니다.
- 기본적으로 롤 포워드 작업인 문제를 해결하는 핫픽스 커밋을 만듭니다.
- 새 커밋을 만들어 손상된 커밋을 되돌리려면
git revert을 수행합니다. 이는 롤포워드 작업이기도 합니다. - 문제를 해결할 때까지 병합을 방지하는 분기 정책입니다.
이러한 작업 중 하나를 완료할 때까지 해당 분기에서 새 실행을 트리거하지 않습니다. 유효성 검사 지침은 병합하기 전에 유효성 검사를 참조하세요.
배포를 앞으로 진행
롤 포워드란 문제를 해결하기 위해 새 커밋을 푸시하는 것을 의미합니다. 끊어진 배포는 수정이 배포될 때까지 라이브 상태로 유지되므로 이 전략은 앱이 해당 시간 동안 성능 저하된 동작을 허용할 수 있을 때 가장 잘 작동합니다.
브랜치에 수정 커밋을 만드세요. 이 수정 사항은 다음과 같습니다.
- 문제를 직접 해결하는 핫픽스 입니다.
- 잘못된 변경 사항을 되돌리는 새 커밋을 만드는
git revert <bad-commit-sha>입니다. 비록git revert가 코드를 되돌리지만, 새 커밋을 생성하고 새 배포를 트리거하므로 롤 포워드입니다.
수정에 구성 변경도 필요한 경우, 동일한 커밋에서 앱 설정을 업데이트하세요(
app-settings.json또는 Bicep 템플릿에서).커밋을 푸시합니다. 배포 시 수정 사항이 자동으로 빌드 및 배포됩니다.
병합하기 전에 유효성 검사
복구 전략에 관계없이 커밋을 프로덕션 분기에 병합하기 전에 유효성을 검사하고 수정하여 문제가 복잡해지는 것을 방지합니다.
이러한 권장 사항은 선제적으로 롤포워드하든 롤백 후 분기를 수정하든 관계없이 적용됩니다.
스테이징 환경 사용: Flex Consumption 계획은 현재 배포 슬롯을 지원하지 않으므로 프로덕션 분기에 병합하기 전에 별도의 Flex Consumption 계획 앱에 배포하여 수정 사항의 유효성을 검사하는 것이 좋습니다.
상태 검사 자동화: 앱에서 상태 검사 엔드포인트를 호출하고 긍정적인 응답을 확인하는 배포 후 단계를 추가합니다. 실패할 경우 이전에 성공한 실행의 다시 실행을 트리거하여 자동으로 롤백하는 것이 좋습니다.
배포 후 모니터링: 회귀 검색을 위해 Application Insights 경고를 설정합니다. 조기 탐지는 잘못된 배포의 영향을 줄입니다.
관련 콘텐츠
- GitHub Actions를 사용한 지속적인 업데이트
Azure Pipelines 를 사용하여 지속적인 배포- 유연 소비 계획
- Azure Functions 코드형 인프라
- 함수 앱 관리