I have a CI/CD pipeline that creates the infrastructure to create the function app, storage container and app insights to the azure portal. I have an Azure function in Linux and I want to know how to link this azure function to the function app during the deployment process.
This is the template.json that I am using to deploy my current infrastructure:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"subscriptionId": {
"type": "string"
},
"name": {
"type": "string"
},
"location": {
"type": "string"
},
"hostingPlanName": {
"type": "string"
},
"serverFarmResourceGroup": {
"type": "string"
},
"alwaysOn": {
"type": "bool"
},
"use32BitWorkerProcess": {
"type": "bool"
},
"storageAccountName": {
"type": "string"
},
"netFrameworkVersion": {
"type": "string"
},
"sku": {
"type": "string"
},
"skuCode": {
"type": "string"
},
"workerSize": {
"type": "string"
},
"workerSizeId": {
"type": "string"
},
"numberOfWorkers": {
"type": "string"
}
},
"variables": {},
"resources": [
{
"apiVersion": "2018-11-01",
"name": "[parameters('name')]",
"type": "Microsoft.Web/sites",
"kind": "functionapp",
"location": "[parameters('location')]",
"tags": {},
"dependsOn": [
"microsoft.insights/components/templateforarm",
"[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]"
],
"properties": {
"name": "[parameters('name')]",
"siteConfig": {
"appSettings": [
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~4"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "node"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~14"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference('microsoft.insights/components/templateforarm', '2015-05-01').InstrumentationKey]"
},
{
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
"value": "[reference('microsoft.insights/components/templateforarm', '2015-05-01').ConnectionString]"
},
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[concat(toLower(parameters('name')), 'a8cc')]"
}
],
"use32BitWorkerProcess": "[parameters('use32BitWorkerProcess')]",
"netFrameworkVersion": "[parameters('netFrameworkVersion')]"
},
"serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
"clientAffinityEnabled": false
}
},
{
"apiVersion": "2018-11-01",
"name": "[parameters('hostingPlanName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[parameters('location')]",
"kind": "",
"tags": {},
"dependsOn": [],
"properties": {
"name": "[parameters('hostingPlanName')]",
"workerSize": "[parameters('workerSize')]",
"workerSizeId": "[parameters('workerSizeId')]",
"numberOfWorkers": "[parameters('numberOfWorkers')]"
},
"sku": {
"Tier": "[parameters('sku')]",
"Name": "[parameters('skuCode')]"
}
},
{
"apiVersion": "2020-02-02-preview",
"name": "templateforarm",
"type": "microsoft.insights/components",
"location": "westus2",
"tags": {},
"dependsOn": [],
"properties": {
"ApplicationId": "[parameters('name')]",
"Request_Source": "IbizaWebAppExtensionCreate",
"Flow_Type": "Redfield",
"Application_Type": "web",
"WorkspaceResourceId": "[concat('/subscriptions/', parameters('subscriptionId'), '/resourcegroups/defaultresourcegroup-wus2/providers/microsoft.operationalinsights/workspaces/defaultworkspace-', parameters('subscriptionId'),'-wus2')]"
}
},
{
"apiVersion": "2019-06-01",
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('storageAccountName')]",
"location": "[parameters('location')]",
"tags": {},
"sku": {
"name": "Standard_LRS"
},
"properties": {
"supportsHttpsTrafficOnly": true,
"minimumTlsVersion": "TLS1_2"
}
}
]
}
This is the folder structure that I have for my azure function, app insights, storage container and function app infrastructure.
-azure
-azure_functions
-my_function
-arm
-dev.json
-prod.json
-template.json
-my_function_code
-index.json
-function.json
-host.json
-local.settings.json
-package-lock.json
-package.json
-proxies.json
-release.yml
This is the yml file that I use to deploy the app insights, storage container and function app.
trigger:
none
pr:
branches:
include:
- main
paths:
include:
- azure/azure_functions/my_function/
stages:
- stage: Validation
displayName: Validate Templates
jobs:
- job: Validate
steps:
- task: AzureResourceGroupDeployment@2
displayName: "Validate Test"
inputs:
azureSubscription: "test-group-SPN"
resourceGroupName: "test-group"
location: "West US 2"
csmFile: azure/azure_functions/my_function/arm/template.json
csmParametersFile:
azure/azure_functions/my_function/arm/test.json
deploymentMode: Validation
- task: PublishBuildArtifacts@1
displayName: "Publish Artifact: ARM Template"
inputs:
PathtoPublish: ./azure/azure_functions/my_function/arm
ArtifactName: arm
- stage: TEST
displayName: Deploy stage Test
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: eventconnector-test
strategy:
runOnce:
deploy:
steps:
- task: AzureResourceManagerTemplateDeployment@3
displayName: 'Deploy App Insights, Storage Container & Function App'
inputs:
deploymentScope: 'Resource Group'
azureResourceManagerConnection: 'eventconnector-test-group-SPN'
subscriptionId: 'XXXX'
action: 'Create Or Update Resource Group'
resourceGroupName: 'eventconnector-test-group'
location: 'West US 2'
templateLocation: 'Linked artifact'
csmFile: '$(Pipeline.Workspace)/arm/template.json'
csmParametersFile: '$(Pipeline.Workspace)/arm/test.json'
deploymentMode: 'Incremental'
There's another yml file that I was able to create to deploy my azure function but this doesn't link to the current function app that I defined previously.
trigger:
none
pr:
branches:
include:
- main
paths:
include:
- azure/azure_functions/my_function/
stages:
- stage: Build
displayName: Build stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: ubuntu-latest
steps:
- task: NodeTool@0
inputs:
versionSpec: '14.x'
displayName: 'Install Node.js'
- script: |
npm install --prefix azure/azure_functions/my_function/
displayName: 'Prepare binaries'
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: 'azure/azure_functions/my_function/'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
artifact: drop
- stage: TEST
displayName: Deploy stage Test
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: eventconnector-test
pool:
vmImage: ubuntu-latest
strategy:
runOnce:
deploy:
steps:
- task: AzureFunctionApp@1
displayName: 'Azure Functions App Deploy: '
inputs:
azureSubscription: 'test-group-SPN'
appType: functionAppLinux
appName: 'my_function'
package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
How can I link this azure function to be deployed in the function app that I declared in my first yml file?
CodePudding user response:
After doing some research I found out that I just needed to add the following code at the end of my yml file to deploy my azure function into the function app:
- task: AzureCLI@1
displayName: 'Deploy Azure function'
inputs:
azureSubscription: 'XXX'
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
az functionapp deployment source config-zip -g XXX -n azure_func_app_name --src $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
Below is the final yml code that deploys the function app, app insights, storage and drops the azure function.
trigger:
none
pr:
branches:
include:
- main
paths:
include:
- azure/azure_functions/my_function/
stages:
- stage: Validation
displayName: Validate Templates
jobs:
- job: Validate
steps:
- task: AzureResourceGroupDeployment@2
displayName: "Validate Test"
inputs:
azureSubscription: "test-group-SPN"
resourceGroupName: "test-group"
location: "West US 2"
csmFile: azure/azure_functions/my_function/arm/template.json
csmParametersFile:
azure/azure_functions/my_function/arm/test.json
deploymentMode: Validation
- task: PublishBuildArtifacts@1
displayName: "Publish Artifact: ARM Template"
inputs:
PathtoPublish: ./azure/azure_functions/my_function/arm
ArtifactName: arm
- stage: TEST
displayName: Deploy stage Test
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: eventconnector-test
strategy:
runOnce:
deploy:
steps:
- task: AzureResourceManagerTemplateDeployment@3
displayName: 'Deploy App Insights, Storage Container & Function App'
inputs:
deploymentScope: 'Resource Group'
azureResourceManagerConnection: 'eventconnector-test-group-SPN'
subscriptionId: 'XXXX'
action: 'Create Or Update Resource Group'
resourceGroupName: 'eventconnector-test-group'
location: 'West US 2'
templateLocation: 'Linked artifact'
csmFile: '$(Pipeline.Workspace)/arm/template.json'
csmParametersFile: '$(Pipeline.Workspace)/arm/test.json'
deploymentMode: 'Incremental'
- task: AzureCLI@1
displayName: 'Deploy Azure function'
inputs:
azureSubscription: 'XXX'
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
az functionapp deployment source config-zip -g XXX -n azure_func_app_name --src $(Pipeline.Workspace)/drop/$(Build.BuildId).zip