Open lnfernux opened 2 years ago
Update:
Managed to deploy the template, just removed the sourcecontrol.
Last update:
Deploying the azuredeploy.json
template works (only removing the sourcecontrol
block), but for some reason it deploys a second ServerFarm. This "works", everything looks right and the values in the keyvault are referenced correctly, but trying to add / deploy to the function app from cli or vscode fails with error 403.
Deploying everything directly from vscode doesn't work as it doesn't actually deploy the keyvault, so some values are missing. It also throws an error (403, the app is stopped) during deployment. This also happens when trying to deploy the zip-file to the function app (created from vscode, or created with the azuredeploy.json template).
@infernuxmonster Thank you for your feedback.
I think you know more about the Azure deployment pipeline than me, as I have not myself successfully deployed using the azuredeploy.json
template just yet. If you see any obvious mistakes, please tell me. Was it still a problem with the names for the KeyVault and the ServicePlan, how should they be named?
I tried deploying from vscode myself now, and found that the latest version of vscode has some problems with the deployment of azure functions at the moment. When, downgrading to the february release it deployed successfully, but I had to manually enter environment keys in the Function App -> Configuration for WORKSPACE_ID, WORKSPACE_KEY, API_KEY, API_SECRET, LOG_TYPE and BASE_URL. Is this what you refer to as the keyvault?
Do you have any suggestions for how to make it easier for you to deploy, or any other questions?
The naming isn't really an issue, it's just handy to have them all using the same scheme so they're easily grouped.
The way most packages are deployed (just looking through the Azure github for reference) is using an azuredeploy.json
.
Take https://github.com/Azure/Azure-Sentinel/tree/master/DataConnectors/Qualys%20KB where the parameter "run from package" is set. This allows for the following flow:
azuredeploy.json
No need to manually update any values afterwards.
The run from package setting can be set like the example I linked above:
"resources": [
{
"apiVersion": "2018-11-01",
"type": "config",
"name": "appsettings",
"dependsOn": [
"[concat('Microsoft.Web/sites/', variables('FunctionName'))]"
],
"properties": {
"WEBSITE_RUN_FROM_PACKAGE": "https://github.com/Azure/Azure-Sentinel/blob/master/DataConnectors/Qualys%20KB/AzureFunctionQualysKB.zip?raw=true"
}
The ZIP-file usually contains the function.json
file and the init.py
or the run.ps1
scripts used in the functions (https://github.com/Azure/Azure-Sentinel/tree/master/DataConnectors/Qualys%20KB/AzureFunctionQualysKB).
Being able to deploy all resources, parameters and the function itself using an azuredeploy.json
via the portal (or pipeline) is the easiest way to deploy - no need to manually add variables/parameters, no need to have the correct version of vscode or knowledge of the CLI etc. I think that would be the best way to go about it.
@infernuxmonster Thanks for the suggestion. This seems like a good solution indeed.
I tried adding the property WEBSITE_RUN_FROM_PACKAGE
, and linking to a release of the function uploaded to GitHub. It successfully deployed by uploading the azuredeploy.json to the CustomDeployment as you described, but the actual function(code) was not deployed with it.
I also tried adding a ZipDeploy resource to deploy the package like so:
{
"name": "[concat(variables('FunctionName'), '/ZipDeploy')]",
"type": "Microsoft.Web/sites/extensions",
"apiVersion": "2015-08-01",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites/', variables('FunctionName'))]"
],
"properties": {
"packageUri": "https://github.com/securepractice/mailrisk-sentinel-connector/releases/download/v0.0.1-alpha/mailrisk-sentinel-connector.zip?raw=true"
}
}
It first looked promising as it tried to deploy it during deployment, but it failed with a InternalServerError:
{
"status": "Failed",
"error": {
"code": "ResourceDeploymentFailure",
"message": "The response for resource had empty or invalid content."
}
}
I tried uploading the zip/release to github with both the function.json and init.py as you proposed and with the whole function repo, as it was suggest somewhere. For both the WEBSITE_RUN_FROM_PACKAGE and the ZipDeploy method without luck. Do you have any suggestions on what to do further on?
Hey, not sure what the issue is.
Including the Microsoft.Web/sites
from another azuredeploy.json
I created. Note, not using the ZipDeploy
resource here.
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('FunctionName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]",
"[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
],
"kind": "functionapp,linux",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"name": "[variables('FunctionName')]",
"httpsOnly": true,
"clientAffinityEnabled": true,
"alwaysOn": true,
"reserved": true
},
"resources": [
{
"apiVersion": "2018-11-01",
"type": "config",
"name": "appsettings",
"dependsOn": [
"[concat('Microsoft.Web/sites/', variables('FunctionName'))]",
"[resourceId('Microsoft.KeyVault/vaults/', variables('KeyVaultName'))]",
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('KeyVaultName'), variables('AWSRoleArn'))]",
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('KeyVaultName'), variables('LogAnalyticsWorkspaceKey'))]"
],
"properties": {
"FUNCTIONS_EXTENSION_VERSION": "~3",
"FUNCTIONS_WORKER_RUNTIME": "python",
"APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2015-05-01').InstrumentationKey]",
"APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2015-05-01').ConnectionString]",
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('StorageAccountName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName')), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
"WorkspaceID": "[parameters('WorkspaceID')]",
"WorkspaceKey": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('LogAnalyticsWorkspaceKey')).secretUriWithVersion, ')')]",
"LogAnalyticsCustomLogName":"[parameters('LogAnalyticsCustomLogName')]",
"Schedule":"*/10 * * * *",
"WEBSITE_RUN_FROM_PACKAGE": "https://github.com/xxx/xxx.zip?raw=true",
"SCM_DO_BUILD_DURING_DEPLOYMENT": "true",
"ENABLE_ORYX_BUILD": "true"
}
}
]
},
I removed some of the script-specific variables, and I'm pretty sure you can drop the "SCM_DO_BUILD_DURING_DEPLOYMENT": "true" and
"ENABLE_ORYX_BUILD": "true"` as they are only for remote builds.
The zip file in question holds the following files:
xxx.zip
|--host.json
|--requirements.txt
|--functionName(folder)
|--__init__.py
|--function.json
|--.python_packages(folder)
|--lib(folder)
|--site-packages(folder)
|--packageX(folder)
|--packageX.dist-info(folder)
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
requirements.txt (use pip freeze to generate, https://pip.pypa.io/en/stable/cli/pip_freeze/)
# DO NOT include azure-functions-worker in this file
# The Python Worker is managed by Azure Functions platform
# Manually managing azure-functions-worker may cause unexpected issues
azure-functions==1.8.0
boto3==1.9.180
requests==2.22.0
adal==1.2.2
aiohttp==3.6.2
asn1crypto==0.24.0
azure-common==1.1.24
azure-core==1.21.0
botocore==1.12.10
cryptography==2.8
pyasn1==0.4.2
pyasn1-modules==0.2.1
cffi==1.5.2
pyOpenSSL==0.12
pycrypto==2.6.1
version-utils==0.2.2
wheel==0.24.0
zope.interface==4.1.1
azure-identity==1.7.1
init.py
Main script/runner.
function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "%Schedule%"
}
]
}
(Note, %Schedule%
refers to the Schedule
value in the properties (configuration blade in azure portal) of the function).
.python_packages
Not sure if you need this, but not including it often leads to errors in versioning of requirements etc.
Basically the full path is:
.python_packages\lib\site-packages\
In this path you just put all the required packages (should be able to tell from requirements.txt) - packages can be downloaded from https://pypi.org/
Example being if you needed to download and use the boto3 library for connectiong to AWS, you'd go to https://pypi.org/project/boto3/#files and download the Built Distribution file boto3-1.21.45-py3-none-any.whl
file. Extracting the .whl file should result in the following structure:
boto3-1.21.45-py3-none-any
|--boto3
|--boto3-1.21.45.dist-info
You drop both the boto3
and the dist-info
folder into the full path mentioned above ( .pythoc_packages\lib\site-packages\
).
Hope this helps,
Truls.
Issue:
Deploying from the template gives the following errors:
The step/component that failed was mailrisk/web Status is conflict and the full message reads:
Feedback
KeyVault<randomString>
.ServicePlan
.