이 빠른 시작에서는 Azure Developer 명령줄 도구를 사용하여 HTTP 요청에 응답하는 함수 엔드포인트를 사용하여 확장 가능한 웹 API를 빌드합니다. 코드를 로컬에서 테스트한 후 Azure Functions의 Flex 사용량 플랜에서 실행되는 새로운 서버리스 함수 앱에 배포합니다.
프로젝트 원본은 Azure Developer CLI(azd)를 사용하여 Azure에 코드를 배포하는 과정을 간소화합니다. 이 배포는 안전하고 확장성 있는 Azure Functions 배포에 대한 최신 모범 사례를 따릅니다.
기본적으로 Flex Consumption 계획은 사용한 만큼 지불하는 청구 모델을 따릅니다. 즉, 이 빠른 시작을 완료하면 Azure 계정에서 소액의 비용, 약 몇 센트 미만의 USD, 이 발생합니다.
Prerequisites
활성 구독이 있는 Azure 계정. 체험 계정을 만듭니다.
-
Java 17 개발자 키트
- 다른 지원되는 Java 버전을 사용하는 경우 프로젝트의 pom.xml 파일을 업데이트해야 합니다.
- 환경 변수는
JAVA_HOME올바른 버전의 JDK(Java Development Kit)의 설치 위치로 설정해야 합니다.
- Apache Maven 3.8.x
- JSON 페이로드가 포함된 요청을 함수 엔드포인트로 보내기 위한 보안 HTTP 테스트 도구입니다. 이 문서에서는
curl을 사용합니다.
프로젝트 초기화
이 azd init 명령을 사용하여 템플릿에서 로컬 Azure Functions 코드 프로젝트를 만듭니다.
로컬 터미널이나 명령 프롬프트에서 빈 폴더에서 이
azd init명령을 실행합니다.azd init --template functions-quickstart-dotnet-azd -e httpendpoint-dotnet이 명령은 템플릿 리포지토리 에서 프로젝트 파일을 끌어오고 현재 폴더의 프로젝트를 초기화합니다.
-e플래그는 현재 환경의 이름을 설정합니다. 환경에서azd는 앱에 대한 고유한 배포 컨텍스트를 유지 관리하며 둘 이상을 정의할 수 있습니다. Azure에서 만드는 리소스 그룹의 이름에도 사용됩니다.http앱 폴더로 이동하려면 다음 명령을 실행합니다.cd http이 JSON 데이터가 포함된 폴더에
http파일을 만듭니다.{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated" } }이 파일은 로컬에서 실행할 때 필요합니다.
로컬 터미널이나 명령 프롬프트에서 빈 폴더에서 이
azd init명령을 실행합니다.azd init --template azure-functions-java-flex-consumption-azd -e httpendpoint-java이 명령은 템플릿 리포지토리 에서 프로젝트 파일을 끌어오고 현재 폴더의 프로젝트를 초기화합니다.
-e플래그는 현재 환경의 이름을 설정합니다. 환경에서azd는 앱에 대한 고유한 배포 컨텍스트를 유지 관리하며 둘 이상을 정의할 수 있습니다. Azure에서 만드는 리소스 그룹의 이름에도 사용됩니다.http앱 폴더로 이동하려면 다음 명령을 실행합니다.cd http이 JSON 데이터가 포함된 폴더에
http파일을 만듭니다.{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "java" } }이 파일은 로컬에서 실행할 때 필요합니다.
로컬 터미널이나 명령 프롬프트에서 빈 폴더에서 이
azd init명령을 실행합니다.azd init --template functions-quickstart-javascript-azd -e httpendpoint-js이 명령은 템플릿 리포지토리 에서 프로젝트 파일을 가져오고 루트 폴더에서 프로젝트를 초기화합니다.
-e플래그는 현재 환경의 이름을 설정합니다. 환경에서azd는 앱에 대한 고유한 배포 컨텍스트를 유지 관리하며 둘 이상을 정의할 수 있습니다. Azure에서 만드는 리소스 그룹의 이름에도 사용됩니다.이 JSON 데이터를 포함하는 루트 폴더에 local.settings.json 파일을 만듭니다.
{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "node" } }이 파일은 로컬에서 실행할 때 필요합니다.
로컬 터미널이나 명령 프롬프트에서 빈 폴더에서 이
azd init명령을 실행합니다.azd init --template functions-quickstart-powershell-azd -e httpendpoint-ps이 명령은 템플릿 리포지토리 에서 프로젝트 파일을 가져오고 루트 폴더에서 프로젝트를 초기화합니다.
-e플래그는 현재 환경의 이름을 설정합니다. 환경에서azd는 앱에 대한 고유한 배포 컨텍스트를 유지 관리하며 둘 이상을 정의할 수 있습니다. Azure에서 만드는 리소스 그룹의 이름에도 사용됩니다.src앱 폴더로 이동하려면 다음 명령을 실행합니다.cd src이 JSON 데이터가 포함된 폴더에
src파일을 만듭니다.{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "powershell", "FUNCTIONS_WORKER_RUNTIME_VERSION": "7.2" } }이 파일은 로컬에서 실행할 때 필요합니다.
로컬 터미널이나 명령 프롬프트에서 빈 폴더에서 이
azd init명령을 실행합니다.azd init --template functions-quickstart-typescript-azd -e httpendpoint-ts이 명령은 템플릿 리포지토리 에서 프로젝트 파일을 가져오고 루트 폴더에서 프로젝트를 초기화합니다.
-e플래그는 현재 환경의 이름을 설정합니다. 환경에서azd는 앱에 대한 고유한 배포 컨텍스트를 유지 관리하며 둘 이상을 정의할 수 있습니다. 환경 이름은 Azure에서 만든 리소스 그룹의 이름에도 사용됩니다.이 JSON 데이터를 포함하는 루트 폴더에 local.settings.json 파일을 만듭니다.
{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "node" } }이 파일은 로컬에서 실행할 때 필요합니다.
로컬 터미널이나 명령 프롬프트에서 빈 폴더에서 이
azd init명령을 실행합니다.azd init --template functions-quickstart-python-http-azd -e httpendpoint-py이 명령은 템플릿 리포지토리 에서 프로젝트 파일을 가져오고 루트 폴더에서 프로젝트를 초기화합니다.
-e플래그는 현재 환경의 이름을 설정합니다. 환경에서azd는 앱에 대한 고유한 배포 컨텍스트를 유지 관리하며 둘 이상을 정의할 수 있습니다. 환경 이름은 Azure에서 만든 리소스 그룹의 이름에도 사용됩니다.이 JSON 데이터를 포함하는 루트 폴더에 local.settings.json 파일을 만듭니다.
{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "UseDevelopmentStorage=true", "FUNCTIONS_WORKER_RUNTIME": "python" } }이 파일은 로컬에서 실행할 때 필요합니다.
가상 환경 만들기 및 활성화
루트 폴더에서 다음 명령을 실행하여 .venv라는 가상 환경을 만들고 활성화합니다.
python3 -m venv .venv
source .venv/bin/activate
Python에서 Linux 배포판에 venv 패키지를 설치하지 않는 경우 다음 명령을 실행합니다.
sudo apt-get install python3-venv
로컬 환경에서 실행
터미널이나 명령 프롬프트의 앱 폴더에서 이 명령을 실행합니다.
func startmvn clean package mvn azure-functions:runnpm install func startnpm install npm start로컬 프로젝트 폴더에서 Functions 호스트가 시작되면 HTTP 트리거 함수의 URL 엔드포인트를 터미널 출력에 기록합니다.
Note
로컬로 실행할 때 액세스 키 권한 부여가 적용되지 않으므로 반환된 함수 URL에는 액세스 키 값이 포함되지 않으며 함수를 호출할 필요가 없습니다.
브라우저에서 엔드포인트로
httpget이동합니다. 이 URL은 다음과 같습니다.새 터미널이나 명령 프롬프트 창에서 이
curl명령을 실행하여 JSON 페이로드가 포함된 POST 요청을httppost엔드포인트로 보냅니다.curl -i http://localhost:7071/api/httppost -H "Content-Type: text/json" -d @testdata.jsoncurl -i http://localhost:7071/api/httppost -H "Content-Type: text/json" -d "@src/functions/testdata.json"이 명령은
testdata.json프로젝트 파일에서 JSON 페이로드 데이터를 읽습니다.test.http프로젝트 파일에서 두 가지 HTTP 요청의 예를 모두 찾을 수 있습니다.완료되면 터미널 창에서 Ctrl+C를 눌러
func.exe호스트 프로세스를 중지합니다.
-
deactivate를 실행하여 가상 환경을 종료합니다.
코드 검토(선택 사항)
두 개의 HTTP 트리거 함수 엔드포인트를 정의하는 코드를 검토할 수 있습니다.
[Function("httpget")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get")]
HttpRequest req,
string name)
{
var returnValue = string.IsNullOrEmpty(name)
? "Hello, World."
: $"Hello, {name}.";
_logger.LogInformation($"C# HTTP trigger function processed a request for {returnValue}.");
return new OkObjectResult(returnValue);
}
@FunctionName("httpget")
public HttpResponseMessage run(
@HttpTrigger(
name = "req",
methods = {HttpMethod.GET},
authLevel = AuthorizationLevel.FUNCTION)
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context) {
context.getLogger().info("Java HTTP trigger processed a request.");
// Parse query parameter
String name = Optional.ofNullable(request.getQueryParameters().get("name")).orElse("World");
return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
}
const { app } = require('@azure/functions');
app.http('httpget', {
methods: ['GET'],
authLevel: 'function',
handler: async (request, context) => {
context.log(`Http function processed request for url "${request.url}"`);
const name = request.query.get('name') || await request.text() || 'world';
return { body: `Hello, ${name}!` };
}
});
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
export async function httpGetFunction(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
context.log(`Http function processed request for url "${request.url}"`);
const name = request.query.get('name') || await request.text() || 'world';
return { body: `Hello, ${name}!` };
};
app.http('httpget', {
methods: ['GET'],
authLevel: 'function',
handler: httpGetFunction
});
이 function.json 파일은 httpget 함수를 정의합니다.
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "Request",
"methods": [
"get"
],
"route": "httpget"
},
{
"type": "http",
"direction": "out",
"name": "Response"
}
]
}
이 run.ps1 파일은 함수 코드를 구현합니다.
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
# Interact with query parameters
$name = $Request.Query.name
$body = "This HTTP triggered function executed successfully. Pass a name in the query string for a personalized response."
if ($name) {
$body = "Hello, $name. This HTTP triggered function executed successfully."
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = $body
})
@app.route(route="httpget", methods=["GET"])
def http_get(req: func.HttpRequest) -> func.HttpResponse:
name = req.params.get("name", "World")
logging.info(f"Processing GET request. Name: {name}")
return func.HttpResponse(f"Hello, {name}!")
여기에서 전체 템플릿 프로젝트를 검토할 수 있습니다.
여기에서 전체 템플릿 프로젝트를 검토할 수 있습니다.
여기에서 전체 템플릿 프로젝트를 검토할 수 있습니다.
여기에서 전체 템플릿 프로젝트를 검토할 수 있습니다.
여기에서 전체 템플릿 프로젝트를 검토할 수 있습니다.
여기에서 전체 템플릿 프로젝트를 검토할 수 있습니다.
로컬에서 함수를 확인한 후에는 Azure에 게시할 차례입니다.
Azure에 배포
이 프로젝트는 azd up 명령을 사용하여 Azure의 Flex 사용량 플랜에서 새 함수 앱에 이 프로젝트를 배포하도록 구성되었습니다.
Tip
이 프로젝트에는 모범 사례를 따르는 Flex 사용 계획에 대한 보안 배포를 만드는 데 사용하는 Bicep 파일 집합이 infra 폴더 azd 에 포함되어 있습니다.
azd가 Azure에서 필요한 Azure 리소스를 만들고 코드 프로젝트를 새 함수 앱에 배포하려면 이 명령을 실행합니다.azd up루트 폴더에는
azure.yaml에 필요한azd정의 파일이 포함되어 있습니다.아직 로그인하지 않은 경우 Azure 계정으로 인증하라는 메시지가 표시됩니다.
메시지가 표시되면 다음과 같은 필수 배포 매개 변수를 제공합니다.
Parameter Description Azure 구독 리소스가 만들어지는 구독. Azure 위치 새 Azure 리소스가 포함된 리소스 그룹을 만들 Azure 지역입니다. 현재 Flex 사용량 플랜을 지원하는 지역만 표시됩니다. vnetEnabled False를 선택합니다. True로 설정하면 배포는 새 가상 네트워크에 함수 앱을 만듭니다. 이
azd up명령은 Bicep 구성 파일과 함께 이러한 프롬프트에 대한 응답을 사용하여 이러한 배포 작업을 완료합니다.다음과 같은 필수 Azure 리소스를 만들고 구성합니다(
azd provision과 동등):- 플렉스 사용량 플랜 및 함수 앱
- Azure Storage(필수) 및 Application Insights(권장)
- 사용자의 계정에 대한 액세스 정책 및 역할
- 관리 ID를 사용한 서비스 간 연결(저장된 연결 문자열 대신)
- (옵션) 함수 앱과 다른 Azure 리소스를 모두 안전하게 실행하는 가상 네트워크
코드를 패키지하여 배포 컨테이너(
azd deploy와 동등)에 배포합니다. 그러면 앱이 시작되어 배포된 패키지에서 실행됩니다.
명령이 성공적으로 완료되면, 만든 리소스에 대한 링크가 표시됩니다.
Azure에서 함수 호출
이제 HTTP 테스트 도구 또는 브라우저(GET 요청용)를 사용하여 URL에 HTTP 요청을 만들어 Azure에서 함수 엔드포인트를 호출할 수 있습니다. Azure에서 함수를 실행하는 경우 액세스 키 권한 부여가 적용되며 요청과 함께 함수 액세스 키를 제공해야 합니다.
핵심 도구를 사용하여 Azure에서 실행되는 함수의 URL 엔드포인트를 가져올 수 있습니다.
로컬 터미널이나 명령 프롬프트에서 다음 명령을 실행하여 URL 엔드포인트 값을 가져옵니다.
$APP_NAME = azd env get-value AZURE_FUNCTION_NAME func azure functionapp list-functions $APP_NAME --show-keysazd env get-value명령은 로컬 환경에서 함수 앱 이름을 가져옵니다. 옵션을--show-keysfunc azure functionapp list-functions사용하는 경우 반환된 Invoke URL: 각 엔드포인트의 값에는 함수 수준 액세스 키가 포함됩니다.이전과 마찬가지로 HTTP 테스트 도구를 사용하여 Azure에서 실행되는 함수 앱에서 이러한 URL의 유효성을 검사합니다.
코드 다시 배포
필요에 따라 Azure 리소스를 프로비전하고 함수 앱에 코드 업데이트를 배포하기 위해 azd up 명령을 여러 번 실행합니다.
Note
배포된 코드 파일은 항상 최신 배포 패키지로 덮어쓰여집니다.
azd 프롬프트에 대한 초기 응답과 azd에서 생성된 모든 환경 변수는 명명된 환경에 로컬로 저장됩니다. 명령을 azd env get-values 사용하여 Azure 리소스를 만들 때 사용한 환경의 모든 변수를 검토합니다.
리소스 정리
함수 앱 및 관련 리소스 작업을 마쳤으면 이 명령을 사용하여 Azure에서 함수 앱 및 관련 리소스를 삭제하고 추가 비용이 발생하지 않도록 합니다.
azd down --no-prompt
Note
--no-prompt 옵션은 사용자의 확인 없이 azd에게 리소스 그룹을 삭제하도록 지시합니다.
이 명령은 로컬 코드 프로젝트에는 영향을 미치지 않습니다.