Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 141 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,46 @@
# Azure Functions Serverless Plugin
# Azure Functions Serverless Plugin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need to add more in addition to the quickstart. But this is good for now.


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

1. Node.js v6.5.0+ *(this is the runtime version supported by Azure Functions)*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should follow markdown list syntax and use

1. one
1. two
1. three

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The markdown guide lists the actual numbered version as the first style, but they both render to the same thing. Also, the VS Code extension auto-generates the next number with a new line.

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.

Expand All @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add reference to use the script I wrote?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should talk about where that should live. I don't know if it's in the quickstart, just because we expose that script in the scripts section of package.json, and it would be kinda awkward for people that were consuming the plugin to drill into node_modules to go run the script. If that script were available in the project template, then I think it would make sense to be here. I think that would go in other more detailed dev docs, just because we'd have to have other instructions like installing jq. Open to chat about where to put that in the future, but I'll probably leave it out for now


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.
Expand All @@ -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"`

Expand Down