PowerShell에서 Azure WebJobs를 실행하려고했을 때 생각 외에도 힘들었습니다.
하고 싶은 일
Azure Web App의 무료 플랜으로 웹 앱을 공개하고 있는데, 이 웹 앱에 대해 정기적으로 백업을 위한 스크립트를 움직이고 싶었다.
이런 때에 사용할 수 있는 편리한 기능으로 WebJobs가 있습니다만, 불행히도 무료 플랜에서는 수동 실행만으로, 스케줄 실행을 할 수 없습니다.
그러나 WebJobs는 WebHook을 사용하여 외부에서 작업을 실행할 수 있습니다.
이것을 이용해 외부에서 PowerShell 스크립트로 실행시키는 것으로, 무료 플랜에서도 정기적으로 실행을 할 수 있을까 생각했습니다.
준비
전제로 실행하려는 WebJobs 태스크를 작성했다고 가정합니다.
Azure 포털에서 만든 작업의 속성을 보려면 WebHook을 실행하는 데 필요한 정보(URL, 사용자 이름, 비밀번호)를 작성했으므로 주의해야 합니다.
먼저 해본 것
WebHook URL에 대해 BASIC 인증으로 POST하면 좋을 뿐이므로,
낙승이다! 라고 생각해서 이렇게 썼습니다.
$Cred = New-Object 'System.Management.Automation.PsCredential' $UserName, (ConvertTo-SecureString -AsPlainText -Force -String $Password)
Invoke-RestMethod -Uri $WebHookURL -Method Post -Credential $Cred
그런데 잘 작동하지 않습니다.
Error 403 - This web app is stopped.
PowerShell이 아닌 방법이라면 가능했습니다.
매개 변수를 확인하거나 스크립트를 괴롭히는 것이 좋지 않으므로 한 번 PowerShell 이외의 방법으로 시도하기로 결정했습니다.
REST 클라이언트(Chrome 앱의 YARC!)를 사용하여 POST를 던져보세요.
그러면 이것은
202 - Accepted
가 돌아와서 성공했습니다. 작업도 확실히 실행되었습니다.그렇다면 역시 문제는 PowerShell에있는 것 같습니다. 우~무・・・
유력한 정보 발견
완전히 막혀 포기하고 있었는데, 유력한 정보를 발견했습니다.
언제든지 WebJob을 실행하기위한 API가 Kudu에 제공됩니다. (중략)
그러나 처음부터 Authentication 헤더를 보내야 하므로 주의해야 합니다.
As noted in the comments, this method will not send the Authorization header on the initial request. It waits for a challenge response then re-sends the request with the Authorization header. This will not work for services that require credentials on the initial request.
흠흠. 처음부터 Authorization 헤더를 송신하지 않으면 안되지만, PowerShell의
Invoke-RestMethod
는 그러한 사양은 되어 있지 않다고. 분명히 이것이 원인 인 것 같습니다.이게 어때?
상기의 Stack Overflow에 회피책의 샘플 코드가 기재되어 있었으므로, 고맙게 copipe 해 주셔서 이러한 코드가 되었습니다.
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $UserName,$Password)))
Invoke-RestMethod -Uri $WebHookURL -Method Post -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -ContentType "application/json"
이것을 실행하면 성공적으로 성공했습니다.
Azure 포털에서 확인하면 배치 WebJobs가 실행 중입니다.
결국 이렇게
일단 이것으로 PowerShell에서 WebJobs를 실행시키는 데 성공했지만
Invoke-RestMethod
는 실행 후 아무것도 값을 반환하지 않기 때문에 성공했는지 확실히 불안합니다.그래서 명령을
Invoke-WebRequest
로 바꾸거나 궁극적으로는 이러한 스크립트로 완성했습니다.# Authorizationヘッダー用の資格情報作成
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $UserName, $Password)))
try {
# POST実行
$Response = Invoke-WebRequest -Uri $WebHookURL -Method Post -Headers @{Authorization = ("Basic {0}" -f $base64AuthInfo)} -ContentType "application/json" -UseBasicParsing -ErrorAction Stop
}
catch {
$Response = $_.Exception.Response
}
# 成否確認
if ([int]$Response.StatusCode -ne 202) {
Write-Error ('Job execution failed - Expected status is "202(Accepted)", but status "{0}({1})" has returned.' -f [int]$Response.StatusCode, $Response.StatusDescription)
}
else {
Write-Host ('Job started successfully.')
}
이 스크립트를 태스크 스케줄러를 사용해 매일 실행해 주는 것으로, 무료 플랜인 채로 스케줄 실행을 할 수 있습니다.
감상
30초에 바삭바삭할 수 있을까 생각했는데, 갓트리 함정에 빠져 버려서 힘들었습니다.
Reference
이 문제에 관하여(PowerShell에서 Azure WebJobs를 실행하려고했을 때 생각 외에도 힘들었습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/mkht/items/b7d4077c8d991350a577텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)