Azure DevOps Services
이 자습서에서는 CI/CD(지속적인 통합 및 지속적인 업데이트)를 위해 Azure Pipelines를 사용하여 Python 웹앱을 빌드하고 Linux의 Azure App Service에 배포하는 방법을 보여 줍니다. 앱 코드 리포지토리에 커밋이 있을 때마다 파이프라인이 자동으로 Python 웹앱을 빌드하고 App Service에 배포합니다.
이 자습서에서는 다음을 수행합니다.
- Python 웹앱을 만들고 Azure App Service에 업로드합니다.
- Azure DevOps 프로젝트를 Azure에 연결합니다.
- 앱에 대한 Azure Pipelines Python 관련 빌드 및 배포 파이프라인을 만듭니다.
- 파이프라인을 실행하여 Azure App Service 웹앱을 빌드, 테스트 및 배포합니다.
- 리포지토리에 커밋할 때마다 파이프라인을 실행하도록 트리거를 설정합니다.
Azure Pipelines 개념에 대해 자세히 알아보려면 다음 비디오를 시청하세요.
필수 구성 요소
| 제품 | 요구 사항 |
|---|---|
| Azure DevOps | - Azure DevOps 프로젝트. - Microsoft 호스팅 에이전트에서 파이프라인을 실행하는 기능입니다. 병렬 작업을 구매하거나 무료 계층을 요청할 수 있습니다. - YAML 및 Azure Pipelines에 대한 기본 지식 자세한 내용은 첫 번째 파이프라인만들기를 참조하세요. - 권한: - 파이프라인을 만들려면 참가자 그룹에 있어야 하며 그룹에 빌드 파이프라인 만들기 권한이 허용으로 설정되어 있어야 합니다. 프로젝트 관리자 그룹의 구성원은 파이프라인을 관리할 수 있습니다. 서비스 연결 |
| 깃허브 | - GitHub 계정입니다. - Azure Pipelines에 권한을 부여하는 GitHub 서비스 연결. |
| 하늘빛 | Azure 구독. |
| 제품 | 요구 사항 |
|---|---|
| Azure DevOps | - Azure DevOps 프로젝트. - 자체 호스팅 에이전트입니다. 에이전트를 만들려면 자체 호스팅 에이전트를 참조하세요. - YAML 및 Azure Pipelines에 대한 기본 지식 자세한 내용은 첫 번째 파이프라인만들기를 참조하세요. - 권한: - 파이프라인을 만들려면 참가자 그룹에 있어야 하며 그룹에 빌드 파이프라인 만들기 권한이 허용으로 설정되어 있어야 합니다. 프로젝트 관리자 그룹의 구성원은 파이프라인을 관리할 수 있습니다. 서비스 연결 |
| 깃허브 | - GitHub 계정입니다. - Azure Pipelines에 권한을 부여하는 GitHub 서비스 연결. |
| 하늘빛 | Azure 구독. |
자체 호스팅 에이전트 구성
Python 버전 다운로드는 자체 호스팅 빌드 에이전트에서 지원되지 않습니다. 자체 호스팅 에이전트를 사용하려면 Python을 실행하도록 에이전트를 구성해야 합니다.
호환성 문제를 방지하려면 Python 버전을 Azure App Services 웹앱 3.11 의 런타임 버전과 일치해야 합니다. Python 버전을 미리 설치해야 합니다. 전체 설치 관리자를 사용하여 Python의 pip 호환 버전을 가져옵니다.
파이프라인 태스크에서 사용할 수 있도록 원하는 Python 버전을 자체 호스팅 에이전트의 도구 캐시에 추가해야 합니다. 일반적으로 도구 캐시는 에이전트의 _work/_tool 디렉터리 아래에 있습니다. 또는 환경 변수 AGENT_TOOLSDIRECTORY를 사용하여 경로를 재정의할 수 있습니다. 도구 디렉터리 아래에서 Python 버전에 따라 다음 디렉터리 구조를 만듭니다.
$AGENT_TOOLSDIRECTORY/
Python/
{version number}/
{platform}/
{tool files}
{platform}.complete
버전 번호는 1.2.3 형식을 따라야 합니다. 플랫폼은 x86 또는 x64여야 합니다. 도구 파일은 압축을 푼 Python 버전 파일이어야 합니다.
{platform}.complete는 x86.complete이나 x64.complete처럼 보여야 하는 0바이트 파일로, 도구가 캐시에 제대로 설치되어 있음을 나타내야 합니다.
예를 들어 64비트 Windows 컴퓨터에서 Python 3.11을 사용하려면 다음 디렉터리 구조를 만듭니다.
$AGENT_TOOLSDIRECTORY/
Python/
3.11.4/
x64/
{python files}
x64.complete
에이전트를 호스팅하는 컴퓨터에 사용하려는 Python 버전이 이미 있는 경우 파일을 도구 캐시에 복사할 수 있습니다. Python 버전이 없는 경우 Python 웹 사이트에서 다운로드할 수 있습니다.
샘플 앱 준비
샘플 리포지토리 https://github.com/Microsoft/python-sample-vscode-flask-tutorial 를 GitHub 계정에 포크합니다.
를 사용하여
git clone <your-forked-repository-url>.git로컬 컴퓨터에 포크를 복제합니다.를 사용하여
cd python-sample-vscode-flask-tutorial로컬 클론으로 이동하여 로컬로 앱을 빌드하고 실행하여 작동하는지 확인합니다.python -m venv .env source .env/Scripts/activate pip install --upgrade pip pip install -r ./requirements.txt export FLASK_APP=hello_app.webapp flask run앱을 테스트하려면 브라우저 창으로 이동하여 http://localhost:5000Visual Studio Flask 자습서라는 제목이 표시되는지 확인합니다.
Ctrl+C를 사용하여 브라우저 창을 닫고 Flask 서버를 중지합니다.
App Service 웹앱 만들기 및 배포
Azure Portal에서 Cloud Shell 을 사용하여 Azure App Service 웹앱을 만듭니다. Cloud Shell을 사용하려면 Azure Portal 에 로그인하고 도구 모음에서 Cloud Shell 단추를 선택합니다.
Cloud Shell이 브라우저 아래쪽에 나타납니다. 드롭다운 메뉴에서 Bash 가 환경으로 선택되어 있는지 확인합니다. Cloud Shell 창을 최대화하여 더 많은 공간을 제공할 수 있습니다.
팁
Cloud Shell에 붙여넣려면 Ctrl+Shift+V 를 사용하거나 마우스 오른쪽 단추를 클릭하고 상황에 맞는 메뉴에서 붙여넣 기를 선택합니다.
웹앱 만들기 및 배포
Cloud Shell에서 다음 명령을 사용하여 포크된 리포지토리를 Azure에 복제하고 포크된 리포지토리의 URL로 대체
<your-forked-repository-url>합니다.git clone <your-forked-repository-url>디렉터리를 복제된 리포지토리 폴더로 변경합니다.
cd python-sample-vscode-flask-tutorialaz webapp up 명령을 실행하여 App Service 웹앱을 프로비전하고 첫 번째 배포를 수행합니다. 매개 변수를
--name <your-web-app-name>사용하여 앱 식별자와--name <your-name>-flaskpipelines함께 개인 또는 회사 이름과 같이 Azure에서 고유한 이름을 할당합니다. 매개 변수 없이 실행az webapp up은 Azure에서 고유한 임의로 생성된 웹앱 이름을 할당합니다.az webapp up --name <your-web-app-name>
이 az webapp up 명령은 앱을 Python 앱으로 인식하고 다음 작업을 수행합니다.
- 기본 리소스 그룹을 만듭니다.
- 기본 App Service 계획을 만듭니다.
- 할당된 이름을 사용하여 웹앱을 만듭니다. 앱
URL이 .입니다<your-web-app-name>.azurewebsites.net. - 빌드 자동화를 사용하도록 설정하여 현재 작업 디렉터리의 모든 파일을 ZIP 보관 파일에 배포합니다.
- . azure/config 파일에 로컬로 매개 변수를 캐시하므로 프로젝트 폴더
az webapp up또는 다른az webapp명령을 사용하여 배포할 때 매개 변수를 다시 지정할 필요가 없습니다. 이 명령은 기본적으로 캐시된 값을 자동으로 사용합니다.
명령 매개 변수를 사용하여 기본 작업을 사용자 고유의 값으로 재정의할 수 있습니다. 자세한 내용은 az webapp up을 참조하세요.
이 az webapp up 명령은 샘플 웹앱에 대해 다음 JSON 출력을 생성합니다.
{
"URL": <your-web-app-url>,
"appserviceplan": <your-app-service-plan-name>,
"location": <your-azure-region>,
"name": <your-web-app-name>,
"os": "Linux",
"resourcegroup": <your-resource-group>,
"runtime_version": "python|3.11",
"runtime_version_detected": "-",
"sku": <sku>,
"src_path": <repository-source-path>
}
이 자습서의 뒷 URL부분 resourcegroup에서 사용할 값 및 runtime_version 값을 기록합니다.
시작 명령 설정
python-sample-vscode-flask-tutorial 앱에는 웹앱에 대한 특정 시작 명령이 포함된 startup.txt 파일이 있습니다. 리소스 그룹 및 웹앱 startup-file 이름을 사용하여 다음 명령을 입력하여 웹앱 구성 속성을 startup.txt 설정합니다.
az webapp config set --resource-group <your-resource-group> --name <your-web-app-name> --startup-file startup.txt
명령이 완료되면 JSON 출력에 웹앱에 대한 모든 구성 설정이 표시됩니다.
실행 중인 앱을 보려면 브라우저를 열고 명령 출력에 URLaz webapp up 표시된 것으로 이동합니다. 일반 페이지가 표시되면 App Service가 시작될 때까지 몇 초 정도 기다린 다음 페이지를 새로 고칩니다.
Visual Studio Flask 자습서라는 제목이 표시되는지 확인합니다.
Azure DevOps 프로젝트를 Azure 구독에 연결
Azure Pipelines를 사용하여 Azure App Service 웹앱에 배포하려면 Azure DevOps 프로젝트를 Azure 리소스에 연결해야 합니다.
서비스 주체 만들기
서비스 주체는 Azure 리소스에 액세스하기 위해 애플리케이션, 호스트된 서비스 및 자동화된 도구에 대해 만든 ID입니다. 이 액세스는 서비스 주체에 할당된 역할로 제한되므로 어느 수준에서 어떤 리소스에 액세스할 수 있는지 제어할 수 있습니다.
서비스 주체를 만들려면 Bash Cloud Shell에서 다음 명령을 실행합니다. 서비스 주체의 이름, <service-principal-name> Azure 구독 ID 및 <your-subscription-id> 웹앱의 리소스 그룹으로 바꿉 <your-resource-group> 니다.
az ad sp create-for-rbac --display-name <service-principal-name> --role contributor --scopes /subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>
이 명령은 다음 JSON 개체를 반환합니다.
{
"appId": "<client GUID>",
"displayName": "<service-principal-name">,
"password": "<password-string>",
"tenant": "<tenant GUID>"
...
}
다음 섹션에서 서비스 연결을 만드는 데 사용할 값 및 appId 값을 기록해 둡다.passwordtenantId
서비스 연결 만들기
서비스 연결은 Azure Pipelines에서 외부 및 원격 서비스로의 인증된 액세스를 제공합니다. Azure App Service 웹앱에 배포하려면 웹앱의 리소스 그룹에 대한 서비스 연결을 만듭니다.
Azure DevOps 프로젝트 페이지에서 프로젝트 설정을 선택합니다.
프로젝트 설정에서 Pipelines>Service 연결을 선택합니다.
서비스 연결 페이지에서 새 서비스 연결을 선택하거나 이 서비스 연결이 프로젝트의 첫 번째 서비스인 경우 서비스 연결을 만듭니다.
새 서비스 연결 화면에서 Azure Resource Manager를 선택한 다음, 다음을 선택합니다.
새 Azure 서비스 연결 화면에서 ID 유형을 선택합니다. 이 예제에서는 앱 등록(자동)을 사용하는 것이 좋습니다. 인증 방법에 대한 자세한 내용은 Azure Resource Manager 서비스 연결을 사용하여 Azure에 연결을 참조하세요.
자격 증명의 경우 워크로드 ID 페더레이션(자동)을 선택합니다.
다음 필드를 완료합니다.
- 범위 수준: 구독을 선택합니다.
- 구독: Azure 구독을 선택합니다.
- 리소스 그룹: 웹앱을 포함하는 리소스 그룹을 선택합니다.
- 서비스 연결 이름: 연결에 대한 설명이 포함된 이름을 입력합니다.
- 모든 파이프라인에 액세스 권한 부여: 프로젝트의 모든 파이프라인에 대한 액세스 권한을 부여하려면 이 확인란을 선택합니다.
저장을 선택합니다.
Azure DevOps 프로젝트 페이지에서 프로젝트 설정을 선택합니다.
프로젝트 설정에서 Pipelines>Service 연결을 선택합니다.
서비스 연결 페이지에서 새 서비스 연결을 선택하거나 이 서비스 연결이 프로젝트의 첫 번째 서비스인 경우 서비스 연결을 만듭니다.
새 서비스 연결 화면에서 Azure Resource Manager를 선택한 다음, 다음을 선택합니다.
서비스 주체(수동)를 선택한 다음, 다음을 선택합니다.
새 Azure 서비스 연결 화면에서 다음 필드를 완료합니다.
- 환경: Azure Cloud를 선택합니다.
- 범위 수준: 구독을 선택합니다.
- 구독 ID: Azure 구독 ID를 입력합니다.
- 구독 이름: Azure 구독 이름을 입력합니다.
인증 섹션에서 다음 필드를 완료합니다.
-
서비스 주체 ID: 명령에서 반환된
appId값을 입력합니다az ad sp create-for-rbac. - 자격 증명: 서비스 주체 키를 선택합니다.
-
서비스 주체 키: 명령에서 반환된
password값을 입력합니다az ad sp create-for-rbac. -
테넌트 ID: 명령에서 반환된
tenant값을 입력합니다az ad sp create-for-rbac. - 확인을 선택하여 연결을 확인합니다.
-
서비스 주체 ID: 명령에서 반환된
세부 정보 섹션의 서비스 연결 이름 아래에 서비스 연결의 이름을 입력합니다.
모든 파이프라인에 액세스 권한 부여 확인란을 선택합니다.
확인 및 저장을 선택합니다.
새 연결이 서비스 연결 목록에 표시되고 파이프라인에서 사용할 준비가 된 것입니다.
파이프라인을 만듭니다.
Python 웹앱을 빌드하고 Azure 앱 Service에 배포하는 파이프라인을 만듭니다.
프로젝트의 왼쪽 탐색 메뉴에서 파이프라인을 선택합니다.
파이프라인 페이지에서 새 파이프라인을 선택하거나 이 파이프라인이 프로젝트의 첫 번째 파이프라인인 경우 파이프라인을 만듭니다.
코드의 위치 화면에서 GitHub를 선택합니다. GitHub에 로그인하라는 메시지가 표시될 수 있습니다.
리포지토리 선택 화면에서 포크된 샘플 리포지토리를 선택합니다. GitHub는 GitHub 암호를 다시 입력하거나 Azure Pipelines GitHub 앱을 설치하라는 메시지를 표시할 수 있습니다. 화면의 지침에 따라 앱을 설치합니다. 자세한 내용은 GitHub 앱 인증을 참조하세요.
파이프라인 구성 페이지에서 Azure에서 Python에서 Linux 웹앱으로 선택합니다.
다음 화면에서 Azure 구독을 선택하고 계속을 선택합니다.
다음 화면에서 Azure 웹앱을 선택하고 유효성 검사 및 구성을 선택합니다.
Azure Pipelines는 azure-pipelines.yml 파일을 만들고 YAML 파이프라인 편집기에서 표시합니다.
프로젝트의 왼쪽 탐색 메뉴에서 파이프라인을 선택합니다.
파이프라인 페이지에서 새 파이프라인을 선택하거나 이 파이프라인이 프로젝트의 첫 번째 파이프라인인 경우 파이프라인을 만듭니다.
코드 위치 페이지에서 GitHub Enterprise Server를 선택합니다. GitHub에 로그인하라는 메시지가 표시될 수 있습니다.
리포지토리 선택 탭에서 포크된 샘플 리포지토리를 선택합니다. GitHub는 GitHub 암호를 다시 입력하거나 Azure Pipelines GitHub 확장 또는 앱을 설치하라는 메시지를 표시할 수 있습니다. 화면의 지침에 따라 앱을 설치합니다. 자세한 내용은 GitHub 리포지토리에 대한 액세스를 참조 하세요.
파이프라인 구성 페이지에서 시작 파이프라인을 선택합니다.
파이프라인 YAML 검토 페이지에서 시작 azure-pipelines.yml 파일의 내용을 다음 YAML 파이프라인 파일로 바꿉니다. YAML 파일에서:
<your-service-connection-name>자리<your-web-app-name>표시자와 자리 표시자를 사용자 고유의 값으로 바꿉다.사용하려는 에이전트 풀의 이름으로 바꾸고 에이전트에서 실행되는 Python 버전으로 바
<your-pool-name>꿉<your-python-version>습니다. 이 버전은 명령의runtime_versionJSON 출력과az webapp up일치해야 합니다.
YAML 파이프라인 파일
파이프라인 YAML 검토 페이지에서 파이프라인을 확인하여 수행하는 작업을 확인합니다. 모든 기본 입력이 코드에 적합한지 확인합니다. 파이프라인 YAML 파일 스키마에 대한 자세한 내용은 YAML 스키마 참조를 참조하세요.
다음 전체 예제 YAML 파이프라인 파일은 CI/CD 파이프라인을 일련의 단계, 작업 및 단계로 정의합니다. 여기서 각 단계에는 다양한 작업 및 스크립트에 대한 세부 정보가 포함 됩니다. 생성된 YAML 코드는 자리 표시자를 앱 및 연결 값으로 자동으로 채웁니다.
trigger:
- main
variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<GUID>'
# Web app name
webAppName: '<your-webapp-name>'
# Agent VM image name
vmImageName: 'ubuntu-latest'
# Environment name
environmentName: '<your-webapp-name>'
# Project root folder. Point to the folder containing manage.py file.
projectRoot: $(System.DefaultWorkingDirectory)
pythonVersion: '3.11'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: BuildJob
pool:
vmImage: $(vmImageName)
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python $(pythonVersion)'
- script: |
python -m venv antenv
source antenv/bin/activate
python -m pip install --upgrade pip
pip install setuptools
pip install -r requirements.txt
workingDirectory: $(projectRoot)
displayName: "Install requirements"
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(projectRoot)'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
displayName: 'Upload package'
artifact: drop
- stage: Deploy
displayName: 'Deploy Web App'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: DeploymentJob
pool:
vmImage: $(vmImageName)
environment: $(environmentName)
strategy:
runOnce:
deploy:
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python version'
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : $(webAppName)'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
trigger:
- main
variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<your-service-connection-name>'
# Web app name
webAppName: '<your-web-app-name>'
# Environment name
environmentName: '<your-web-app-name>'
# Project root folder.
projectRoot: $(System.DefaultWorkingDirectory)
# Python version:
pythonVersion: '<your-python-version>'
stages:
- stage: Build
displayName: Build stage
jobs:
- job: BuildJob
pool:
name: '<your-pool-name>'
demands: python
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python $(pythonVersion)'
- script: |
python -m venv antenv
source antenv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txt
workingDirectory: $(projectRoot)
displayName: "Install requirements"
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(projectRoot)'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
- stage: Deploy
displayName: 'Deploy Web App'
dependsOn: Build
condition: succeeded()
jobs:
- deployment: DeploymentJob
pool:
name: '<your-pool-name'
environment: $(environmentName)
strategy:
runOnce:
deploy:
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '$(pythonVersion)'
displayName: 'Use Python version'
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : <your-web-app-name>'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
startUpCommand: 'startup.txt'
변수
YAML 파일의 시작 부분에 있는 섹션에서는 variables 다음 변수를 정의합니다.
| 변수 | 설명 |
|---|---|
azureServiceConnectionId |
Azure Resource Manager 서비스 연결의 ID입니다. |
webAppName |
App Service 웹앱의 이름입니다. |
vmImageName |
빌드 에이전트에 사용할 운영 체제의 이름입니다. |
environmentName |
배포 작업을 실행할 때 자동으로 만들어지는 배포할 환경의 이름입니다. |
projectRoot |
앱 코드가 포함된 루트 폴더입니다. |
pythonVersion |
빌드 및 배포 에이전트에서 사용할 Python 버전입니다. |
| 변수 | 설명 |
|---|---|
azureServiceConnectionId |
Azure Resource Manager 서비스 연결의 ID입니다. |
webAppName |
App Service 웹앱의 이름입니다. |
environmentName |
배포 작업을 실행할 때 자동으로 만들어지는 배포할 환경의 이름입니다. |
projectRoot |
앱 코드가 포함된 폴더입니다. 값은 자동 시스템 변수입니다. |
pythonVersion |
빌드 및 배포 에이전트에서 사용할 Python 버전입니다. |
빌드 및 배포 단계
파이프라인은 빌드 및 배포 단계로 구성됩니다.
빌드 단계
빌드 단계에는 변수에 정의된 운영 체제에서 vmImageName 실행되는 단일 작업(이 경우 ubuntu-latest)이 포함됩니다.
- job: BuildJob
pool:
vmImage: $(vmImageName)
빌드 단계에는 매개 변수로 식별된 에이전트에서 pool 실행되는 단일 작업이 포함됩니다 name .
키워드를 사용하여 에이전트 기능을 demands 지정할 수 있습니다. 예를 들어 demands: python 에이전트에 Python이 설치되어 있어야 한다고 지정합니다. 이름으로 demands: Agent.Name -equals <agent-name>자체 호스팅 에이전트를 지정하려면 .
- job: BuildJob
pool:
name: <your-pool-name>
demands: python
작업에는 다음과 같은 여러 단계가 포함됩니다.
먼저 UsePythonVersion 작업은 변수에 정의된
pythonVersion대로 사용할 Python 버전을 선택합니다.- task: UsePythonVersion@0 inputs: versionSpec: '$(pythonVersion)' displayName: 'Use Python $(pythonVersion)'다음 단계에서는 가상 Python 환경을 만들고 앱의 종속성을 설치하는 스크립트를
requirements.txt사용합니다. 매개 변수는workingDirectory앱 코드의 위치를 지정합니다.- script: | python -m venv antenv source antenv/bin/activate python -m pip install --upgrade pip pip install setuptools pip install -r ./requirements.txt workingDirectory: $(projectRoot) displayName: "Install requirements"ArchiveFiles 작업은 빌드된 웹앱을 포함하는 ZIP 보관 파일을 만듭니다.
- task: ArchiveFiles@2 displayName: 'Archive files' inputs: rootFolderOrFile: '$(projectRoot)' includeRootFolder: false archiveType: zip archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip replaceExistingArchive: true매개 변수는 다음과 같이 설정됩니다.
매개 변수 설명 rootFolderOrFile앱 코드의 위치입니다. includeRootFolder.zip 파일에 루트 폴더를 포함할지 여부입니다. false로 설정합니다. 이 폴더로true설정하면 .zip 파일의 내용 이 s 폴더 에 저장되고 작업에서 앱 코드를 찾을 수 없습니다.archiveType생성할 아카이브의 유형입니다. zip로 설정합니다.archiveFile.zip 파일을 만들 위치입니다. replaceExistingArchive파일이 이미 있는 경우 기존 보관 파일을 바꿀지 여부를 나타냅니다. true로 설정합니다.그런 다음 파일이
.zip파이프라인에 라는drop아티팩트로 업로드됩니다. 배포 단계에서는 .zip 파일을 사용하여 앱을 배포합니다.- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip displayName: 'Upload package' artifact: drop- 매개 변수는
upload업로드할 .zip 파일의 위치와 이름을 설정합니다. - 매개 변수는
artifact만든 아티팩트 이름을 .로drop설정합니다.
- 매개 변수는
배포 단계
빌드 단계가 성공적으로 완료되면 배포 단계가 실행됩니다. 및 dependsOn 키워드는 condition 이 동작을 정의합니다.
dependsOn: Build
condition: succeeded()
배포 단계에는 다음과 같이 구성된 단일 배포 작업이 포함됩니다.
- deployment: DeploymentJob
pool:
vmImage: $(vmImageName)
environment: $(environmentName)
- deployment: DeploymentJob
pool:
name: <your-pool-name>
environment: $(environmentName)
키워드는 strategy 배포 전략을 정의합니다.
strategy:
runOnce:
deploy:
steps:
- 키워드는
runOnce배포 작업이 한 번 실행되도록 지정합니다. - 키워드는
deploy배포 작업에서 실행할 값을 지정합니다steps.
이 단계에서는 steps 다음 작업을 실행합니다.
- UsePythonVersion@0빌드 단계와 마찬가지로 사용할 Python 버전을 선택합니다.
-
AzureWebApp@1 웹앱 및 ZIP 아티팩트
drop배포
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : <your-web-app-name>'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
- 매개 변수는
azureSubscriptionazureServiceConnectionId파이프라인 변수에 지정된 것을 포함합니다. - 변수
appName의webAppName값을 포함합니다. -
package배포할 .zip 파일의 이름과 위치를 지정합니다.
또한 python-vscode-flask-tutorial 리포지토리에는 startup.txt파일의 앱 시작 명령이 포함되어 있으므로 매개 변수 startUpCommand: 'startup.txt'를 추가하여 앱 시작 명령을 지정할 수 있습니다.
파이프라인 실행
이제 파이프라인을 사용해 볼 준비가 되었습니다.
파이프라인 편집기에서 저장 및 실행을 선택합니다.
저장 및 실행 화면에서 원하는 경우 커밋 메시지를 추가한 다음 저장 및 실행을 선택합니다.
파이프라인 요약 페이지에서 스테이지 또는 작업을 선택하여 파이프라인 실행을 볼 수 있습니다. 각 작업 및 스테이지는 성공적으로 완료되면 녹색 확인 표시를 표시합니다. 오류가 발생하면 요약 또는 작업 단계에 표시됩니다.
요약 페이지의 오른쪽 위에 있는 세로 점을 선택하고 파이프라인 편집을 선택하여 YAML 편집기로 빠르게 돌아갈 수 있습니다.
배포 작업에서 Azure Web App 배포 작업을 선택하여 출력을 표시합니다.
출력에서 App Service 애플리케이션 URL 뒤에 있는 URL을 선택합니다. 앱은 다음과 같이 표시됩니다.
참고
종속성 누락으로 인해 앱 배포가 실패하는 경우 배포 중에 requirements.txt 파일이 처리되지 않습니다. 이 문제는 명령을 사용하는 az webapp up 대신 포털에서 직접 웹앱을 만드는 경우에 발생할 수 있습니다.
이 az webapp up 명령은 빌드 작업 SCM_DO_BUILD_DURING_DEPLOYMENT을 true로 설정합니다. 포털을 통해 앱 서비스를 프로비전하는 경우 이 작업은 자동으로 설정되지 않습니다.
이 작업을 설정하려면 다음을 수행합니다.
- 웹앱의 포털 페이지에서 왼쪽 탐색 메뉴에서 구성 을 선택합니다.
- 애플리케이션 설정 탭에서 새 애플리케이션 설정을 선택합니다.
- 팝업이 나타나면 이름을
SCM_DO_BUILD_DURING_DEPLOYMENT로 설정하고, 값을true로 설정한 뒤, 확인을 선택합니다. - 구성 페이지의 맨 위에 있는 저장을 선택합니다.
- 파이프라인 다시 실행 이제 배포 중에 종속성이 설치되어야 합니다.
파이프라인 실행을 트리거하세요
이 파이프라인은 변경 내용이 코드 리포지토리에 체크 인할 때마다 실행되도록 설정됩니다. 파이프라인 실행을 트리거하려면 리포지토리에 변경 내용을 커밋합니다. 예를 들어 앱에 새 기능을 추가하거나 앱의 종속성을 업데이트할 수 있습니다.
- 앱의 GitHub 리포지토리로 이동합니다.
- 앱의 제목 변경과 같이 코드를 변경합니다.
- 변경 내용을 커밋합니다.
- 파이프라인으로 이동하여 새 실행이 만들어지고 실행 중인지 확인합니다.
- 실행이 완료되면 변경 내용이 웹앱에 배포되었는지 확인합니다.
- Azure Portal에서 웹앱으로 이동하여 왼쪽 탐색 메뉴에서 배포 센터를 선택합니다.
- 로그 탭 을 선택하고 새 배포가 나열되었는지 확인합니다.
App Service에 Django 앱 배포
별도의 데이터베이스를 사용하는 경우 Azure Pipelines를 사용하여 Linux의 App Service에 Django 앱을 배포할 수 있습니다. App Service에서 db.sqlite3 파일을 잠가 읽기 및 쓰기를 모두 차단하므로 SQLite 데이터베이스를 사용할 수 없습니다. 이 동작은 외부 데이터베이스에 영향을 주지 않습니다.
컨테이너 시작 프로세스에서 설명한 대로 App Service는 앱 코드에서 일반적으로 앱 개체를 포함하는 wsgi.py 파일을 자동으로 찾습니다. 시작 명령을 사용자 지정하려면 YAML 파이프라인 파일의 단계에서 매개 변수를 startUpCommand 사용합니다AzureWebApp@1.
Django를 사용하는 경우 일반적으로 앱 코드를 배포한 후 사용하여 manage.py migrate 데이터 모델을 마이그레이션하려고 합니다. 이 목적을 위해 배포 후 스크립트를 사용하여 추가할 startUpCommand 수 있습니다. 예를 들어 AzureWebApp@1 작업의 속성은 다음과 같습니다 startUpCommand .
- task: AzureWebApp@1
displayName: 'Deploy Azure Web App : $(webAppName)'
inputs:
azureSubscription: $(azureServiceConnectionId)
appName: $(webAppName)
package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
startUpCommand: 'python manage.py migrate'
빌드 에이전트에서 테스트 실행
빌드 프로세스의 일부로 앱 코드에서 테스트를 실행할 수 있습니다. 테스트는 빌드 에이전트에서 실행되므로 빌드 에이전트의 가상 환경에 종속성을 설치해야 합니다. 테스트를 실행한 후 배포할 .zip 파일을 만들기 전에 테스트 가상 환경을 삭제합니다.
다음 스크립트 요소는 이 프로세스를 보여 줍니다.
ArchiveFiles@2 파일의 작업 앞에 배치합니다. 자세한 내용은 플랫폼 간 스크립트 실행을 참조 하세요.
# The | symbol is a continuation character, indicating a multi-line script.
# A single-line script can immediately follow "- script:".
- script: |
python -m venv .env
source .env/bin/activate
pip install setuptools
pip install -r requirements.txt
# The displayName shows in the pipeline UI when a build runs
displayName: 'Install dependencies on build agent'
- script: |
# Put commands to run tests here
displayName: 'Run tests'
- script: |
echo Deleting .env
deactivate
rm -rf .env
displayName: 'Remove .env before zip'
PublishTestResults@2 같은 작업을 사용하여 테스트 결과를 파이프라인에 게시할 수도 있습니다. 자세한 내용은 테스트 실행을 참조하세요.
리소스 정리
이 자습서에서 만든 Azure 리소스를 완료한 경우 추가 요금이 발생하지 않도록 삭제합니다.
- 만든 Azure DevOps 프로젝트를 삭제합니다. 프로젝트를 삭제하면 파이프라인 및 서비스 연결이 삭제됩니다.
- App Service 및 App Service 계획을 포함하는 Azure 리소스 그룹을 삭제합니다. Azure Portal에서 리소스 그룹으로 이동하여 리소스 그룹 삭제를 선택하고 프롬프트를 따릅니다.
- Cloud Shell 파일 시스템을 유지 관리하는 Azure Storage 계정을 삭제합니다. Cloud Shell을 닫은 다음 cloud-shell-storage-로 시작하는 리소스 그룹을 찾습니다. 리소스 그룹 삭제를 선택하고 프롬프트를 따릅니다.