Microsoft MVP성태의 닷넷 이야기
.NET Framework: 1998. Azure Functions를 사용한 간단한 실습 [링크 복사], [링크+제목 복사],
조회: 15847
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 7개 있습니다.)
기타: 46. Microsoft의 응용 프로그램을 클라우드로 제공하는 서비스 - Azure RemoteApp 소개
; https://www.sysnet.pe.kr/2/0/1672

Java: 22. Azure - 자바(Java)로 만드는 Web App Service - Java SE (Embedded Web Server) 호스팅
; https://www.sysnet.pe.kr/2/0/12686

Java: 23. Azure - 자바(Java)로 만드는 Web App Service - Tomcat 호스팅
; https://www.sysnet.pe.kr/2/0/12690

.NET Framework: 1998. Azure Functions를 사용한 간단한 실습
; https://www.sysnet.pe.kr/2/0/13037

개발 환경 구성: 736. 파이썬 웹 앱을 Azure App Service에 배포하기
; https://www.sysnet.pe.kr/2/0/13830

개발 환경 구성: 749. 파이썬 - Azure App Service에 응용 프로그램 배포하기 전의 환경
; https://www.sysnet.pe.kr/2/0/13946

개발 환경 구성: 750. 파이썬 - Azure App Service에 응용 프로그램 배포 후의 환경
; https://www.sysnet.pe.kr/2/0/13947




Azure Functions를 사용한 간단한 실습

오늘은 부담없이, ^^ 간단하게 Azure Function을 실습해 볼까요?

사실 Visual Studio 환경에서는 매우 쉽게 테스트해 볼 수 있습니다. 우선, 프로젝트 자체를 "Azure Functions"로 시작해,

azure_func_1.png

중간에 선택하는 응용 프로그램 유형에서 (이번 실습은 웹 요청에 반응할 것이므로) "Http trigger"를 선택하면,

azure_func_2.png

기본적으로 다음과 같은 코드를 포함하는 프로젝트가 열립니다.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace FunctionApp1
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}

제가 원하는 기능은 클라이언트의 공용 IP를 출력하는 것이므로 Function1을 다음과 같이 수정하면 됩니다.

[FunctionName("Function1")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string userHostAddress = req.HttpContext.Connection.RemoteIpAddress.ToString(); 
    string ip = req.Headers["HTTP_X_FORWARDED_FOR"];

    if (string.IsNullOrEmpty(ip) == false)
    {
        userHostAddress = ip;
    }

    return new OkObjectResult(userHostAddress);
}

이렇게 바꾸고 곧바로 F5 키를 눌러 디버깅을 실행하면 Local PC에서 Emulator가 구동되면서 다음과 같은 출력의 콘솔 창이 뜹니다.

Azure Functions Core Tools
Core Tools Version:       4.0.4483 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.1.3.17473

[2022-04-18T04:33:25.113Z] Found C:\temp\FunctionApp1\FunctionApp1\FunctionApp1.csproj. Using for user secrets file configuration.

Functions:

        Function1: [GET,POST] http://localhost:7071/api/Function1

For detailed output, run func with --verbose flag.

따라서 웹 브라우저를 이용해 "http://localhost:7071/api/Function1" URL로 요청을 보내면, 콘솔에는 다음과 같은 식의 디버깅 로그가 찍히고,

[2022-04-18T04:54:04.785Z] Executing 'Function1' (Reason='This function was programmatically called via the host APIs.', Id=f13d0c90-2f8e-4424-ad94-eeca81759aa3)
[2022-04-18T04:54:06.632Z] C# HTTP trigger function processed a request.
[2022-04-18T04:54:06.646Z] Executed 'Function1' (Succeeded, Id=f13d0c90-2f8e-4424-ad94-eeca81759aa3, Duration=1871ms

화면에는 (로컬에서 테스트했으므로) "127.0.0.1"이 찍히는 것을 확인할 수 있습니다.




이렇게 로컬에서도 실행 및 테스트를 할 수 있으므로 개발이 어렵지 않습니다. 이후, Azure로의 배포는 솔루션 탐색기의 프로젝트 노드를 우 클릭해 나오는 "Publish" 메뉴를 선택, Azure에서 준비한 다양한 환경을 대상으로 배포할 수 있습니다.

azure_func_3.png

Azure 측에 미리 Function App 서비스를 하나 만들어 두거나, 위의 배포 창에서 제공하는 기능을 이용해 즉석에서 만들어도 됩니다.

Azure Function App 서비스는 겉으로는 별도의 서비스인 듯하지만, 내부적으로는 결국 Azure Web App Services와 다를 바가 없습니다. 실제로 호스팅되는 기본 URL도 사용자가 지정한 이름 외에 "azurewebsites.net"가 붙기도 합니다. 그러니까 전체적인 서비스 형태는 기존의 App Services를 Function App 유형으로 확장한 것에 불과합니다.

배포 후 사용법을 볼까요?

가령 사용자의 Function App URL이 다음과 같이 정해진 경우라면,

https://publicipfuncapp.azurewebsites.net/

이 글의 예제에서 작성한 코드는 다음과 같은 경로로 호출할 수 있습니다.

https://publicipfuncapp.azurewebsites.net/api/Function1

그런데, 실제로 저렇게 호출하면 "HTTP ERROR 401" 오류가 발생합니다.

This page isn’t working right now
If the problem continues, contact the site owner.
HTTP ERROR 401

왜냐하면, 해당 Function1에 대해 소스 코드에서 보면 AuthorizationLevel이 Function으로 되어 있기 때문입니다.

[FunctionName("Function1")]
public static async Task&lt;IActionResult&gt; Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    ILogger log)

저 값을 "AuthorizationLevel.Anonymous"로 바꾸고 다시 시도하면 이제는 정상적으로 Function1 코드가 수행되는 것을 확인할 수 있습니다.

반면, AuthorizationLevelFunction이 Function으로 지정돼 있다면 이를 호출하기 위해 (일반적인 REST API 서비스 측에서 요구하는 App Key처럼) 미리 정해진 Key 값을 함께 명시를 해야 합니다. 이 Key 값은 Azure Portal에서 Function App 화면을 통해 "Get Function Url"로 알아낼 수 있습니다.

azure_func_4.png

저 위의 모든 키 값은 Function App 서비스가 생성되는 시점에 함께 만들어지지만, 원한다면 언제든 새롭게 키를 바꿀 수 있습니다. 위의 목록을 보면 3가지 유형의 키가 나오는데,

  1. default (function key)
  2. default (host key)
  3. masterKey (host key)

function key는 해당 Function마다 달라지는 key입니다. 그래서 또 다른 Function을 하나 더 추가하면 그 Function은 그것에 고유하게 생성되는 Function Key를 또 알아내서 호출을 해야 합니다.

반면, host key는 모든 Function을 호출할 수 있는 기능을 합니다. 따라서, Function1과 Funciton2를 만들었고 host key가 "6vkrc/7BLZVHc2AXkeG"라면, 다음과 같은 식으로 2개의 Function 모두를 호출할 수 있습니다.

https://publicipfuncapp.azurewebsites.net/api/Function1?code=6vkrc/7BLZVHc2AXkeG
https://publicipfuncapp.azurewebsites.net/api/Function2?code=6vkrc/7BLZVHc2AXkeG

또한 같은 host key이면서, default와 masterKey로 나뉘는데 masterKey는 일종의 관리자 권한을 더한다고 보시면 됩니다.

Master Key
; https://learn.microsoft.com/en-us/azure/azure-functions/security-concepts?tabs=v4#master-key-admin-level

일례로, AuthorizationLevel을 Admin으로 주면,

[HttpTrigger(AuthorizationLevel.Admin, "get", "post", Route = null)] HttpRequest req, ILogger log)

이 Function은 오직 masterKey로만 호출할 수 있고, 일반적인 다른 host key로는 호출할 수 없습니다.

참고로, host key는 Azure Portal의 "Function App" 서비스 화면에서 제어할 수 있고, function key는 개별 Function 화면에서 제어할 수 있습니다.




비주얼 스튜디오 환경 내에서, 로컬로 실행하는 Function App의 응용 프로그램은 다음의 위치에서 실행되는 func.exe가 대체합니다.

%USERPROFILE%\AppData\Local\AzureFunctionsTools\Releases\4.13.0\cli_x64

그리고 iisexpress.exe처럼, 이것 역시 비주얼 스튜디오가 아닌 그냥 단순하게 다음과 같은 식의 명령어를 이용해 실행하는 것도 가능합니다.

// Function App 프로젝트가 빌드된 경로로 이동하고,

c:\temp> cd c:\temp\FunctionApp1\FunctionApp1\bin\Debug\net6.0\

// 그 경로를 Current Directory로 해서 func.exe를 수행

c:\temp\FunctionApp1\FunctionApp1\bin\Debug\net6.0> "%USERPROFILE%\AppData\Local\AzureFunctionsTools\Releases\4.13.0\cli_x64\func.exe" host start --port 7071 --pause-on-error




대충 어떤 식인지 이 정도면 쉽게 파악이 되셨을 것입니다.

참고로, Azure Functions는 무료 범위가 있다는 점! ^^

// https://azure.microsoft.com/ko-kr/pricing/details/functions/

Azure Functions 사용량 과금제는 초당 리소스 사용량과 실행 횟수에 따라 비용이 청구됩니다. 사용량 플랜 가격에는 종량제 가격 체제로 구독 내의 모든 함수 앱에 대해 구독별로 매월 1백만 건의 요청 및 매월 400,000GB의 리소스 사용이 무료로 부여됩니다.





(2024-04-04: 업데이트)

.NET Conf 2023 (Day 1) - Leveraging the power of the .NET platform in Azure Functions
; https://youtu.be/vU-iZcxbDUk?t=14791

azure_func_net8_1.png




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 4/4/2024]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 46  47  48  [49]  50  51  52  53  54  55  56  57  58  59  60  ...
NoWriterDateCnt.TitleFile(s)
12746정성태7/31/202123881개발 환경 구성: 588. 네트워크 장비 환경을 시뮬레이션하는 Packet Tracer 프로그램 소개
12745정성태7/31/202116396개발 환경 구성: 587. Azure Active Directory - tenant의 관리자 계정 로그인 방법
12744정성태7/30/202116443개발 환경 구성: 586. Azure Active Directory에 연결된 App 목록을 확인하는 방법?
12743정성태7/30/202118017.NET Framework: 1083. Azure Active Directory - 외부 Token Cache 저장소를 사용하는 방법파일 다운로드1
12742정성태7/30/202115727개발 환경 구성: 585. Azure AD 인증을 위한 사용자 인증 유형
12741정성태7/29/202117404.NET Framework: 1082. Azure Active Directory - Microsoft Graph API 호출 방법파일 다운로드1
12740정성태7/29/202116001오류 유형: 747. SharePoint - InvalidOperationException 0x80131509
12739정성태7/28/202116265오류 유형: 746. Azure Active Directory - IDW10106: The 'ClientId' option must be provided.
12738정성태7/28/202117494오류 유형: 745. Azure Active Directory - Client credential flows must have a scope value with /.default suffixed to the resource identifier (application ID URI).
12737정성태7/28/202116536오류 유형: 744. Azure Active Directory - The resource principal named api://...[client_id]... was not found in the tenant
12736정성태7/28/202116866오류 유형: 743. Active Azure Directory에서 "API permissions"의 권한 설정이 "Not granted for ..."로 나오는 문제
12735정성태7/27/202115853.NET Framework: 1081. C# - Azure AD 인증을 지원하는 데스크톱 애플리케이션 예제(Windows Forms) [2]파일 다운로드1
12734정성태7/26/202132727스크립트: 20. 특정 단어로 시작하거나/끝나는 문자열을 포함/제외하는 정규 표현식 - Look-around
12733정성태7/23/202121834.NET Framework: 1081. Self-Contained/SingleFile 유형의 .NET Core/5+ 실행 파일을 임베딩한다면? [1]파일 다운로드2
12732정성태7/23/202114366오류 유형: 742. SharePoint - The super user account utilized by the cache is not configured.
12731정성태7/23/202116348개발 환경 구성: 584. Add Internal URLs 화면에서 "Save" 버튼이 비활성화 된 경우
12730정성태7/23/202118225개발 환경 구성: 583. Visual Studio Code - Go 코드에서 입력을 받는 경우
12729정성태7/22/202116260.NET Framework: 1080. xUnit 단위 테스트에 메서드/클래스 수준의 문맥 제공 - Fixture
12728정성태7/22/202116861.NET Framework: 1079. MSTestv2 단위 테스트에 메서드/클래스/어셈블리 수준의 문맥 제공
12727정성태7/21/202117971.NET Framework: 1078. C# 단위 테스트 - MSTestv2/NUnit의 Assert.Inconclusive 사용법(?) [1]
12726정성태7/21/202117450VS.NET IDE: 169. 비주얼 스튜디오 - 단위 테스트 선택 시 MSTestv2 외의 xUnit, NUnit 사용법 [1]
12725정성태7/21/202116087오류 유형: 741. Failed to find the "go" binary in either GOROOT() or PATH
12724정성태7/21/202119083개발 환경 구성: 582. 윈도우 환경에서 Visual Studio Code + Go (Zip) 개발 환경 [1]
12723정성태7/21/202115203오류 유형: 740. SharePoint - Alternate access mappings have not been configured 경고
12722정성태7/20/202115293오류 유형: 739. MSVCR110.dll이 없어 exe 실행이 안 되는 경우
12721정성태7/20/202121010오류 유형: 738. The trust relationship between this workstation and the primary domain failed. - 세 번째 이야기
... 46  47  48  [49]  50  51  52  53  54  55  56  57  58  59  60  ...