연습 - 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을 선택하여 배포된 사이트를 확인합니다.
사이트가 App Service에서 실행되는 페이지가 표시됩니다. 아래로 스크롤하여 순위표에 실제 데이터가 있는지 확인합니다. 해당 데이터는 함수 앱에 의해 제공됩니다.
참고
순위표를 로드하는 동안 오류가 발생하는 경우 이 모듈에서 수행한 단계를 다시 확인하세요. “해당 액세스 권한에 의해 금지된 방식으로 소켓에 액세스하려고 시도했습니다.”라는 예외 프롬프트가 표시되면 앱 서비스의 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: 아주 좋네요. 모든 사람이 여기서 우리가 보여 준 가능성에 깊은 인상을 받을 거예요.