Repository: serverless/serverless-azure-functions
Pull request #201 (2019-07-12 16:53:03)

docs: README Update
Update README to reflect current state of plugin.

[AB#483]

coveralls: 
[![Coverage Status](https://coveralls.io/builds/24535502/badge)](https://coveralls.io/builds/24535502)

Coverage remained the same at 76.321% when pulling **054af2e8e185446a08a32a82c933f215c67d255a on tabarlow/readme-update** into **4208625bc31ebec5efb4971386ab203fea1321f7 on dev**.


Patch:
diff --git a/README.md b/README.md
index f545fbb..c6f018b 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
-# Azure Functions Serverless Plugin 
+# Azure Functions Serverless Plugin
 
 This plugin enables Azure Functions support within the Serverless Framework.
 
 [![Coverage Status](https://coveralls.io/repos/github/serverless/serverless-azure-functions/badge.svg)](https://coveralls.io/github/serverless/serverless-azure-functions)
 
-## Getting started
+## Quickstart
 
 ### Pre-requisites
 
@@ -12,50 +12,35 @@ This plugin enables Azure Functions support within the Serverless Framework.
 2. Serverless CLI `v1.9.0+`. You can run `npm i -g serverless` if you don't already have it.
 3. An Azure account. If you don't already have one, you can sign up for a [free trial](https://azure.microsoft.com/en-us/free/) that includes $200 of free credit.
 
-### Create a new Azure service
-
-1. Create a new service using the standard Node.js template, specifying a unique name for your app: `serverless create -t azure-nodejs -p <appName>`
-2. CD into the generated app directory: `cd <appName>`
-3. Install the app's NPM dependencies, which includes this plugin: `npm install`
-
-### Creating or removing Azure Functions
-
-To create a new Azure Function within your function app, run the following command from within your app's directory:
+### Create a new Azure Function App
 
 ```bash
-sls func add -n {functionName}
+# Create Azure Function App from template
+$ sls create -t azure-nodejs -p <appName>
+# Move into project directory
+$ cd <appName>
+# Install dependencies (including this plugin)
+$ npm install
 ```
 
-This will create a new `{functionName}` directory at the root of your application with `index.js` and `function.json` inside the directory. It will also update `serverless.yml` to contain the new function.
-
-To remove an existing Azure Function from your function app, run the following command from within your app's directory:
-
-```bash
-sls func remove -n {functionName}
-```
-
-This will remove the `{functionName}` directory and remove the function from `serverless.yml`
-
-*Note: Add & remove currently only support HTTP triggered functions. For other triggers, you will need to update `serverless.yml` manually
-
 ### Running Function App Locally (`offline` plugin)
 
 In order to run a Azure Function App locally, the `azure-functions-core-tools` package needs to be installed from NPM. Since it is only used for local development, we did not include it in the `devDependencies` of `package.json`. To install globally, run:
 
 ```bash
-npm i azure-functions-core-tools -g
+$ npm i azure-functions-core-tools -g
 ```
 
 Then, at the root of your project directory, run:
 
 ```bash
 # Builds necessary function bindings files
-sls offline
+$ sls offline
 # Starts the function app
-npm start
+$ npm start
 ```
 
-The build process will generate a directory for each of your functions, which will contain a file titled `function.json`. This will contain a relative reference to your handler file & exported function from that file as long as they are referenced correctly in `serverless.yml`.
+The `offline` process will generate a directory for each of your functions, which will contain a file titled `function.json`. This will contain a relative reference to your handler file & exported function from that file as long as they are referenced correctly in `serverless.yml`.
 
 The `npm start` script just runs `func host start`, but we included the `npm` script for ease of use.
 
@@ -65,58 +50,146 @@ To clean up files generated from the build, you can simply run:
 sls offline cleanup
 ```
 
-### Deploy, test, and diagnose your Azure service
+### Deploy Your Function App
 
-1. Deploy your new service to Azure! The first time you do this, you will be asked to authenticate with your Azure account, so the `serverless` CLI can manage Functions on your behalf. Simply follow the provided instructions, and the deployment will continue as soon as the authentication process is completed.
+Deploy your new service to Azure! The first time you do this, you will be asked to authenticate with your Azure account, so the `serverless` CLI can manage Functions on your behalf. Simply follow the provided instructions, and the deployment will continue as soon as the authentication process is completed.
 
-    ```bash
-    serverless deploy
-    ```
+```bash
+$ sls deploy
+```
 
-    > Note: Once you've authenticated, a new Azure "service principal" will be created, and used for subsequent deployments. This prevents you from needing to manually login again. See [below](#advanced-authentication) if you'd prefer to use a custom service principal instead.
+For more advanced deployment scenarios, see our [deployment docs](docs/DEPLOY.md)
 
-2. Invoke a function, in order to test that it works:
+### Test Your Function App
 
-    ```bash
-    serverless invoke -f hello
-    ```
+Invoke your HTTP functions without ever leaving the CLI using:
 
-3. Stream the output logs for your function:
+```bash
+$ sls invoke -f <functionName>
+```
 
-    ```bash
-    serverless logs -f hello
-    ```
- 
-4. Make some code changes, `deploy` again, view logs, etc. and provide us feedback on how to make the experience even better!
+##### Invoke Options
 
-    > Note: If you're working on a single function, you can use the `serverless deploy function -f <function>` command instead of `serverless deploy`, which will simply deploy the specified function instead of the entire service.
+- `-f` or `--function` - Function to Invoke
+- `-d` or `--data` - Stringified JSON data to use as either query params or request body
+- `-p` or `--path` - Path to JSON file to use as either query params or request body
+- `-m` or `--method` - HTTP method for request
 
-If at any point, you no longer need your service, you can run the following command to remove the Azure Functions that were created, and ensure you don't incur any unexpected charges:
+##### Example
+
+After deploying template function app, run
 
 ```bash
-serverless remove
-``` 
+$ sls invoke -f hello '{"name": "Azure"}'
+```
 
-### Advanced Authentication
+### Roll Back Your Function App
+
+To roll back your function app to a previous deployment, simply select a timestamp of a previous deployment and use `rollback` command.
+
+```bash
+# List all deployments to know the timestamp for rollback
+$ sls deploy list
+Serverless:
+-----------
+Name: myFunctionApp-t1561479533
+Timestamp: 1561479533
+Datetime: 2019-06-25T16:18:53+00:00
+-----------
+Name: myFunctionApp-t1561479506
+Timestamp: 1561479506
+Datetime: 2019-06-25T16:18:26+00:00
+-----------
+Name: myFunctionApp-t1561479444
+Timestamp: 1561479444
+Datetime: 2019-06-25T16:17:24+00:00
+-----------
+
+# Rollback Function App to timestamp
+$ sls rollback -t 1561479506
+```
+
+This will update the app code and infrastructure to the selected previous deployment.
+
+For more details, check out our [rollback docs](docs/ROLLBACK.md).
+
+### Deleting Your Function App
 
-The getting started walkthrough illustrates the interactive login experience, which is recommended for most users. However, if you'd prefer to create an Azure ["service principal"](https://github.com/Azure/azure-sdk-for-node/blob/master/Documentation/Authentication.md#2-azure-cli) yourself, you can indicate that this plugin should use its credentials instead, by setting the following environment variables:
+If at any point you no longer need your service, you can run the following command to delete the resource group containing your Azure Function App and other depoloyed resources using:
 
-**Bash**
 ```bash
-export azureSubId='<subscriptionId>'
-export azureServicePrincipalTenantId='<tenantId>'
-export azureServicePrincipalClientId='<servicePrincipalName>'
-export azureServicePrincipalPassword='<password>'
+$ sls remove
 ```
 
-**Powershell**
-```powershell
-$env:azureSubId='<subscriptionId>'
-$env:azureServicePrincipalTenantId='<tenantId>'
-$env:azureServicePrincipalClientId='<servicePrincipalName>'
-$env:azureServicePrincipalPassword='<password>'
+### Creating or removing Azure Functions
+
+To create a new Azure Function within your function app, run the following command from within your app's directory:
+
+```bash
+# -n or --name for name of new function
+$ sls func add -n {functionName}
 ```
 
+This will create a new handler file at the root of your project with the title `{functionName}.js`. It will also update `serverless.yml` to contain the new function.
+
+To remove an existing Azure Function from your function app, run the following command from within your app's directory:
+
+```bash
+# -n or --name for name of function to remove
+$ sls func remove -n {functionName}
+```
+
+This will remove the `{functionName}.js` handler and remove the function from `serverless.yml`
+
+*Note: Add & remove currently only support HTTP triggered functions. For other triggers, you will need to update `serverless.yml` manually
+
+### Advanced Authentication
+
+The getting started walkthrough illustrates the interactive login experience, which is recommended when getting started. However, for more robust use, a [service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals) is recommended for authentication.
+
+##### Creating a Service Principal
+
+1. [Install the Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
+2. Login via Azure CLI and set subscription
+    ```bash
+    # Login to Azure
+    $ az login
+    # Set Azure Subscription for which to create Service Principal
+    $ az account set -s <subscription-id>
+    ```
+3. Generate Service Principal for Azure Subscription
+    ```bash
+    # Create SP with unique name
+    $ az ad sp create-for-rbac --name <name>
+    ```
+    This will yield something like:
+    ```json
+    {
+      "appId": "<servicePrincipalId>",
+      "displayName": "<name>",
+      "name": "<name>",
+      "password": "<password>",
+      "tenant": "<tenantId>"
+    }
+    ```
+4. Set environment variables
+
+    **Bash**
+    ```bash
+    $ export azureSubId='<subscriptionId>'
+    $ export azureServicePrincipalTenantId='<tenantId>'
+    $ export azureServicePrincipalClientId='<servicePrincipalId>'
+    $ export azureServicePrincipalPassword='<password>'
+    ```
+
+    **Powershell**
+    ```powershell
+    $env:azureSubId='<subscriptionId>'
+    $env:azureServicePrincipalTenantId='<tenantId>'
+    $env:azureServicePrincipalClientId='<servicePrincipalName>'
+    $env:azureServicePrincipalPassword='<password>'
+    ```
+
 ### Contributing
 
 Please create issues in this repo for any problems or questions you find. Before sending a PR for any major changes, please create an issue to discuss.
@@ -128,27 +201,23 @@ We're still in the process of getting everying running 100%, but please refer to
 1. Clone this repository to your local machine
 2. Navigate to the cloned folder
 3. Run `npm install`
-4. Run `npm run-script build`
+4. Run `npm run build`
 5. Navigate to a folder where you created a new Serverless project, run `npm install`, and then run `npm link {path to serverless-azure-functions folder}`. Running `npm install` after the link command may override the link.
-6. The npm modules should now contain your local version of this plugin.  
-
-#### Signing commits
-
-All commits in your Pull Request will need to be signed. When looking at the commits in the pull request, you will see a green 'verified' icon next to your commit. Commit signature verification is discussed [here](https://help.github.com/en/articles/about-commit-signature-verification)
+6. The npm modules should now contain your local version of this plugin.
 
-Follow the directions [here](https://help.github.com/en/articles/signing-commits) to configure commit signing.
+#### Unit Tests
 
-If any of your commits are not signed, your pull request will not be able to be merged into the base branch. You can fix this by squashing any unsigned commits into signed commits using an interactive rebase, and force pushing your new commit history. More detail [here](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History)
+We use [Jest](https://jestjs.io/) for unit tests, and it is expected that every Pull Request containing code changes have accompanying unit tests.
 
-When using Windows you may also encounter an error when trying to sign a commit, stating that a security key could not be found. Ensure that you have set the path the gpg in the git config: `git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"`
+Run unit tests using `npm test` or `npm run test:coverage` to get coverage results.
 
 #### Signing commits
 
-All commits in your Pull Request will need to be signed. When looking at the commits in the pull request, you will see a green 'verified' icon next to your commit. Commit signature verification is discussed [here](https://help.github.com/en/articles/about-commit-signature-verification)
+All commits in your Pull Request will need to be signed. When looking at the commits in the pull request, you will see a green 'verified' icon next to your commit. Commit signature verification is discussed [here](https://help.github.com/en/articles/about-commit-signature-verification).
 
 Follow the directions [here](https://help.github.com/en/articles/signing-commits) to configure commit signing.
 
-If any of your commits are not signed, your pull request will not be able to be merged into the base branch. You can fix this by squashing any unsigned commits into signed commits using an interactive rebase, and force pushing your new commit history. More detail [here](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History)
+If any of your commits are not signed, your pull request will not be able to be merged into the base branch. You can fix this by squashing any unsigned commits into signed commits using an interactive rebase, and force pushing your new commit history. More detail [here](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History).
 
 When using Windows you may also encounter an error when trying to sign a commit, stating that a security key could not be found. Ensure that you have set the path the gpg in the git config: `git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"`
 
diff --git a/package-lock.json b/package-lock.json
index b52ea54..8f27d8f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "serverless-azure-functions",
-  "version": "1.0.0-5",
+  "version": "1.0.0-6",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/package.json b/package.json
index a6baa47..f8d38ce 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "serverless-azure-functions",
-  "version": "1.0.0-5",
+  "version": "1.0.0-6",
   "description": "Provider plugin for the Serverless Framework v1.x which adds support for Azure Functions.",
   "license": "MIT",
   "main": "./lib/index.js",
@@ -16,7 +16,8 @@
     "test:coverage": "npm run test -- --coverage",
     "compile": "tsc",
     "prebuild": "shx rm -rf lib/ && npm run test",
-    "build": "npm run compile"
+    "build": "npm run compile",
+    "generate:spn": "bash ./scripts/generate-service-principal.sh"
   },
   "repository": {
     "git": "https://github.com/serverless/serverless-azure-functions"
diff --git a/scripts/npmVersionBumpPrerelease.sh b/scripts/npmVersionBumpPrerelease.sh
index a3c30ec..e1951d2 100755
--- a/scripts/npmVersionBumpPrerelease.sh
+++ b/scripts/npmVersionBumpPrerelease.sh
@@ -10,12 +10,12 @@ git checkout -b npmRelease
 ## configure npm to sign commit
 npm config set sign-git-tag true
 
-version=$(npm version prerelease -m "Bumped to version %s")
+version=$(npm version prerelease -m "release: Bumped to version %s")
 
 echo "Bumped to version ${version}"
 
 # remove git tag, we don't want to tag pr
-git tag -d ${version} 
+git tag -d ${version}
 
 # push to remote
 git push origin npmRelease
diff --git a/src/plugins/apim/azureApimFunctionPlugin.ts b/src/plugins/apim/azureApimFunctionPlugin.ts
index da6cec6..ff8010a 100644
--- a/src/plugins/apim/azureApimFunctionPlugin.ts
+++ b/src/plugins/apim/azureApimFunctionPlugin.ts
@@ -5,8 +5,8 @@ import { AzureBasePlugin } from "../azureBasePlugin";
 export class AzureApimFunctionPlugin extends AzureBasePlugin {
   public hooks: { [eventName: string]: Promise<any> };
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     this.hooks = {
       "after:deploy:function:deploy": this.deploy.bind(this)
     };
diff --git a/src/plugins/apim/azureApimServicePlugin.ts b/src/plugins/apim/azureApimServicePlugin.ts
index 92d4739..3aa6e5e 100644
--- a/src/plugins/apim/azureApimServicePlugin.ts
+++ b/src/plugins/apim/azureApimServicePlugin.ts
@@ -5,8 +5,8 @@ import { AzureBasePlugin } from "../azureBasePlugin";
 export class AzureApimServicePlugin extends AzureBasePlugin {
   public hooks: { [eventName: string]: Promise<any> };
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     this.hooks = {
       "after:deploy:deploy": this.deploy.bind(this)
     };
diff --git a/src/plugins/azureBasePlugin.ts b/src/plugins/azureBasePlugin.ts
index 0869bad..e90b584 100644
--- a/src/plugins/azureBasePlugin.ts
+++ b/src/plugins/azureBasePlugin.ts
@@ -1,9 +1,11 @@
 import { Guard } from "../shared/guard";
 import Serverless from "serverless";
+import { Utils } from "../shared/utils";
 
 export abstract class AzureBasePlugin {
   public constructor(
     protected serverless: Serverless,
+    protected options: Serverless.Options,
   ) {
     Guard.null(serverless);
   }
@@ -11,4 +13,8 @@ export abstract class AzureBasePlugin {
   protected log(message: string) {
     this.serverless.cli.log(message);
   }
+
+  protected getOption(key: string, defaultValue?: any): string {
+    return Utils.get(this.options, key, defaultValue);
+  }
 }
diff --git a/src/plugins/deploy/azureDeployPlugin.ts b/src/plugins/deploy/azureDeployPlugin.ts
index 52e451c..945b672 100644
--- a/src/plugins/deploy/azureDeployPlugin.ts
+++ b/src/plugins/deploy/azureDeployPlugin.ts
@@ -4,12 +4,13 @@ import { ResourceService } from "../../services/resourceService";
 import { Utils } from "../../shared/utils";
 import { AzureBasePlugin } from "../azureBasePlugin";
 
+
 export class AzureDeployPlugin extends AzureBasePlugin {
   public hooks: { [eventName: string]: Promise<any> };
   public commands: any;
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
 
     this.hooks = {
       "deploy:deploy": this.deploy.bind(this),
diff --git a/src/plugins/func/azureFuncPlugin.ts b/src/plugins/func/azureFuncPlugin.ts
index 09ec9ad..599f6fb 100644
--- a/src/plugins/func/azureFuncPlugin.ts
+++ b/src/plugins/func/azureFuncPlugin.ts
@@ -7,8 +7,8 @@ export class AzureFuncPlugin extends AzureBasePlugin {
   public commands: any;
   private service: FuncService;
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
 
     this.hooks = {
       "func:func": this.func.bind(this),
diff --git a/src/plugins/invoke/azureInvokePlugin.ts b/src/plugins/invoke/azureInvokePlugin.ts
index 0905530..4c18936 100644
--- a/src/plugins/invoke/azureInvokePlugin.ts
+++ b/src/plugins/invoke/azureInvokePlugin.ts
@@ -9,8 +9,8 @@ export class AzureInvokePlugin extends AzureBasePlugin {
   public hooks: { [eventName: string]: Promise<any> };
   private commands: ServerlessCommandMap;
   private invokeService: InvokeService;
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     const path = this.options["path"];
 
     if (path) {
diff --git a/src/plugins/login/azureLoginPlugin.ts b/src/plugins/login/azureLoginPlugin.ts
index d59b049..188086f 100644
--- a/src/plugins/login/azureLoginPlugin.ts
+++ b/src/plugins/login/azureLoginPlugin.ts
@@ -7,8 +7,8 @@ export class AzureLoginPlugin extends AzureBasePlugin {
   private provider: AzureProvider;
   public hooks: { [eventName: string]: Promise<any> };
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     this.provider = (this.serverless.getProvider("azure") as any) as AzureProvider;
 
     this.hooks = {
diff --git a/src/plugins/logs/azureLogsPlugin.ts b/src/plugins/logs/azureLogsPlugin.ts
index 05e7c81..3c4acc8 100644
--- a/src/plugins/logs/azureLogsPlugin.ts
+++ b/src/plugins/logs/azureLogsPlugin.ts
@@ -7,8 +7,8 @@ export class AzureLogsPlugin extends AzureBasePlugin {
 
   private provider: AzureProvider;
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
 
     this.provider = (this.serverless.getProvider("azure") as any) as AzureProvider;
 
diff --git a/src/plugins/offline/azureOfflinePlugin.ts b/src/plugins/offline/azureOfflinePlugin.ts
index a3b1ad4..2f5f879 100644
--- a/src/plugins/offline/azureOfflinePlugin.ts
+++ b/src/plugins/offline/azureOfflinePlugin.ts
@@ -7,8 +7,8 @@ export class AzureOfflinePlugin extends AzureBasePlugin {
   public commands: any;
   private offlineService: OfflineService;
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     this.offlineService = new OfflineService(this.serverless, this.options);
 
     this.hooks = {
diff --git a/src/plugins/package/azurePackagePlugin.ts b/src/plugins/package/azurePackagePlugin.ts
index ef317a3..abfb7b9 100644
--- a/src/plugins/package/azurePackagePlugin.ts
+++ b/src/plugins/package/azurePackagePlugin.ts
@@ -10,8 +10,8 @@ export class AzurePackagePlugin extends AzureBasePlugin {
   public provider: AzureProvider;
   public hooks: { [eventName: string]: Promise<any> };
 
-  public constructor(serverless: Serverless) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     this.hooks = {
       "before:package:setupProviderConfiguration": this.setupProviderConfiguration.bind(this),
       "before:webpack:package:packageModules": this.webpack.bind(this),
diff --git a/src/plugins/remove/azureRemovePlugin.ts b/src/plugins/remove/azureRemovePlugin.ts
index 4eb2928..e4fe885 100644
--- a/src/plugins/remove/azureRemovePlugin.ts
+++ b/src/plugins/remove/azureRemovePlugin.ts
@@ -5,8 +5,8 @@ import { AzureBasePlugin } from "../azureBasePlugin";
 export class AzureRemovePlugin extends AzureBasePlugin {
   public hooks: { [eventName: string]: Promise<any> };
 
-  public constructor(serverless: Serverless, private options: Serverless.Options) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     this.hooks = {
       "remove:remove": this.remove.bind(this)
     };
diff --git a/src/plugins/rollback/azureRollbackPlugin.ts b/src/plugins/rollback/azureRollbackPlugin.ts
index a3c24e3..438d77b 100644
--- a/src/plugins/rollback/azureRollbackPlugin.ts
+++ b/src/plugins/rollback/azureRollbackPlugin.ts
@@ -1,13 +1,15 @@
 import Serverless from "serverless";
 import { RollbackService } from "../../services/rollbackService";
+import { AzureBasePlugin } from "../azureBasePlugin";
 
 /**
  * Plugin for rolling back Function App Service to previous deployment
  */
-export class AzureRollbackPlugin {
+export class AzureRollbackPlugin extends AzureBasePlugin {
   public hooks: { [eventName: string]: Promise<any> };
 
-  public constructor(private serverless: Serverless, private options: Serverless.Options) {
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
     this.hooks = {
       "rollback:rollback": this.rollback.bind(this)
     };


Test patch:
diff --git a/src/plugins/azureBasePlugin.test.ts b/src/plugins/azureBasePlugin.test.ts
index 3269408..e3a8d54 100644
--- a/src/plugins/azureBasePlugin.test.ts
+++ b/src/plugins/azureBasePlugin.test.ts
@@ -3,13 +3,17 @@ import Serverless from "serverless";
 import { MockFactory } from "../test/mockFactory";
 
 class MockPlugin extends AzureBasePlugin {
-  public constructor(serverless: Serverless) {
-    super(serverless);
+  public constructor(serverless: Serverless, options: Serverless.Options) {
+    super(serverless, options);
   }
 
   public logMessage(message: string) {
     this.log(message);
   }
+
+  public getServerlessOption(key: string, defaultValue?: any) {
+    return this.getOption(key, defaultValue);
+  }
 }
 
 describe("Azure Base Plugin", () => {
@@ -18,12 +22,22 @@ describe("Azure Base Plugin", () => {
 
   beforeEach(() => {
     sls = MockFactory.createTestServerless();
-    plugin = new MockPlugin(sls);
+    const options = MockFactory.createTestServerlessOptions();
+    options["key1"] = "val1";
+    options["key2"] = "val2";
+    plugin = new MockPlugin(sls, options);
   });
 
 
   it("logs a message", () => {
     plugin.logMessage("test message");
     expect(sls.cli.log).lastCalledWith("test message");
-  })
+  });
+
+  it("gets an option", () => {
+    expect(plugin.getServerlessOption("key1")).toEqual("val1");
+    expect(plugin.getServerlessOption("key2")).toEqual("val2");
+    expect(plugin.getServerlessOption("key3")).toBeUndefined();
+    expect(plugin.getServerlessOption("key3", "myValue")).toEqual("myValue");
+  });
 })
diff --git a/src/plugins/package/azurePackagePlugin.test.ts b/src/plugins/package/azurePackagePlugin.test.ts
index 34ddcd5..f40c307 100644
--- a/src/plugins/package/azurePackagePlugin.test.ts
+++ b/src/plugins/package/azurePackagePlugin.test.ts
@@ -12,8 +12,9 @@ describe("Azure Package Plugin", () => {
   beforeEach(() => {
     jest.resetAllMocks();
     sls = MockFactory.createTestServerless();
+    const options = MockFactory.createTestServerlessOptions();
 
-    plugin = new AzurePackagePlugin(sls);
+    plugin = new AzurePackagePlugin(sls, options);
   });
 
   it("sets creates function bindings before package:setupProviderConfiguration life cycle event", async () => {