글: Kristijan Sekereš

2027년 3월 31일 Azure Cloud Services(추가 지원) 종료: 웹 역할과 작업자 역할 옮기기

데이터 센터에서 푸른 조명을 받은 서버 랙 행렬

Microsoft는 2025년 3월 31일 Azure Cloud Services(추가 지원)를 사용 중단으로 지정했고, 2027년 3월 31일에 완전히 종료합니다. 귀사의 업무용 애플리케이션이 웹 역할과 작업자 역할로 실행되고 있다면 그 날짜 전에 Azure의 다른 곳에서 실행되고 있어야 합니다. 종료 FAQ는 모두가 가장 먼저 묻는 두 질문에 단호하게 답합니다. Microsoft는 "연장 요청을 승인할 수 없으며", "원클릭 마이그레이션 도구는 없습니다".

오늘 2026년 10월 3일 기준으로 남은 기간은 6개월입니다.

누구를 위한 글인가

전형적인 경우는 이렇습니다. .NET Framework 기반 ASP.NET 애플리케이션으로, 앞에는 웹 역할이 있고 뒤에는 대기열을 처리하는 작업자 역할 한두 개가 있으며, 8년이나 10년 전에 외주 업체가 만들었습니다. 그 업체는 이미 떠난 경우가 많고, 애플리케이션은 여전히 주문 처리나 고객 포털을 돌리며, 지난번 마이그레이션 이후 아무도 .csdef 파일을 열어 보지 않았습니다.

영향을 받는지 확인하려면 Azure 포털을 열고 "Cloud Services(추가 지원)" 유형의 리소스를 조회하십시오. Microsoft의 종료 공지는 바로 그 화면으로 연결됩니다. 비어 있다면 할 일은 없습니다.

이 글은 2024년에 종료된 Cloud Services(클래식)에 관한 것이 아닙니다. 벤더가 제품을 대신 호스팅한다면 마이그레이션은 벤더의 일입니다. 날짜를 서면으로 요청하십시오. 아래 내용은 코드를 소유한 팀, 또는 서류상으로는 소유하고 있지만 그것을 이해하는 사람을 찾아야 하는 팀을 위한 것입니다.

2024년의 이전보다 어려운 이유

많은 회사가 클래식이 종료된 2024년에 추가 지원으로 옮겼습니다. 그 이전은 의도적으로 비용이 적게 들도록 설계되었습니다. Microsoft의 추가 지원 개요는 .csdef, .cscfg, .cspkg 파일이 "그대로 이어지며 형식에 변경이 없다"고, 그리고 "런타임 코드는 변경할 필요가 없다"고 말합니다. 제자리 마이그레이션까지 있었습니다. 같은 페이지는 더 이상 발전하지 않는 애플리케이션에 추가 지원을 권했는데, "빠른 마이그레이션 경로를 제공하기" 때문이었습니다.

이번에는 같은 형태의 이전 대상이 없습니다. Microsoft의 표현으로 Cloud Services는 "애플리케이션을 VM으로 배포하는 것입니다. 작성한 코드는 VM 인스턴스와 긴밀하게 결합되어 있습니다". 귀사의 코드는 자신이 역할 안에서 실행된다는 것을 압니다. 역할에서 설정을 읽고, 역할을 통해 디스크 공간을 찾고, 역할이 설치한 인증서를 받고, 역할이 시작되기 전에 관리자 권한으로 설정 스크립트를 실행합니다. 이 모든 것을 대체해야 합니다.

공식 안내를 읽기 전에 한 가지 더 알아 두십시오. Microsoft의 종료 공지와 FAQ는 이전 대상으로 Service Fabric 관리형 클러스터 하나를 지목합니다. 개요 페이지는 다섯 가지를 나열하고, Microsoft 자신의 마이그레이션 결정 매트릭스는 일곱 가지를 비교합니다. Service Fabric은 기본값일 뿐 요건이 아니며, 많은 웹 역할에게는 잘못된 선택입니다.

이전 대상과 각각이 맞는 경우

웹 역할과 작업자 역할이 같은 곳으로 갈 필요는 없습니다. 역할마다 대상을 고르십시오.

App Service(Windows). ASP.NET 애플리케이션에게 웹 역할과 가장 가까운 대상입니다. Windows 인스턴스에는 지원되는 .NET Framework 버전이 설치되어 있어 Web Forms와 MVC 5가 다시 작성하지 않고도 실행됩니다. 작업자 역할은 WebJobs로 따라갈 수 있으며, WebJobs는 "웹앱과 같은 인스턴스에서" 추가 비용 없이 실행됩니다. 한계는 머신 자체입니다. Microsoft는 COM 구성 요소, 레지스트리 접근, MSI 설치 프로그램이 필요한 앱을 관리형 인스턴스로 안내하므로, 표준 요금제에서는 관리자 권한 시작 작업이 갈 곳이 없습니다.

App Service 관리형 인스턴스. 레거시 Windows 웹앱을 위해 만들어졌습니다. Microsoft의 개요에 따르면 "일부 지역에서 Windows 웹앱용으로 정식 출시"되었고, Pv4와 Pmv4 요금제로 제한되며, .NET Framework 3.5와 4.8이 미리 설치되어 있고, COM 구성 요소 등록, 레지스트리 키 작성, MSI 설치 프로그램 실행, IIS 구성을 할 수 있는 PowerShell 설치 스크립트를 제공합니다. 관리자 권한 시작 작업이 하던 일 대부분을 감당합니다. 한계는 이렇습니다. 웹앱 전용(WebJobs 없음), 컨테이너 없음, Entra ID와 관리 ID만 지원(도메인 가입, NTLM, Kerberos 없음), 그리고 이 글을 쓰는 시점에 목록에 있는 유럽 지역은 북유럽(North Europe)뿐입니다.

Container Apps. 작업자 역할이 최신 .NET으로 옮겨진 뒤라면 좋은 선택입니다. 대기열 기반 확장, 예약 작업과 이벤트 트리거 작업, 0까지 축소가 가능합니다. 하지만 컨테이너 요구 사항은 "Linux 기반(linux/amd64) 컨테이너 이미지가 필요하다"고 말합니다. .NET Framework 코드는 이식하기 전까지 여기서 실행되지 않습니다.

Azure Kubernetes Service. Windows 노드 풀에서 Windows Server 컨테이너를 실행하므로, .NET Framework 역할을 컨테이너화해 옮길 수 있습니다. 결정 매트릭스는 마이그레이션 복잡도와 운영 부담을 모두 높음으로 평가합니다. 이미 Kubernetes를 운영하고 있다면 맞지만, 레거시 앱 하나를 위해 처음 만드는 클러스터로는 맞지 않습니다.

Virtual Machine Scale Sets. 매트릭스는 이를 "Cloud Services 모델에 더 가까워 리프트 앤 시프트가 더 쉽다"고 설명합니다. VM은 돌아오지만, 역할이 대신 해 주던 패치, 이미지 빌드, IIS 설정도 함께 돌아옵니다.

Service Fabric 관리형 클러스터. Microsoft가 지목한 대상입니다. 작업자 역할은 깔끔하게 대응됩니다. 웹 역할은 그렇지 않은 경우가 많습니다. Service Fabric은 "IIS를 지원하지 않으며", 변환 가이드는 ASP.NET Web Forms를 지원하지 않는 것으로 분류하고 ASP.NET Core MVC로의 변환을 경로로 제시합니다. Service Fabric 마이그레이션 가이드는 관리형 클러스터가 "현재 컨테이너를 지원하지 않는다"고 덧붙이므로, IIS에 의존하는 앱에는 운영할 것이 더 많은 기존 방식의 클러스터가 필요합니다.

결정표

역할의 모습유력한 대상작업이 들어가는 곳
ASP.NET Web Forms나 MVC 5 웹 역할, 시작 작업이 간단하거나 없음App Service(Windows)설정, 인증서, 배포 파이프라인
시작 작업이 COM 구성 요소, MSI, 레지스트리 키를 설치하는 웹 역할App Service 관리형 인스턴스시작 작업을 설치 스크립트로 다시 작성, 지역과 요금제 확인
대기열을 폴링하는 .NET Framework 작업자 역할, 부하는 보통웹앱 옆의 WebJobRoleEntryPoint를 콘솔 호스트로 대체
최신 .NET으로 이식할 의향이 있는 작업자 역할Container Apps이식 자체, 그다음 컨테이너 이미지
역할이 많고 이미 Kubernetes를 운영하는 팀Windows 노드 풀을 쓰는 AKS이미지, 클러스터 운영
네이티브 의존성이 많고 코드 변경 의향이 없음VM Scale SetsOS 패치와 이미지 유지보수, 영구적으로
작업자 중심 시스템, 웹 계층은 이미 ASP.NET CoreService Fabric 관리형 클러스터플랫폼 학습, IIS 없음, 컨테이너 없음

코드에서 바뀌는 것

솔루션에서 Microsoft.WindowsAzure.ServiceRuntime을 검색하십시오. 이것을 가져오는 모든 파일이 작업 목록에 오릅니다.

RoleEntryPoint

작업자 역할은 RoleEntryPoint를 상속하고 OnStart, Run, OnStop을 재정의하는 클래스입니다. Run이 반환되면 인스턴스가 재활용됩니다. Service Fabric은 셋을 하나의 RunAsync로 합치며, 이 메서드는 "RunAsync 메서드의 CancellationToken에 신호가 오면" 멈춰야 합니다. App Service나 컨테이너에서는 같은 로직이 루프와 취소 토큰을 가진 콘솔 애플리케이션이나 호스팅된 백그라운드 서비스가 됩니다.

사람들이 놓치는 부분은 종료입니다. OnStop은 처리 중이던 메시지를 끝낼 틈을 주었습니다. 새 호스트가 취소 신호를 전달하는지, 그리고 처리 도중 중단된 메시지를 두 번 처리해도 안전한지 확인하십시오.

웹 역할에도 이런 클래스가 있는 경우가 많으며, 대개 WebRole.cs입니다. 그 OnStart가 무언가(IIS 조정, 캐시 예열)를 한다면 지우기 전에 무엇을 하는지 확인하십시오.

RoleEnvironment

RoleEnvironment.GetConfigurationSettingValue("Key")는 .cscfg에서 설정을 읽습니다. Cloud Services 밖에서는 아무것도 이것을 제공하지 않습니다. 무엇이든 옮기기 전에 모든 호출을 작은 설정 인터페이스 하나로 감싸고, 새 호스트에서는 그 인터페이스가 앱 설정, 환경 변수, Key Vault를 가리키게 하십시오. 프로젝트에서 가장 저렴한 변경이며, 나머지를 노트북에서 테스트할 수 있게 해 줍니다.

그 밖에 찾아볼 용도가 세 가지 있습니다.

  • RoleEnvironment.Changed: 재시작 없이 설정 변경을 적용했습니다. Service Fabric에는 대응하는 이벤트가 있습니다. 다른 곳에서는 설정 변경이 프로세스를 재시작한다고 가정하고, 그것이 처리 중인 작업에 어떤 영향을 주는지 테스트하십시오.
  • 예약 작업을 맡을 인스턴스 하나를 고르는 데 쓰인 RoleEnvironment.CurrentRoleInstance. 트리거된 WebJobs는 인스턴스 하나에서 실행되고, 연속 WebJobs는 제한하지 않으면 모든 인스턴스에서 실행됩니다. 명시적으로 정하십시오.
  • RoleEnvironment.IsAvailable 분기와 IsEmulated 분기. "클라우드" 경로와 "로컬" 경로를 나누는 분기이며, 그중 하나는 곧 죽은 코드가 됩니다.

.cscfg와 .csdef

.cscfg에는 환경별 설정, 인스턴스 수, 인증서 지문이 들어 있습니다. .csdef에는 엔드포인트, VM 크기, 로컬 스토리지, 시작 작업, 인증서 저장소, 그리고 때로는 웹 역할 하나 안의 여러 IIS 사이트가 들어 있습니다. 두 파일을 한 줄씩 살펴보며 각 항목이 이전 후 어디에 있게 될지 적어 두십시오. 앱 설정, Key Vault 참조, 인프라 코드, 또는 아무 데도 없음입니다. 역할끼리 직접 호출하게 해 주던 내부 엔드포인트는 서비스 주소나 대기열로 대체해야 합니다.

인증서

추가 지원이 이미 인증서를 Key Vault로 옮기게 했으므로 2024년 작업의 그 부분은 보람이 있습니다. 바뀌는 것은 코드가 인증서를 찾는 방식입니다. .csdef는 인증서를 이름이 붙은 저장소, 흔히 LocalMachine에 설치합니다. Windows App Service에서는 WEBSITE_LOAD_CERTIFICATES 설정이 인증서를 Current User\My에서 쓸 수 있게 합니다. LocalMachine 저장소를 여는 코드는 아무것도 찾지 못하고, 인증서가 필요한 첫 호출이 실패합니다. Linux 컨테이너에서는 그 대신 시작할 때 Key Vault에서 불러오십시오.

시작 작업

Startup.cmd를 여십시오. 뜻밖의 것들이 숨어 있는 곳이며, 대개 executionContext="elevated"로 실행됩니다. PDF 생성용 글꼴, COM 구성 요소, IIS 재작성 모듈, TLS를 위한 레지스트리 변경 같은 것들입니다. 각 줄의 운명은 세 가지 중 하나입니다. 더 이상 필요 없거나, 관리형 인스턴스의 설치 스크립트로 옮기거나, 컨테이너나 VM 이미지에 구워 넣습니다.

로컬 스토리지

.csdef의 LocalStorage 리소스를 RoleEnvironment.GetLocalResource로 읽으면 인스턴스마다 임시 디스크를 쓸 수 있었습니다. 진짜 임시 파일에는 플랫폼의 임시 디렉터리를 쓰십시오. 재시작 후에도 남아 있어야 하는 것은, 누군가 영구적이라고 가정했던 파일까지 포함해 Blob Storage로 보냅니다.

Web Forms

나머지를 좌우하는 결정입니다. Web Forms는 System.Web 위에 만들어졌고 ASP.NET Core 버전이 없으므로, Web Forms 애플리케이션을 Service Fabric이나 Container Apps로 옮긴다는 것은 사용자 인터페이스를 다시 작성한다는 뜻입니다. App Service, 관리형 인스턴스, Windows 컨테이너, Scale Sets는 모두 이를 그대로 실행할 수 있습니다. 있는 그대로 옮기고, 현대화는 자체 예산을 가진 별도 프로젝트로 만드십시오. UI 재작성은 종료일이 정해진 일정의 핵심 경로에 들어갈 일이 아닙니다.

나머지

두 클라우드 서비스 사이의 VIP 스왑은 App Service의 배포 슬롯이나 Container Apps의 리비전이 됩니다. 진단(WAD) 확장으로 보내던 로그는 새 목적지가 필요하며, 대개 Application Insights입니다. 표준 App Service와 Container Apps는 원격 데스크톱을 제공하지 않습니다. 관리형 인스턴스는 진단 목적에 한해 Azure Bastion을 통한 원격 데스크톱을 허용합니다.

6개월 계획

2027년 3월 31일부터 거꾸로 계산하며, 중간에 12월 연휴가 있습니다.

10월: 현황 파악과 대상 선택. 모든 추가 지원 배포를 나열합니다. 역할마다 .NET Framework 버전, Web Forms인지 MVC인지, 모든 RoleEnvironment 호출, 시작 작업, 로컬 스토리지 리소스, 인증서, 엔드포인트를 기록합니다. 그다음 불편한 부분을 확인합니다. 갖고 있는 소스로 배포된 패키지를 빌드할 수 있습니까? 외주 업체가 만든 시스템에서는 답이 아니오일 때가 있고, 그것을 알아낼 달이 10월입니다. 역할마다 대상을 고릅니다.

11월: 역할 하나를 처음부터 끝까지. 설정 래퍼를 추가하고, 대상 환경을 인프라 코드로 작성하고, 역할 하나(대개 가장 단순한 작업자)를 로그, 인증서, 파이프라인을 갖춘 테스트 환경에서 실행합니다.

12월과 1월: 나머지 이식. 진입점, 시작 작업, 로컬 스토리지를 대체합니다. 운영과 비슷한 데이터로 스테이징 환경에 부하 테스트를 합니다. WebJob이나 컨테이너는 전용 역할 VM의 처리량을 따라가지 못할 수 있습니다.

2월: 병행 운영. 새 환경을 실제 트래픽으로 돌립니다. 구 역할과 대기열을 공유하는 작업자라면 먼저 처리를 멱등하게 만들거나, 새 작업자를 시작하기 전에 구 작업자를 멈추십시오.

3월 초: 전환. 여유를 두고 DNS를 전환합니다. 구 배포는 1주에서 2주 동안 중지된 상태로 손대지 않고 두었다가 삭제합니다. 전환을 3월 마지막 주로 잡지 마십시오. 그때 전환에 실패하면 두 번째 기회가 없습니다.

1월에 시작한다면 현대화는 완전히 접으십시오. 코드 변경이 가장 적은 대상(App Service, 관리형 인스턴스, Scale Sets)을 골라 옮기고, 리팩터링은 그 뒤에 하십시오.

분명하지 않은 것

Microsoft는 이 서비스가 "완전히 종료"되며 "서비스 중단을 피하려면" 마이그레이션이 필요하다고 말합니다. 저희가 읽은 페이지들은 2027년 4월 1일에도 실행 중인 배포가 어떻게 되는지 말하지 않습니다. 직접 확인해 보겠다는 계획은 세우지 마십시오. 관리형 인스턴스의 지역과 요금제도 앞으로 몇 달 동안 바뀔 가능성이 크므로, 이 글이 아니라 결정하는 시점에 확인하십시오.

도움이 필요하시면

저희는 다른 사람이 만든 애플리케이션을 넘겨받아 어떻게 돌아가는지 파악하고 옮깁니다. 현황 파악, 역할별 대상, RoleEnvironment와 시작 작업 변경, 전환까지입니다. 레거시 시스템 유지보수 작업은 .NET Framework와 Web Forms를 다루며, 귀사 팀이 직접 마이그레이션을 하는데 일손이 더 필요하다면 인력 증강을 참고하십시오.

Cloud Services 배포가 있고 기한이 6개월 남았다면 office@c9group.dev로 연락 주십시오.