연습 - Azure에 Azure Functions 앱 배포
프로젝트에는 솔루션에서 프로젝트를 빌드하고 웹앱을 Azure App Service에 배포하는 파이프라인이 함께 제공되었습니다. 이제 해당 파이프라인을 확장하여 새 Azure Functions 프로젝트도 배포해 보겠습니다.
이 부분에서는 다음 작업을 수행합니다.
- ‘빌드’ 단계를 검토합니다.
- 함수 앱을 배포하는 작업을 추가합니다.
- 게시된 함수를 사용하도록 게시된 App Service를 구성하는 작업을 추가합니다.
- 파이프라인을 저장하여 CI/CD 워크플로를 트리거합니다.
빌드 단계 검토
여기서는 azure-pipelines.yml 정의된 기존 CI/CD 파이프라인을 검토합니다.
Azure DevOps에서 Pipelines로 이동합니다.
파이프라인을 선택합니다.
편집을 선택합니다. 드롭다운 메뉴에서 분기를 선택하여 분기가 기본으로 설정되어 있는지 확인합니다. 그러면 기존 CI/CD 파이프라인을 정의한 azure-pipelines.yml 파일이 표시됩니다.
프로젝트 경로에 와일드카드를 사용하기 때문에 이 파일의 강조 표시된 작업은 새 Azure Functions 프로젝트를 자동으로 복원, 빌드 및 게시합니다.
stages: - stage: 'Build' displayName: 'Build the web application' jobs: - job: 'Build' displayName: 'Build job' pool: vmImage: 'ubuntu-20.04' demands: - npm variables: wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot' dotnetSdkVersion: '6.0.x' steps: - task: UseDotNet@2 displayName: 'Use .NET SDK $(dotnetSdkVersion)' inputs: version: '$(dotnetSdkVersion)' - task: Npm@1 displayName: 'Run npm install' inputs: verbose: false - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)' displayName: 'Compile Sass assets' - task: gulp@1 displayName: 'Run gulp tasks' - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt' displayName: 'Write build info' workingDirectory: $(wwwrootDir) - task: DotNetCoreCLI@2 displayName: 'Restore project dependencies' inputs: command: 'restore' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Build the project - $(buildConfiguration)' inputs: command: 'build' arguments: '--no-restore --configuration $(buildConfiguration)' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Publish the project - $(buildConfiguration)' inputs: command: 'publish' projects: '**/*.csproj' publishWebProjects: false arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)' zipAfterPublish: true - publish: '$(Build.ArtifactStagingDirectory)' artifact: drop
Andy: 여기까지가 이전의 빌드 단계였습니다. 작업이 이미 와일드카드 일치 패턴을 기반으로 모든 프로젝트에 대해 실행되도록 구성되었기 때문에 원래 프로젝트에서 코드를 변경하지 않았어요.
Mara: 예, 이것은 있는 그대로 작동해요. 여기서 변경할 필요가 없다고 생각해요. 이 빌드 작업이 실행된 후 웹과 순위표 프로젝트 모두에 대한 zip 파일 아티팩트가 배포 단계에서 사용될 수 있도록 게시될 거예요.
Azure Functions를 배포하는 작업 추가
Andy: App Service 배포 작업을 있는 그대로 재사용할 수도 있을 것 같은데요. 함수 앱을 배포하는 데 사용할 수 있는 비슷한 것이 있으면 좋겠네요.
Mara: 좋은 소식이 있어요. 조사를 조금 해보니까 App Service 배포 작업과 개념적으로 비슷하지만 Azure Functions 배포를 위한 작업이 있는 것 같아요. 이제 이를 검토해 보겠습니다.
Azure 함수 앱 작업
AzureFunctionApp@1 작업은 함수 앱을 배포하도록 설계되었습니다. 해당 작업은 개념적으로 AzureWebApp@1 작업과 비슷하며, 다음과 같이 이 함수 앱 시나리오에 필요한 모든 것을 포함하고 있습니다.
azureSubscription은 Azure 서비스 연결 파이프라인 변수의 이름을 나타냅니다.appType은 앱이 Linux(functionAppLinux)용으로 배포되는지 또는 Windows(functionApp)용으로 배포되는지를 나타냅니다.appName은 Azure 계정에서 Azure Functions 앱 인스턴스의 이름을 지정합니다.package는 배포할 패키지의 경로를 지정합니다.runtimeStack은 Linux 배포에 필요한 함수가 실행되어야 하는 이미지를 나타냅니다.startUpCommand는 Linux 배포에 필요한 함수가 배포된 후 실행할 시작 명령을 지정합니다.
Azure 함수 앱 작업에 관한 설명서에서 이 작업의 유연성에 대해 자세히 알아볼 수 있습니다.
아래에 강조 표시된 코드를 파이프라인 끝에 추가합니다.
- stage: 'Deploy'
displayName: 'Deploy the web application'
dependsOn: Build
jobs:
- deployment: Deploy
pool:
vmImage: 'ubuntu-20.04'
environment: spike
variables:
- group: Release
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: drop
- task: AzureWebApp@1
displayName: 'Azure App Service Deploy: website'
inputs:
azureSubscription: 'Resource Manager - Tailspin - Space Game'
appName: '$(WebAppName)'
appType: webAppLinux
package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/Tailspin.SpaceGame.Web.zip'
- task: AzureFunctionApp@1
displayName: 'Azure Function Deploy: leaderboard'
inputs:
azureSubscription: 'Resource Manager - Tailspin - Space Game'
appType: functionAppLinux
appName: '$(LeaderboardAppName)'
package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/Tailspin.SpaceGame.LeaderboardFunction.zip'
runtimeStack: DOCKER|microsoft/azure-functions-dotnet:4
startUpCommand: 'func azure functionapp publish $(functionAppName) --no-bundler'
팁
YAML 파일에서 공백은 중요합니다. 여기서 추가하는 작업이 이전 작업과 동일한 들여쓰기를 사용하는지 확인해야 합니다.
App Service의 앱 설정을 업데이트하는 작업 추가
Andy: 이제 게시된 순위표 API를 사용하도록 웹앱을 구성하기만 하면 됩니다. 일반적으로 포털에서 변수를 구성하지만 여기서 구성할 수 있다면 더 좋겠어요. 그러려면 LeaderboardFunctionUrl라는 AppSettings 매개 변수가 필요해요.
Mara: 동의해요. 이를 위한 작업을 파이프라인에 추가하면 어느 한 서비스를 변경하더라도 장래의 우발적인 실수를 방지할 수 있을 거예요. 우리는 끝에 바로 넣을 수 있어요.
아래에 강조 표시된 코드를 파이프라인 끝에 추가합니다. 그 위에 있는 작업의 들여쓰기와 일치해야 합니다. 이 작업에 대해 자세히 알아보려면 Azure App Service 설정 작업에 대한 설명서를 검토하세요.
- task: AzureFunctionApp@1
displayName: 'Azure Function Deploy: leaderboard'
inputs:
azureSubscription: 'Resource Manager - Tailspin - Space Game'
appType: functionAppLinux
appName: '$(LeaderboardAppName)'
package: '$(Pipeline.Workspace)/drop/$(buildConfiguration)/Tailspin.SpaceGame.LeaderboardFunction.zip'
runtimeStack: DOCKER|microsoft/azure-functions-dotnet:4
startUpCommand: 'func azure functionapp publish $(functionAppName) --no-bundler'
- task: AzureAppServiceSettings@1
displayName: 'Update web app settings'
inputs:
azureSubscription: 'Resource Manager - Tailspin - Space Game'
appName: $(WebAppName)
resourceGroupName: $(ResourceGroupName)
appSettings: |
[
{
"name": "AppSettings__LeaderboardFunctionUrl",
"value": "http://$(LeaderboardAppName).azurewebsites.net/api/LeaderboardFunction",
"slotSetting": false
}
]
파이프라인을 저장하여 빌드 및 릴리스 트리거
페이지 오른쪽 상단 모서리에서 Save를 선택합니다. Save를 확인하여 실행을 트리거합니다.
Azure Pipelines에서 빌드로 이동합니다. 실행되는 빌드를 추적합니다.
빌드가 성공하면 웹 사이트의 배포 작업을 선택하고 URL을 선택하여 배포된 사이트를 확인합니다.
웹 사이트 URL의 위치를 보여 주는 Azure Pipelines의 스크린샷.
App Service에서 실행되는 사이트가 있는 페이지가 표시됩니다. 아래로 스크롤하여 순위표에 실제 데이터가 있는지 확인합니다. 이 기능은 함수 앱에서 구동됩니다.
Space Game 웹 사이트의 스크린샷.
참고
순위표를 로드하는 동안 오류가 발생하는 경우 이 모듈에서 수행한 단계를 다시 확인하세요. “해당 액세스 권한에 의해 금지된 방식으로 소켓에 액세스하려고 시도했습니다.”라는 예외 프롬프트가 표시되면 앱 서비스의 AppSettings__LeaderboardFunctionUrl 설정이 올바르게 설정되어 있는지 확인하세요.
함수 앱을 직접 테스트할 수도 있습니다. 다음 형식을 사용하여 URL로 이동하면 됩니다. 응답은 JSON으로, 브라우저에서 텍스트로 렌더링됩니다.
http://<leaderboard function name>.azurewebsites.net/api/LeaderboardFunction?pageSize=10예:
http://tailspin-space-game-leaderboard-4692.azurewebsites.net/api/LeaderboardFunction?pageSize=10
Andy: 아주 좋네요. 모든 사람이 여기서 우리가 보여 준 가능성에 깊은 인상을 받을 거예요.