Hey all!
This post is another in the Custom Deployer series, specifically with Azure functions. Here is the git repository with all of the scripts.
PRE-REQUISITES
To bring this integration in, there are some pre-requisites on the Azure side before this can happen. First, you will need to have an Azure Service Principal to leverage the AZ CLI. This doc shows how to get the Service Principal set up. Using the AZ CLI to set up the Service Principal is the easiest way that Iβve found. The output from creating the Service Principal will give you a response containing some required information to leverage in Harness: appId, tenant, and password.
Another Azure pre-requisite is that a Function App must be created for the Function to live in. The Azure Documentation has some good walk throughs on how to get the Function App setup.
The last pre-requisite is related to the artifact type for the function. Azure allows you to deploy a ZIP file or the contents of a Git repository to an Azure Function. The Git repository must be available via HTTPS, whether that is public or private. This doc will show how to deploy both a Git-based Azure Function and a ZIP based Azure Function. If your Git repository requires authentication, you will need to add --private-repo-password
and --private-repo-username
to the Git command in this post. The secret and/or the username can be added the Harness Secrets Manager to keep it secret.
Secrets
Once you have that information, you need to create 2 secrets in the Harness Secrets Manager using the Password from the Create Service Principal response mentioned above (Note: Please do not use the -
character in your naming convention):
-
The first secret will be applied to the Delegate. As a result, I named the secret βazure_sp_delβ and the
Scope to Account
checkbox MUST BE CHECKED:
-
The second secret will be applied in different commands. As a result, I named the secret βazure_spβ and the
Scope to Account
checkbox MUST NOT BE CHECKED, but you can scope the secret to specific Applications at the bottom, if necessary:
Delegate Profile
Next, you will need to setup a Delegate Profile using the App ID and Tenant ID from the Service Principal Create output:
-
Setup
>Harness Delegates
>Delegate Profiles
:
# Adding Python PIP
echo β β && echo "apt-get update" && echo β β
apt-get update
echo β β && echo "install pip" && echo β β
apt-get -y install python3-pip
echo β β && echo "check pip version" && echo β β
pip3 --version
# Adding AZ-CLI
echo β β && echo "install azure cli" && echo β β
pip3 install azure-cli
echo β β && echo "check azure version" && echo β β
az --version
# Add Login info
az login --service-principal --username <APP ID> --password ${secrets.getValue("azure_sp_del")} --tenant <TENANT ID>
-
Assign the Delegate Profile to a Delegate and add a Custom Selector called
az-functions
.
Harness Application Setup
This post will assume that you are using a Linux-based Azure Function. As such, we will not be going through slot deployments
since that is not currently available with Linux-based Azure Functions.
There are three ways that the Azure Function App and Azure Function can be set up:
- Azure Function App and Azure Function have the same name
- Azure Function App and Azure Function have different names (multiple Functions per Function App)
- Azure Function App or Azure Function have an Environment-based naming convention (function-dev/function-prod or functionapp-dev/functionapp-prod)
If your current Azure Function setup is similar to number 1 above, then the Harness Service can be named after the Azure Function you are deploying.
If your current Azure Function setup is similar to number 2 or 3 above, which the examples in this post will be like number 2 above, then the Harness Application or Environment can be named after the Azure FunctionApp and the Harness Service can be named after the Azure Function you are deploying.
- To create the Custom Deployer, go to
Setup
>Template Library
>+ Add Template
>Custom Deployment Type
- Add
RES_GROUP
andFUNC_APP
asInfrastructure Variables
- Fetch Instance script
- Put a
$
in theHost Object Array Path
- For the
Host Attributes
section, add the following setup:
hostname = name
Language = language
ID = id
URL = invokeUrlTemplate
Location = location
Service Command Templates
ZIP ARTIFACT
This example will show how to pull a ZIP file from one artifact source and then upload it to Azure Functions
-
Setup
>Template Library
>+ Add Template
>Service Command
> Name the service command
- Click the
+
icon and add anExec
command - Use this script. This script is using an AWS S3 bucket to pull the artifact. But if the artifact repository is different, please alter the script as needed.
- Click the
+
icon again and add anotherExec
command - Use this script
GIT ARTIFACT
-
Setup
>Template Library
>+ Add Template
>Service Command
> Name the service command and add two variables:GIT_URL
andBRANCH
- Click the
+
icon and add anExec
command - Use this script. This script uses a public Git repository, but if you need to use a private Git repository, then follow the alteration instructions at the top of this post.
-
Application
>Services
>+ Add Service
>Name
= Function Name (Case-sensitive) >Deployment Type
= Name of the Custom Deployer >Artifact Type
=ZIP File
- If you are using a ZIP file artifact then add an
Artifact Source
to point to the correct ZIP file
. If you are not using a ZIP file, then you can leave that blank.
Harness Environment and Infrastructure Definition
The name of the Environment is important if your Azure Functions setup requires different environments to deploy to. If this is the case, please use a good naming convention for the Environment names so that you can leverage the built-in variables. For example, if your Azure Function requires a -dev
or -qa
for the FunctionApp name, then naming the Environment dev
or qa
will allow you to use ${env.name}
to the end of the Function App name to make it easier for scaling (i.e. ${service.name}-${env.name}
will always evaluate to what you need if you use the right naming convention). In this example, we are just using a generic Environment name.
To create the Infrastructure Definition:
-
Environments
>Desired Environment
>+ Add Infrastructure Definition
> Name the Infrastructure Definition something recognizable (the example isazure-functions
) >Cloud Provider Type
=Custom
>Deployment Type
= Name of the Custom Deployer >Select Version
=Latest
> Add the Resource Group and the Function App name in the correct fields
Harness Workflow
I highly recommend using a Multi-Service Workflow
for this process.
-
Setup
>Application
>Workflows
>+ Add Workflow
>Name
=azure-functions
>Workflow Type
=Multi-Service Workflow
>Environment
= The environment you created above
-
Deployment Phases
>+ Add Phase
>Service
= Custom Deployer Service >Infrastructure Definition
= Infrastructure Definition created in the Environment
-
Deploy
>+ Add Step
>Template Library
>Link
the Service Command for either ZIP artifact or Git repository
- Move the deployment command before the Fetch Instance command
a. If using the Git Service Command, make sure to add the Git Repo URL and Branch to the bottom - Deploy the workflow
Git Artifact
ZIP Artifact
Hope this helps!
Donβt forget to Like/Comment/Share!