Azure Functions의 함수 앱에 대한 리소스 배포 자동화

Bicep 파일 또는 Azure Resource Manager 템플릿을 사용하여 함수 앱을 새 Azure 리소스 또는 기존 Azure 리소스에 배포하는 프로세스를 자동화할 수 있습니다. 이러한 자동화는 리소스 배포를 DevOps의 소스 코드와 통합하여 백업에서 함수 앱 및 관련 리소스를 복원하거나, 앱 토폴로지를 여러 번 배포할 수 있는 훌륭한 방법을 제공합니다.

이 문서에서는 Azure Functions에 대한 리소스 만들기 및 배포를 자동화하는 방법을 보여줍니다. 함수에서 사용하는 트리거 및 바인딩에 따라 이 문서의 범위를 벗어나는 다른 리소스를 배포해야 할 수도 있습니다.

특정 템플릿 코드는 함수 앱이 호스트되는 방법, 코드 또는 컨테이너화된 함수 앱을 배포하는지 여부 및 앱에서 사용하는 운영 체제에 따라 달라집니다. 이 문서에서 지원하는 호스팅 옵션은 다음과 같습니다.

호스팅 옵션 배포 유형 자세한 내용은 다음을 참조하세요...
Azure Functions 사용량 요금제 코드 전용 사용 계획
Azure Functions 탄력적 프리미엄 플랜 코드 | 컨테이너 프리미엄 계획
Azure Functions 전용(App Service) 플랜 코드 | 컨테이너 전용 계획
Azure Container Apps 컨테이너만 Azure Functions의 Container Apps 호스팅
Azure Arc 코드 | 컨테이너 Azure Arc의 App Service, Functions 및 Logic Apps(미리 보기)

필요한 리소스

Azure Functions 호스팅 배포를 일반적으로 구성하는 리소스는 다음과 같습니다.

리소스 요구 사항 구문 및 속성 참조
스토리지 계정 Required Microsoft.Storage/storageAccounts
Application Insights 구성 요소 권장 Microsoft.Insights/components
호스팅 계획 필수1 Microsoft.Web/serverfarms
함수 앱 Required Microsoft.Web/sites

사용량 플랜에 대한 Azure Functions 배포를 일반적으로 구성하는 리소스는 다음과 같습니다.

리소스 요구 사항 구문 및 속성 참조
스토리지 계정 Required Microsoft.Storage/storageAccounts
Application Insights 구성 요소 권장 Microsoft.Insights/components
함수 앱 Required Microsoft.Web/sites

Azure Container Apps 호스팅 배포를 일반적으로 구성하는 리소스는 다음과 같습니다.

리소스 요구 사항 구문 및 속성 참조
스토리지 계정 Required Microsoft.Storage/storageAccounts
Application Insights 구성 요소 권장 Microsoft.Insights/components
관리 환경 Required Microsoft.App/managedEnvironments
함수 앱 Required Microsoft.Web/sites

Azure Arc 호스팅 배포를 일반적으로 구성하는 리소스는 다음과 같습니다.

리소스 요구 사항 구문 및 속성 참조
스토리지 계정 Required Microsoft.Storage/storageAccounts
Application Insights 구성 요소 권장 Microsoft.Insights/components
App Service Kubernetes 환경 Required Microsoft.ExtendedLocation/customLocations
함수 앱 Required Microsoft.Web/sites

1사용량 플랜에서 함수 앱을 호스트하도록 선택한 경우 명시적인 호스팅 계획이 필요하지 않습니다.

여러 리소스를 단일 Bicep 파일 또는 ARM 템플릿에 배포하는 경우 리소스를 만드는 순서가 중요합니다. 이 요구 사항은 리소스 간의 종속성으로 인한 결과입니다. 이러한 종속성의 경우 dependsOn 요소를 사용하여 종속 리소스의 종속성을 정의해야 합니다. 자세한 내용은 ARM 템플릿에서 리소스 배포 순서 정의 또는 Bicep의 리소스 종속성을 참조하세요.

이 문서에서는 사용자가 Bicep 파일 만들기 또는 Azure Resource Manager 템플릿 작성에 대해 기본적으로 이해하고 있다고 가정합니다. 예제는 특정 리소스에 대한 개별 섹션으로 표시됩니다. 다양한 전체 Bicep 파일 및 ARM 템플릿 예제는 이러한 함수 앱 배포 예제를 참조하세요.

필수 조건

이 문서에서는 Azure Container Apps에서 이미 관리 환경을 만들었다고 가정합니다. Container Apps에서 호스트되는 함수 앱을 만들려면 관리 환경의 이름과 ID가 모두 필요합니다.

이 문서에서는 App Service 지원 사용자 지정 위치Azure Arc 지원 Kubernetes 클러스터에 이미 만들었다고 가정합니다. Azure Arc 사용자 지정 위치에서 호스트되는 함수 앱을 만들려면 사용자 지정 위치 ID와 Kubernetes 환경 ID가 모두 필요합니다.

스토리지 계정 만들기

모든 함수 앱에는 Azure 스토리지 계정이 필요합니다. Blob, 테이블, 큐 및 파일을 지원하는 일반 용도의 계정이 있어야 합니다. 자세한 내용은 Azure Functions 스토리지 계정 요구 사항을 참조하세요.

Important

스토리지 계정은 중요한 앱 데이터를 저장하는 데 사용되며, 이러한 중요 앱 데이터에 애플리케이션 코드 자체가 포함되는 경우도 있습니다. 다른 앱이나 사용자가 스토리지 계정에 액세스하는 행위를 제한해야 합니다.

이 예제 섹션에서는 표준 범용 v2 스토리지 계정을 만듭니다.

"resources": [
  {
    "type": "Microsoft.Storage/storageAccounts",
    "apiVersion": "2022-05-01",
    "name": "[parameters('storageAccountName')]",
    "location": "[parameters('location')]",
    "kind": "StorageV2",
    "sku": {
      "name": "[parameters('storageAccountType')]"
    },
    "properties": {
      "supportsHttpsTrafficOnly": true,
      "defaultToOAuthAuthentication": true
    }
  }
]

자세한 컨텍스트는 템플릿 리포지토리의 전체 azuredeploy.json 파일을 참조하세요.

이 스토리지 계정의 연결 문자열을 Functions에 필요한 AzureWebJobsStorage 앱 설정으로 설정해야 합니다. 이 문서의 템플릿은 만든 스토리지 계정을 기반으로 하여 이 연결 문자열 값을 구성하는 것이 좋습니다. 자세한 내용은 애플리케이션 구성을 참조하세요.

스토리지 로그 사용

스토리지 계정은 중요한 함수 앱 데이터에 사용되므로 해당 콘텐츠를 수정하기 위해 계정을 모니터링해야 합니다. 스토리지 계정을 모니터링하려면 Azure Storage에 대한 Azure Monitor 리소스 로그를 구성해야 합니다. 이 예제 섹션에서는 myLogAnalytics라는 Log Analytics 작업 영역이 이러한 로그의 대상으로 사용됩니다.

"resources": [
  {
    "type": "Microsoft.Insights/diagnosticSettings",
    "apiVersion": "2021-05-01-preview",
    "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/default', parameters('storageAccountName'))]",
    "name": "[parameters('storageDataPlaneLogsName')]",
    "properties": {
        "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('myLogAnalytics'))]",
        "logs": [
          {
            "category": "StorageWrite",
            "enabled": true
          }
        ],
        "metrics": [
          {
            "category": "Transaction",
            "enabled": true
          }
        ]
    }
  }
]

이 동일한 작업 영역은 나중에 정의되는 Application Insights 리소스에도 사용할 수 있습니다. 이러한 로그 작업 방법을 포함한 자세한 내용은 Azure Storage 모니터링을 참조하세요.

Application Insights 만들기

Application Insights에서는 함수 앱 실행을 모니터링하는 것이 좋습니다. 이 예제 섹션에서 Application Insights 리소스는 Microsoft.Insights/components 형식과 web 종류로 정의됩니다.

{
  "type": "Microsoft.Insights/components",
  "apiVersion": "2020-02-02",
  "name": "[variables('applicationInsightsName')]",
  "location": "[parameters('appInsightsLocation')]",
  "tags": {
    "[format('hidden-link:{0}', resourceId('Microsoft.Web/sites', parameters('functionAppName')))]": "Resource"
  },
  "properties": {
    "Application_Type": "web"
  },
  "kind": "web"
},

자세한 컨텍스트는 템플릿 리포지토리의 전체 azuredeploy.json 파일을 참조하세요.

APPLICATIONINSIGHTS_CONNECTION_STRING 애플리케이션 설정을 사용하여 연결을 함수 앱에 제공해야 합니다. 자세한 내용은 애플리케이션 설정을 참조하세요.

이 문서의 예제에서는 만든 인스턴스에 대한 연결 문자열 값을 가져옵니다. 이전 버전에서는 APPINSIGHTS_INSTRUMENTATIONKEY를 대신 사용하여 계측 키를 설정할 수 있었지만 이 키는 더 이상 권장되지 않습니다.

호스팅 계획 만들기

Azure Functions 프리미엄 플랜 또는 전용(App Service) 플랜에서 호스트되는 앱에는 호스팅 계획이 명시적으로 정의되어 있어야 합니다.

프리미엄 계획은 소비 계획과 동일한 크기 조정을 제공하지만 전용 리소스 및 추가 기능을 포함합니다. 자세한 정보는 Azure Functions 프리미엄 계획을 참조하세요.

프리미엄 계획은 특수한 유형의 serverfarm 리소스입니다. 이는 sku 속성의 Name 속성 값에 대해 EP1, EP2 또는 EP3을 사용하여 지정할 수 있습니다. Functions 호스팅 계획을 정의하는 방법은 함수 앱이 Windows에서 실행되는지 아니면 Linux에서 실행되는지에 따라 달라집니다. 이 예제 섹션에서는 EP1 플랜을 만듭니다.

"resources": [
  {
    "type": "Microsoft.Web/serverfarms",
    "apiVersion": "2022-03-01",
    "name": "[parameters('hostingPlanName')]",
    "location": "[parameters('location')]",
    "sku": {
      "name": "EP1",
      "tier": "ElasticPremium",
      "family": "EP"
    },
    "kind": "elastic",
    "properties": {
      "maximumElasticWorkerCount": 20
    }
  }
]

자세한 컨텍스트는 템플릿 리포지토리의 전체 azuredeploy.json 파일을 참조하세요.

sku 개체에 대한 자세한 내용은 SkuDefinition을 참조하거나 예제 템플릿을 검토하세요.

전용(App Service) 플랜에서 함수 앱은 웹앱과 비슷하게 App Service 요금제의 기본, 표준 및 프리미엄 SKU의 전용 VM에서 실행됩니다. 자세한 내용은 전용 플랜을 참조하세요.

샘플 Bicep 파일/Azure Resource Manager 템플릿은 Azure App Service 요금제의 함수 앱을 참조하세요.

Functions에서 전용 계획은 serverfarm 리소스로 정의되는 일반 App Service 계획일 뿐입니다. 최소한 name 값을 제공해야 합니다. 지원되는 플랜 이름 목록은 전용 플랜에 지원되는 현재 값 목록에 대한 az appservice plan create--sku 설정을 참조하세요.

호스팅 계획을 정의하는 방법은 함수 앱이 Windows에서 실행되는지 아니면 Linux에서 실행되는지에 따라 달라집니다.

"resources": [
  {
    "type": "Microsoft.Web/serverfarms",
    "apiVersion": "2022-03-01",
    "name": "[parameters('hostingPlanName')]",
    "location": "[parameters('location')]",
    "sku": {
      "tier": "Standard",
      "name": "S1",
      "size": "S1",
      "family": "S",
      "capacity": 1
    }
  }
]

자세한 컨텍스트는 템플릿 리포지토리의 전체 azuredeploy.json 파일을 참조하세요.

호스팅 계획 만들기

사용량 호스팅 계획 리소스는 명시적으로 정의할 필요가 없습니다. 이 리소스 정의를 건너뛰면 함수 앱 리소스 자체를 만들 때 지역별로 플랜이 자동으로 만들어지거나 선택됩니다.

사용량 플랜을 computeModesku 속성에 대해 Dynamic 값을 사용하여 지정하는 특수 형식의 serverfarm 리소스로 명시적으로 정의할 수 있습니다. 이 예제 섹션에서는 사용량 플랜을 명시적으로 정의하는 방법을 보여줍니다. 호스팅 계획을 정의하는 방법은 함수 앱이 Windows에서 실행되는지 아니면 Linux에서 실행되는지에 따라 달라집니다.

"resources": [
  {
    "type": "Microsoft.Web/serverfarms",
    "apiVersion": "2022-03-01",
    "name": "[parameters('hostingPlanName')]",
    "location": "[parameters('location')]",
    "sku": {
      "name": "Y1",
      "tier": "Dynamic",
      "size": "Y1",
      "family": "Y",
      "capacity": 0
    },
    "properties": {
      "computeMode": "Dynamic"
    }
  }
]

자세한 컨텍스트는 템플릿 리포지토리의 전체 azuredeploy.json 파일을 참조하세요.

Kubernetes 환경

Azure Functions는 코드 프로젝트 또는 컨테이너화된 함수 앱으로 Azure Arc 지원 Kubernetes에 배포할 수 있습니다.

앱 및 계획 리소스를 만들려면 Azure Arc 지원 Kubernetes 클러스터에 대해 이미 App Service Kubernetes 환경이 만들어져 있어야 합니다. 이 문서의 예제에서는 배포할 사용자 지정 위치(customLocationId) 및 App Service Kubernetes 환경(kubeEnvironmentId)의 리소스 ID가 있다고 가정합니다. 다음 예제와 같이 설정됩니다.

"parameters": {
  "kubeEnvironmentId" : {
    "type": "string"
  },
  "customLocationId" : {
    "type": "string"
  }
}

사이트와 계획 둘 다 extendedLocation 필드를 통해 사용자 지정 위치를 참조해야 합니다. 이 잘린 예제와 같이 extendedLocationkindlocation에 대한 피어로 properties 외부에 있습니다.

{
  "type": "Microsoft.Web/serverfarms",
  ...
  {
    "extendedLocation": {
      "name": "[parameters('customLocationId')]"
    },
  }
}

플랜 리소스는 Linux 배포이므로 Kubernetes(K1) 값을 SKU에 사용하고, kind 필드는 linux,kubernetes이고, reserved 속성은 true이어야 합니다. 또한 extendedLocationkubeEnvironmentProfile.id를 각각 사용자 지정 위치 ID와 Kubernetes 환경 ID로 설정해야 합니다. 다음 예제 섹션과 같습니다.

"resources": [
  {
    "type": "Microsoft.Web/serverfarms",
    "apiVersion": "2022-03-01",
    "name": "[parameters('hostingPlanName')]",
    "location": "[parameters('location')]",
    "kind": "linux,kubernetes",
    "sku": {
      "name": "K1",
      "tier": "Kubernetes"
    },
    "extendedLocation": {
      "name": "[parameters('customLocationId')]"
    },
    "properties": {
      "kubeEnvironmentProfile": {
        "id": "[parameters('kubeEnvironmentId')]"
      },
      "reserved": true
    }
  }
]

함수 앱 만들기

함수 앱 리소스는 최소한 functionapp을 포함하는 Microsoft.Web/siteskind 형식의 리소스에서 정의됩니다.

함수 앱 리소스를 정의하는 방법은 Linux에서 호스트하는지 아니면 Windows에서 호스트하는지에 따라 달라집니다.

Windows에서 실행할 때 필요한 애플리케이션 설정 목록은 애플리케이션 구성을 참조하세요. 샘플 Bicep 파일/Azure Resource Manager 템플릿은 사용량 플랜에서 Windows에 호스트되는 함수 앱 템플릿을 참조하세요.

Windows에서 실행할 때 필요한 애플리케이션 설정 목록은 애플리케이션 구성을 참조하세요.

참고 항목

필요에 따라 사용량 플랜을 정의하도록 선택하는 경우 플랜의 리소스 ID를 가리키도록 앱에서 serverFarmId 속성을 설정해야 합니다. 함수 앱에 계획도 참조하는 dependsOn 설정이 있는지 확인합니다. 플랜을 명시적으로 정의하지 않은 경우 플랜을 만듭니다.

플랜의 리소스 ID를 가리키도록 앱에서 serverFarmId 속성을 설정합니다. 함수 앱에 계획도 참조하는 dependsOn 설정이 있는지 확인합니다.

"resources": [
  {
    "type": "Microsoft.Web/sites",
    "apiVersion": "2022-03-01",
    "name": "[parameters('functionAppName')]",
    "location": "[parameters('location')]",
    "kind": "functionapp",
    "dependsOn": [
      "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]",
      "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
      "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
    ],
    "properties": {
      "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
      "siteConfig": {
        "appSettings": [
          {
            "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
            "value": "[reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), '2020-02-02').ConnectionString]"
          },
          {
            "name": "AzureWebJobsStorage",
            "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', parameters('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)]"
          },
          {
            "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
            "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', parameters('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)]"
          },
          {
            "name": "WEBSITE_CONTENTSHARE",
            "value": "[toLower(parameters('functionAppName'))]"
          },
          {
            "name": "FUNCTIONS_EXTENSION_VERSION",
            "value": "~4"
          },
          {
            "name": "FUNCTIONS_WORKER_RUNTIME",
            "value": "node"
          },
          {
            "name": "WEBSITE_NODE_DEFAULT_VERSION",
            "value": "~14"
          }
        ]
      }
    }
  }
]

전체 엔드투엔드 예제는 이 azuredeploy.json 템플릿을 참조하세요.

"resources": [
  {
    "type": "Microsoft.Web/sites",
    "apiVersion": "2022-03-01",
    "name": "[parameters('functionAppName')]",
    "location": "[parameters('location')]",
    "kind": "functionapp",
    "dependsOn": [
      "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]",
      "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
      "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
    ],
    "properties": {
      "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
      "siteConfig": {
        "alwaysOn": true,
        "appSettings": [
          {
            "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
            "value": "[reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), '2020-02-02').ConnectionString]"
          },
          {
            "name": "AzureWebJobsStorage",
            "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};EndpointSuffix={1};AccountKey={2}', parameters('storageAccountName'), environment().suffixes.storage, listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)]"
          },
          {
            "name": "FUNCTIONS_EXTENSION_VERSION",
            "value": "~4"
          },
          {
            "name": "FUNCTIONS_WORKER_RUNTIME",
            "value": "node"
          },
          {
            "name": "WEBSITE_NODE_DEFAULT_VERSION",
            "value": "~14"
          }
        ]
      }
    }
  }
]

전체 엔드투엔드 예제는 이 azuredeploy.json 템플릿을 참조하세요.

배포 원본

Bicep 파일 또는 ARM 템플릿은 필요에 따라 함수 코드에 대한 배포를 정의할 수도 있습니다. 여기에는 다음 메서드가 포함될 수 있습니다.

배포 원본

Bicep 파일 또는 ARM 템플릿은 필요에 따라 zip 배포 패키지를 사용하여 함수 코드에 대한 배포를 정의할 수도 있습니다.

Azure Resource Manager를 사용하여 애플리케이션을 성공적으로 배포하려면 Azure에서 리소스가 배포되는 방식을 이해하는 것이 중요합니다. 대부분의 예제에서 최상위 구성은 siteConfig를 사용하여 적용됩니다. Functions 런타임 및 배포 엔진에 정보를 전달하기 때문에 최상위 수준에서 이러한 구성을 설정하는 것이 중요합니다. 자식 sourcecontrols/web 리소스가 적용되기 전에 최상위 정보가 필요합니다. 이러한 설정은 자식 수준 config/appSettings 리소스에서 구성할 수 있지만 경우에 따라 config/appSettings가 적용되기 전에 함수 앱을 배포해야 합니다.

Zip 배포 패키지

Zip 배포는 함수 앱 코드를 배포하는 데 권장되는 방법입니다. 기본적으로 zip 배포를 사용하는 함수는 배포 패키지 자체에서 실행됩니다. 배포 패키지 요구 사항을 포함한 자세한 내용은 Azure Functions에 대한 Zip 배포를 참조하세요. 리소스 배포 자동화를 사용하는 경우 Bicep 또는 ARM 템플릿에서 .zip 배포 패키지를 참조할 수 있습니다.

템플릿에서 zip 배포를 사용하려면 앱의 WEBSITE_RUN_FROM_PACKAGE 설정을 1로 설정하고 /zipDeploy 리소스 정의를 포함합니다.

Linux의 사용량 플랜의 경우 이 예제 템플릿과 같이 WEBSITE_RUN_FROM_PACKAGE 설정에서 직접 배포 패키지의 URI를 대신 설정합니다.

다음 예제에서는 zip 배포 원본을 기존 앱에 추가합니다.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "functionAppName": {
      "type": "string",
      "metadata": {
        "description": "The name of the Azure Function app."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "The location into which the resources should be deployed."
      }
    },
    "packageUri": {
      "type": "string",
      "metadata": {
        "description": "The zip content url."
      }
    }
  },
  "resources": [
    {
      "name": "[concat(parameters('functionAppName'), '/ZipDeploy')]",
      "type": "Microsoft.Web/sites/extensions",
      "apiVersion": "2021-02-01",
      "location": "[parameters('location')]",
      "properties": {
        "packageUri": "[parameters('packageUri')]"
      }
    }
  ]
}

zip 배포 리소스를 템플릿에 포함하는 경우 다음 사항에 유의하세요.

  • packageUri는 Functions에서 액세스할 수 있는 위치여야 합니다. SAS(공유 액세스 서명)를 통해 Azure Blob Storage를 사용하는 것이 좋습니다. SAS가 만료되면 배포를 위해 Functions에서 더 이상 공유에 액세스할 수 없습니다. SAS를 다시 생성하는 경우 WEBSITE_RUN_FROM_PACKAGE 설정을 새 URI 값으로 업데이트해야 합니다.

  • WEBSITE_RUN_FROM_PACKAGE을(를) URI로 설정할 때는 트리거를 수동으로 동기화해야 합니다.

  • 설정을 추가하거나 업데이트하는 경우 항상 필요한 모든 애플리케이션 설정을 appSettings 컬렉션에 지정해야 합니다. 명시적으로 설정되지 않은 기존 설정은 업데이트에서 제거됩니다. 자세한 내용은 애플리케이션 구성을 참조하세요.

  • Functions는 패키지 배포에 대한 웹 배포(msdeploy)를 지원하지 않습니다. 대신 배포 파이프라인 및 자동화에서 zip 배포를 사용해야 합니다. 자세한 내용은 Azure Functions에 대한 Zip 배포를 참조하세요.

원격 빌드

배포 프로세스에서는 사용하는 .zip 파일 또는 zip 배포에 실행 준비 앱이 포함되어 있다고 가정합니다. 즉, 기본적으로 사용자 지정이 실행되지 않습니다.

그러나 Windows 컴퓨터에서 개발한 Python 또는 Node.js 앱에서 Linux 관련 패키지를 가져와야 하는 경우와 같이 앱을 원격으로 다시 빌드해야 하는 시나리오가 있습니다. 이 경우 zip 배포 후 코드에서 원격 빌드를 수행하도록 Functions를 구성할 수 있습니다.

원격 빌드를 요청하는 방법은 배포하려는 운영 체제에 따라 달라집니다.

앱이 Windows에 배포되면 언어별 명령(예: C# 앱의 경우 dotnet restore, Node.js 앱의 경우 npm install)이 실행됩니다.

연속 통합을 통해 가져오는 것과 동일한 빌드 프로세스를 사용하도록 설정하려면 배포 코드의 애플리케이션 설정에서 SCM_DO_BUILD_DURING_DEPLOYMENT=true를 추가하고 WEBSITE_RUN_FROM_PACKAGE를 완전히 제거합니다.

Linux 컨테이너

컨테이너화된 함수 앱을 Azure Functions 프리미엄 또는 전용 플랜에 배포하는 경우 다음을 수행해야 합니다.

자세한 내용은 애플리케이션 구성을 참조하세요.

"resources": [
  {
    "type": "Microsoft.Web/sites",
    "apiVersion": "2022-03-01",
    "name": "[parameters('functionAppName')]",
    "location": "[parameters('location')]",
    "kind": "functionapp",
    "dependsOn": [
      "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
      "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
    ],
    "properties": {
      "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
      "siteConfig": {
        "appSettings": [
          {
            "name": "AzureWebJobsStorage",
            "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}', parameters('storageAccountName'), listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)]"
          },
          {
            "name": "FUNCTIONS_WORKER_RUNTIME",
            "value": "node"
          },
          {
            "name": "WEBSITE_NODE_DEFAULT_VERSION",
            "value": "~14"
          },
          {
            "name": "FUNCTIONS_EXTENSION_VERSION",
            "value": "~4"
          },
          {
            "name": "DOCKER_REGISTRY_SERVER_URL",
            "value": "[parameters('dockerRegistryUrl')]"
          },
          {
            "name": "DOCKER_REGISTRY_SERVER_USERNAME",
            "value": "[parameters('dockerRegistryUsername')]"
          },
          {
            "name": "DOCKER_REGISTRY_SERVER_PASSWORD",
            "value": "[parameters('dockerRegistryPassword')]"
          },
          {
            "name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
            "value": "false"
          }
        ],
        "linuxFxVersion": "DOCKER|myacr.azurecr.io/myimage:mytag"
      }
    }
  }
]

컨테이너화된 함수를 Azure Container Apps에를 배포하는 경우 템플릿에서 다음을 수행해야 합니다.

  • kind 필드를 functionapp,linux,container,azurecontainerapps 값으로 설정합니다.
  • managedEnvironmentId 사이트 속성을 Container Apps 환경의 정규화된 URI로 설정합니다.
  • 사이트와 동시에 Microsoft.App/managedEnvironments 리소스를 만들 때 리소스 링크를 사이트의 dependsOn 컬렉션에 추가합니다.

프라이빗 컨테이너 레지스트리에서 기존 Container Apps 환경으로 배포된 컨테이너화된 함수 앱의 정의는 다음 예제와 같습니다.

"resources": [
  {
    "type": "Microsoft.Web/sites",
    "apiVersion": "2022-03-01",
    "name": "[parameters('functionAppName')]",
    "kind": "functionapp,linux,container,azurecontainerapps",
    "location": "[parameters('location')]",
    "dependsOn": [
      "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]",
      "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
    ],
    "properties": {
      "serverFarmId": "[parameters('hostingPlanName')]",
      "siteConfig": {
        "linuxFxVersion": "DOCKER|myacr.azurecr.io/myimage:mytag",
        "appSettings": [
          {
            "name": "FUNCTIONS_EXTENSION_VERSION",
            "value": "~4"
          },
          {
            "name": "AzureWebJobsStorage",
            "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}', parameters('storageAccountName'), listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)]"
          },
          {
            "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
            "value": "[reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), '2020-02-02').ConnectionString]"
          }
        ],
      },
      "managedEnvironmentId": "[parameters('managedEnvironmentId')]"
    }
  }
]

함수를 Azure Arc에 배포하는 경우 함수 앱 리소스의 kind 필드에 설정하는 값은 배포 유형에 따라 달라집니다.

배포 유형 kind 필드 값
코드만 배포 functionapp,linux,kubernetes
컨테이너 배포 functionapp,linux,kubernetes,container

호스팅 계획 리소스에서와 마찬가지로 customLocationId도 설정해야 합니다.

.NET 6 빠른 시작 이미지를 사용하는 컨테이너화된 함수 앱의 정의는 다음 예제와 같습니다.

"resources": [
  {
    "type": "Microsoft.Web/sites",
    "apiVersion": "2022-03-01",
    "name": "[parameters('functionAppName')]",
    "kind": "kubernetes,functionapp,linux,container",
    "location": "[parameters('location')]",
    "extendedLocation": {
      "name": "[parameters('customLocationId')]"
    },
    "dependsOn": [
      "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]",
      "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
      "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
    ],
    "properties": {
      "serverFarmId": "[parameters('hostingPlanName')]",
      "siteConfig": {
        "linuxFxVersion": "DOCKER|mcr.microsoft.com/azure-functions/4-dotnet-isolated6.0-appservice-quickstart",
        "appSettings": [
          {
            "name": "FUNCTIONS_EXTENSION_VERSION",
            "value": "~4"
          },
          {
            "name": "AzureWebJobsStorage",
            "value": "[format('DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}', parameters('storageAccountName'), listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').keys[0].value)]"
          },
          {
            "name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
            "value": "[reference(resourceId('Microsoft.Insights/components', parameters('applicationInsightsName')), '2020-02-02').ConnectionString]"
          }
        ],
        "alwaysOn": true
      }
    }
  }
]

애플리케이션 구성

Functions는 Azure에서 함수 앱을 구성하기 위한 다음 옵션을 제공합니다.

구성 Microsoft.Web/sites 속성
사이트 설정 siteConfig
애플리케이션 설정 siteConfig.appSettings 컬렉션

siteConfig 속성에는 다음 사이트 설정이 필요합니다.

다음 애플리케이션 설정은 특정 운영 체제 및 호스팅 옵션에 필요하거나 권장됩니다.

다음 애플리케이션 설정은 컨테이너 배포에 필요합니다.

다음 설정은 프라이빗 컨테이너 레지스트리에서 배포하는 경우에만 필요합니다.

Bicep 파일 또는 ARM 템플릿을 사용하여 사이트 및 애플리케이션 설정 작업을 사용하는 경우 다음 고려 사항에 유의하세요.

  • 자동화된 배포에서 WEBSITE_CONTENTSHARE를 설정해야 하는 경우에 대한 중요한 고려 사항이 있습니다. 자세한 지침은 WEBSITE_CONTENTSHARE 참조를 참조하세요.
  • 이 문서의 예제에서와 같이 항상 애플리케이션 설정을 만드는 Microsoft.Web/sites 리소스의 siteConfig/appSettings 컬렉션으로 정의해야 합니다. 이렇게 하면 초기 시작 시 함수 앱을 실행하는 데 필요한 설정을 사용할 수 있습니다.

  • 템플릿을 사용하여 애플리케이션 설정을 추가하거나 업데이트하는 경우 모든 기존 설정을 업데이트에 포함해야 합니다. 기본 업데이트 REST API 호출에서 전체 /config/appsettings 리소스를 대체하므로 이 작업을 수행해야 합니다. 기존 설정을 제거하면 함수 앱이 실행되지 않습니다. 개별 애플리케이션 설정을 프로그래밍 방식으로 업데이트하려면 Azure CLI, Azure PowerShell 또는 Azure Portal을 대신 사용하여 이러한 변경을 수행할 수 있습니다. 자세한 내용은 애플리케이션 설정 작업을 참조하세요.

슬롯 배포

Functions를 사용하면 다양한 버전의 코드를 함수 앱의 고유한 엔드포인트에 배포할 수 있습니다. 이렇게 하면 프로덕션에서 실행되는 함수에 영향을 주지 않고 함수 업데이트를 더 쉽게 개발, 유효성 검사 및 배포할 수 있습니다. 배포 슬롯은 Azure App Service의 기능입니다. 사용 가능한 슬롯 수는 호스팅 계획에 따라 달라집니다. 자세한 내용은 Azure Functions 배포 슬롯 기능을 참조하세요.

슬롯 리소스는 함수 앱 리소스(Microsoft.Web/sites)와 동일한 방식으로 정의되지만 대신 Microsoft.Web/sites/slots 리소스 식별자를 사용합니다. 프리미엄 플랜에서 프로덕션 슬롯과 스테이징 슬롯을 모두 만드는 배포 예제(Bicep 및 ARM 템플릿 모두에서)는 배포 슬롯이 있는 Azure Function 앱을 참조하세요.

템플릿을 사용하여 교환을 수행하는 방법에 대한 자세한 내용은 Resource Manager 템플릿을 사용하여 자동화를 참조하세요.

슬롯 배포 작업을 사용하는 경우 다음 고려 사항에 유의하세요.

  • 배포 슬롯 정의에서 WEBSITE_CONTENTSHARE 설정을 명시적으로 설정하지 않습니다. 이 설정은 앱이 배포 슬롯에 만들어질 때 만들어집니다.

  • 슬롯을 교환하는 경우 일부 애플리케이션 설정은 교환되는 코드가 아니라 슬롯에 유지된다는 점에서 "고정"된 설정으로 간주됩니다. 이러한 슬롯 설정"slotSetting":true를 템플릿의 특정 애플리케이션 설정 정의에 포함하여 정의할 수 있습니다. 자세한 내용은 설정 관리를 참조하세요.

보안 배포

가상 네트워크와 통합하여 하나 이상의 리소스가 보호되는 배포에서 함수 앱을 만들 수 있습니다. 함수 앱에 대한 가상 네트워크 통합은 Microsoft.Web/sites/networkConfig 리소스에서 정의됩니다. 이 통합은 참조되는 함수 앱과 가상 네트워크 리소스에 따라 달라집니다. 함수 앱은 프라이빗 엔드포인트 및 경로와 같은 다른 프라이빗 네트워킹 리소스를 사용할 수도 있습니다. 자세한 내용은 Azure Functions 네트워킹 옵션을 참조하세요.

보안 스토리지 계정을 사용하는 배포를 만드는 경우 WEBSITE_CONTENTSHARE 설정을 명시적으로 설정하고 이 설정에 명명된 파일 공유 리소스를 만들어야 합니다. 이 예제(ARM 템플릿|Bicep 파일)와 같이 WEBSITE_CONTENTSHARE 값을 사용하여 Microsoft.Storage/storageAccounts/fileServices/shares 리소스를 만들어야 합니다. 또한 vnetContentShareEnabled 사이트 속성을 true로 설정해야 합니다.

참고 항목

이러한 설정이 보안 스토리지 계정을 사용하는 배포의 일부가 아닌 경우 배포 유효성 검사 중에 Could not access storage account using provided connection string 오류가 표시됩니다.

다음 프로젝트에서는 네트워크 액세스 제한을 포함하여 함수 앱을 가상 네트워크에 배포하는 방법에 대한 Bicep 및 ARM 템플릿 예제를 모두 제공합니다.

제한된 시나리오 설명
가상 네트워크 통합을 사용하는 함수 앱 만들기 함수 앱은 해당 네트워크의 리소스에 대한 모든 권한이 있는 가상 네트워크에 만들어집니다. 함수 앱에 대한 인바운드 및 아웃바운드 액세스는 제한되지 않습니다. 자세한 내용은 가상 네트워크 통합을 참조하세요.
보안 스토리지 계정에 액세스하는 함수 앱 만들기 만든 함수 앱은 Functions에서 프라이빗 엔드포인트를 사용하여 액세스하는 보안 스토리지 계정을 사용합니다. 자세한 내용은 스토리지 계정을 가상 네트워크로 제한을 참조하세요.
프라이빗 엔드포인트를 모두 사용하는 함수 앱 및 스토리지 계정 만들기 만든 함수 앱은 프라이빗 엔드포인트를 통해서만 액세스할 수 있으며, 프라이빗 엔드포인트를 사용하여 스토리지 리소스에 액세스합니다. 자세한 내용은 프라이빗 엔드포인트를 참조하세요.

제한된 네트워크 설정

함수 앱에 네트워크 제한이 있는 경우 다음 설정을 사용해야 할 수도 있습니다.

설정 설명
WEBSITE_CONTENTOVERVNET 1 스토리지 계정이 가상 네트워크로 제한되면 함수 앱의 크기를 조정할 수 있도록 하는 애플리케이션 설정입니다. 자세한 내용은 스토리지 계정을 가상 네트워크로 제한을 참조하세요.
vnetrouteallenabled 1 함수 앱의 모든 트래픽에서 가상 네트워크를 사용하도록 강제하는 사이트 설정입니다. 자세한 내용은 지역 가상 네트워크 통합을 참조하세요. 이 사이트 설정은 WEBSITE_VNET_ROUTE_ALL 애플리케이션 설정을 대체합니다.

네트워크 제한에 대한 고려 사항

프라이빗 엔드포인트를 통한 스토리지 계정 액세스를 제한하는 경우 포털 또는 가상 네트워크 외부의 디바이스를 통해 스토리지 계정에 액세스할 수 없습니다. 기본 네트워크 액세스 규칙을 관리하여 스토리지 계정의 보안 IP 주소 또는 가상 네트워크에 대한 액세스 권한을 부여할 수 있습니다.

템플릿 만들기

Bicep 또는 ARM 템플릿을 사용하는 전문가는 간단한 텍스트 편집기를 사용하여 배포를 수동으로 코딩할 수 있습니다. 나머지 사용자에게는 개발 프로세스를 더 쉽게 만드는 몇 가지 방법이 있습니다.

  • Visual Studio Code: Bicep 파일ARM 템플릿 작업을 사용하는 데 도움이 되는 확장이 있습니다. 이러한 도구를 사용하여 코드가 올바른지 확인하고 몇 가지 기본 유효성 검사를 제공할 수 있습니다.

  • Azure Portal: 포털에서 함수 앱 및 관련 리소스를 만들면 최종 검토 + 만들기 화면에 자동화 템플릿 다운로드 링크가 있습니다.

    Azure Portal의 Azure Functions 만들기 프로세스에서 템플릿 링크를 다운로드합니다.

    이 링크는 포털에서 선택한 옵션에 따라 생성된 ARM 템플릿을 보여줍니다. 새 리소스가 많이 포함된 함수 앱을 만들 때 이 템플릿은 약간 복잡할 수 있지만 ARM 템플릿의 모양에 대한 좋은 참조를 제공할 수 있습니다.

템플릿 유효성 검사

배포 템플릿 파일을 수동으로 만드는 경우 배포하기 전에 템플릿의 유효성을 검사해야 합니다. 모든 배포 메서드는 템플릿 구문의 유효성을 검사하고, 다음 JSON 형식 예제와 같이 validation failed 오류 메시지를 발생시킵니다.

{"error":{"code":"InvalidTemplate","message":"Deployment template validation failed: 'The resource 'Microsoft.Web/sites/func-xyz' is not defined in the template. Please see https://aka.ms/arm-template for usage details.'.","additionalInfo":[{"type":"TemplateViolation","info":{"lineNumber":0,"linePosition":0,"path":""}}]}}

다음 메서드는 배포하기 전에 템플릿의 유효성을 검사하는 데 사용할 수 있습니다.

deploymentMode: 'Validation'를 사용하는 다음 Azure 리소스 그룹 배포 v2 작업에서는 템플릿의 유효성을 검사하도록 Azure Pipelines에 지시합니다.

- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Resource Group'
    subscriptionId: # Required subscription ID
    action: 'Create Or Update Resource Group'
    resourceGroupName: # Required resource group name
    location: # Required when action == Create Or Update Resource Group
    templateLocation: 'Linked artifact'
    csmFile: # Required when  TemplateLocation == Linked Artifact
    csmParametersFile: # Optional
    deploymentMode: 'Validation'

테스트 리소스 그룹을 만들어 실행 전배포 오류를 확인할 수도 있습니다.

템플릿 배포

다음 방법 중 하나를 사용하여 Bicep 파일 및 템플릿을 배포할 수 있습니다.

Azure에 배포 단추

참고 항목

이 방법은 현재 Bicep 파일 배포를 지원하지 않습니다.

<url-encoded-path-to-azuredeploy-json>을 GitHub에 있는 azuredeploy.json 파일의 원시 경로에 대한 URL 인코딩 버전으로 바꿉니다.

markdown을 사용하는 예는 다음과 같습니다.

[![Deploy to Azure](https://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/<url-encoded-path-to-azuredeploy-json>)

HTML을 사용하는 예는 다음과 같습니다.

<a href="https://portal.azure.com/#create/Microsoft.Template/uri/<url-encoded-path-to-azuredeploy-json>" target="_blank"><img src="https://azuredeploy.net/deploybutton.png"></a>

PowerShell을 사용하여 배포

다음 PowerShell 명령은 리소스 그룹을 만들고 필요한 리소스로 함수 앱을 생성하는 Bicep 파일/ARM 템플릿을 배포합니다. 로컬에서 실행하려면 Azure PowerShell이 설치되어 있어야 합니다. 로그인하려면 Connect-AzAccount를 실행합니다.

# Register Resource Providers if they're not already registered
Register-AzResourceProvider -ProviderNamespace "microsoft.web"
Register-AzResourceProvider -ProviderNamespace "microsoft.storage"

# Create a resource group for the function app
New-AzResourceGroup -Name "MyResourceGroup" -Location 'West Europe'

# Deploy the template
New-AzResourceGroupDeployment -ResourceGroupName "MyResourceGroup" -TemplateFile azuredeploy.json  -Verbose

이 배포를 테스트하려면 Windows에서 소비 계획에 함수 앱을 만드는 이와 같은 템플릿을 사용하면 됩니다.

다음 단계

Azure Functions를 개발하고 구성하는 방법에 대해 자세히 알아봅니다.