This article is part of #ServerlessSeptember. You'll find other helpful articles, detailed tutorials, and videos in this all-things-Serverless content collection. New articles are published every day — that's right, every day — from community members and cloud advocates in the month of September.
Find out more about how Microsoft Azure enables your Serverless functions at https://docs.microsoft.com/azure/azure-functions/.
You should never store secrets in code. But what if your function need access to a secret, ie. a connection string to a storage blob? You can store those secrets in Azure KeyVault and securely reference said secrets in your function app.
The rest of this article is going to show you how to set this up without using Azure Portal.
If you want to learn more about how to better secure your function app, take a look at this article by Function PM Matthew
Pre-requisites
Azure CLI
jq
a lightweight and flexible command-line JSON processor that I promise you'll be using over and over again
A deployed function app
This can either be done through
Serverless framework - recommended since this article is building upon the sample app walk through from yesterday
Create and Deploy Azure Functions with Serverless
My ・ Sep 24 '19
Walk-through
All the scripts I mentioned below can be find in this accompanying repo
mydiemho / myho-serverless-demo
app to demo connecting Azure KeyVault using Serverless Framework
Feel free to change the chosen resource name in the scripts to something else, but beware that different resource have different naming restrictions.
Refer to the Azure resources naming convention guide if you're having trouble using
your desire values.
Log in
az account show # list all subscriptions you have access to
az account set --subscription <SUB_ID> # id of the sub you want to use
az login
Clone repo
git clone git@github.com:mydiemho/myho-serverless-demo.git
cd myho-serverless-demo
Set up keyVault
./scripts/create-keyvault.sh
The script will create a resource group and a keyVault.
Add secrets
./scripts/add-secrets.sh AwesomeSecret AwesomeSecretValue
The script takes 2 inputs: the secret key and the secret value. If you do not pass in any inputs, the default key and value will be used.
Take note of the secret url
in the output, you'll need it in a later step
Grant function app read permission
In order for the app the reference keyVault secrets, you have to add the app to the keyVault's access policies.
Behind the scene
The steps involved in doing this is:
Adding a system-assigned identity to the function app 1
Add this identity as access policy to keyVault
How-to
You'll have to first deploy a function app, then you can using the following script to grant access to the app
./scripts/grant-app-access.sh <APP_RESOURCE_GROUP> <APP_NAME>
Once the script finish, you can check the portal and see that a new access policy has been added to the function app
Add new app setting
We'll add the keyvault secret reference as an app setting *. App settings are available as environment variables to function handlers.
Using serverless, anything under the environment
section will be created as app settings.
Make sure to replace the url with the one generated in add secrets
# see https://github.com/mydiemho/myho-serverless-demo/blob/master/serverless.yml#L29
environment: # these will be created as application settings
SUPER_SECRET: "@Microsoft.KeyVault(SecretUri=https://myho-serverless-demo-kv.vault.azure.net/secrets/MySuperSecretName/88df087331004326994047248b0b6b67)"
Add new function
You can either update the handler code for one of the function or create a new function. For this example, I choose to create a new function called secrets
.
update serverless.yml
add the following section to your yaml below existing functions
# see https://github.com/mydiemho/myho-serverless-demo/blob/master/serverless.yml#L93
secrets:
handler: src/handlers/secrets.printSecrets
events:
- http: true
x-azure-settings:
methods:
- GET
authLevel: anonymous
add handler code
Add a new file src/handlers/secrets.js
# https://github.com/mydiemho/myho-serverless-demo/blob/master/src/handlers/secrets.js
"use strict";
const superSecret = process.env["SUPER_SECRET"];
module.exports.printSecrets = async function(context, req) {
context.log(
"JavaScript HTTP trigger function processed a request to display the secret in keyvault."
);
context.res = {
// status: 200, /* Defaults to 200 */
// FOR DEMO PURPOSE: DO NOT LOG SECRETS IN PRODUCTION
body: `Shhhhh.. it's a secret: ${superSecret}`
};
};
Deploy new changes
Once you've done all the set up, you're now ready to test out your new function app that is referencing KeyVault
sls deploy
If you're having trouble deploying, refer to this article to make sure you have done all the pre-requisites
Create and Deploy Azure Functions with Serverless
My ・ Sep 24 '19
#serverless #webdev #tutorial #node
Verify changes
After deploy, you can hit the function url, apim url, or using the invoke
command to test your changes.
➜ sls invoke -f secrets
Serverless: Logging into Azure
...
Serverless: Invoking function secrets with GET request
Serverless: "Shhhhh.. it's a secret: ItIsASecret"