Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.

Commit 2180a9a

Browse files
authored
feat: Linux & Python Runtime Support (#420)
* feat: Linux & Python Runtime Support * Respond to PR feedback * Update API endpoint to work with linux (#429)
1 parent 90221cd commit 2180a9a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1527
-779
lines changed

.vscode/launch.json

+35-33
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
11
{
2-
"version": "0.2.0",
3-
"configurations": [
4-
{
5-
"type": "node",
6-
"request": "launch",
7-
"name": "Jest All",
8-
"program": "${workspaceFolder}/node_modules/.bin/jest",
9-
"args": ["--runInBand"],
10-
"console": "integratedTerminal",
11-
"internalConsoleOptions": "neverOpen",
12-
"disableOptimisticBPs": true,
13-
"windows": {
14-
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
15-
}
16-
},
17-
{
18-
"type": "node",
19-
"request": "launch",
20-
"name": "Jest Current File",
21-
"program": "${workspaceFolder}/node_modules/.bin/jest",
22-
"args": [
23-
"${fileBasenameNoExtension}",
24-
"--config",
25-
"jest.config.js"
26-
],
27-
"console": "integratedTerminal",
28-
"internalConsoleOptions": "neverOpen",
29-
"disableOptimisticBPs": true,
30-
"windows": {
31-
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
32-
}
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"type": "node",
6+
"request": "launch",
7+
"name": "Jest All",
8+
"program": "${workspaceFolder}/node_modules/.bin/jest",
9+
"args": [
10+
"--runInBand"
11+
],
12+
"console": "integratedTerminal",
13+
"internalConsoleOptions": "neverOpen",
14+
"disableOptimisticBPs": true,
15+
"windows": {
16+
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
3317
}
34-
]
35-
}
18+
},
19+
{
20+
"type": "node",
21+
"request": "launch",
22+
"name": "Jest Current File",
23+
"program": "${workspaceFolder}/node_modules/.bin/jest",
24+
"args": [
25+
"${fileBasenameNoExtension}",
26+
"--config",
27+
"jest.config.js"
28+
],
29+
"console": "integratedTerminal",
30+
"internalConsoleOptions": "neverOpen",
31+
"disableOptimisticBPs": true,
32+
"windows": {
33+
"program": "${workspaceFolder}/node_modules/jest/bin/jest",
34+
}
35+
}
36+
]
37+
}

README.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ $ cd <appName>
2323
$ npm install
2424
```
2525

26+
The `serverless.yml` file contains the configuration for your service. For more details on its configuration, see [the docs](docs/CONFIG.md).
27+
2628
### Running Function App Locally (`offline` plugin)
2729

2830
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:
@@ -57,9 +59,17 @@ $ sls offline build
5759
To clean up files generated from the build, run:
5860

5961
```bash
60-
sls offline cleanup
62+
$ sls offline cleanup
63+
```
64+
65+
To pass additional arguments to the spawned `func host start` process, add them as the option `spawnargs` (shortcut `a`). Example:
66+
67+
```bash
68+
$ sls offline -a "--cors *"
6169
```
6270

71+
This works for `sls offline` or `sls offline start`
72+
6373
### Deploy Your Function App
6474

6575
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.

docs/CONFIG.md

+207
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
# Serverless Configuration
2+
3+
This document serves as a basic outline for configuring your Azure Function App through `serverless.yml`.
4+
5+
- `service` - Name of service. Used to generate name for resource group, function app, and other resources
6+
7+
## Provider Configuration
8+
9+
- `provider.name` - Name of serverless provider. Always `azure`
10+
- `provider.os` - Operating system for function app. Available options:
11+
- `windows` (default)
12+
- `linux`
13+
- `provider.runtime` - Runtime language for function app. Available options (no default, must be specified):
14+
- `nodejs10`
15+
- `nodejs12`
16+
- `python3.6` (forced to use `linux`)
17+
- `python3.7` (forced to use `linux`)
18+
- `python3.8` (forced to use `linux`)
19+
- `provider.region` - [Azure region](https://azure.microsoft.com/en-us/global-infrastructure/regions/) for resources
20+
- `provider.prefix` - Prefix used in naming convention for resources. Default `sls`
21+
- `provider.subscriptionId` - Subscription ID to be used in deployment. Can also be set via:
22+
- Command-line argument (`--subscriptionId {SUB_ID}`)
23+
- Environment variable (`AZURE_SUBSCRIPTION_ID`)
24+
- `provider.stage` - Stage for resources. Default `dev`
25+
<!-- TODO - provider.type -->
26+
- `provider.environment` - Key value pairs to set as app settings (environment variables) within function app. Example:
27+
```yaml
28+
provider:
29+
environment:
30+
VARIABLE_FOO: 'bar'
31+
```
32+
- `provider.apim` - APIM Configuration. See [documentation](../docs/examples/apim.md) for more details
33+
34+
## Plugin Configuration
35+
36+
- `plugins` - List of plugins used by service. Must always include:
37+
`- serverless-azure-functions`
38+
39+
## Package Configuration
40+
41+
- `package.include` - Files or folders to include in package
42+
- `package.exclude` - Files or folders to exclude from package
43+
44+
## Functions Configuration
45+
46+
Example:
47+
48+
```yaml
49+
functions:
50+
hello:
51+
# Handler is in src/handlers/hello.js and function sayHello
52+
handler: src/handlers/hello.sayHello
53+
events:
54+
# Http Triggered function
55+
- http: true
56+
x-azure-settings:
57+
# Allows GET method
58+
methods:
59+
- GET
60+
authLevel: anonymous # can also be `function` or `admin`
61+
```
62+
63+
## Full Example Config
64+
65+
```yaml
66+
# Welcome to Serverless!
67+
#
68+
# This file is the main config file for your service.
69+
# It's very minimal at this point and uses default values.
70+
# You can always add more config options for more control.
71+
# We've included some commented out config examples here.
72+
# Just uncomment any of them to get that config option.
73+
#
74+
# For full config options, check the docs:
75+
# docs.serverless.com
76+
#
77+
# Happy Coding!
78+
79+
service: my-api
80+
81+
# You can pin your service to only deploy with a specific Serverless version
82+
# Check out our docs for more details
83+
# frameworkVersion: "=X.X.X"
84+
85+
provider:
86+
name: azure
87+
region: West Europe
88+
runtime: nodejs10.x
89+
prefix: "sample" # prefix of generated resource name
90+
# subscriptionId: A356AC8C-E310-44F4-BF85-C7F29044AF99
91+
# stage: dev
92+
# type: premium # premium azure functions
93+
94+
environment: # these will be created as application settings
95+
VARIABLE_FOO: 'foo'
96+
97+
# you can define apim configuration here
98+
# apim:
99+
# apis:
100+
# - name: v1
101+
# subscriptionRequired: false # if true must provide an api key
102+
# displayName: v1
103+
# description: V1 sample app APIs
104+
# protocols:
105+
# - https
106+
# path: v1
107+
# tags:
108+
# - tag1
109+
# - tag2
110+
# authorization: none
111+
# cors:
112+
# allowCredentials: false
113+
# allowedOrigins:
114+
# - "*"
115+
# allowedMethods:
116+
# - GET
117+
# - POST
118+
# - PUT
119+
# - DELETE
120+
# - PATCH
121+
# allowedHeaders:
122+
# - "*"
123+
# exposeHeaders:
124+
# - "*"
125+
126+
plugins: # look for additional plugins in the community plugins repo: https://github.com/serverless/plugins
127+
- serverless-azure-functions
128+
129+
# you can add packaging information here
130+
package:
131+
# include:
132+
# - include-me.js
133+
# - include-me-dir/**
134+
exclude:
135+
# - exclude-me.js
136+
# - exclude-me-dir/**
137+
- local.settings.json
138+
- .vscode/**
139+
140+
functions:
141+
hello:
142+
handler: src/handlers/hello.sayHello
143+
events:
144+
- http: true
145+
x-azure-settings:
146+
methods:
147+
- GET
148+
authLevel: anonymous # can also be `function` or `admin`
149+
150+
goodbye:
151+
handler: src/handlers/goodbye.sayGoodbye
152+
events:
153+
- http: true
154+
x-azure-settings:
155+
methods:
156+
- GET
157+
authLevel: anonymous
158+
# The following are a few examples of other events you can configure:
159+
# storageBlob:
160+
# handler: src/handlers/storageBlob.printMessage
161+
# events:
162+
# - blob:
163+
# x-azure-settings:
164+
# name: blob # Specifies which name is available on `context`
165+
# path: blob-sample/{blobName}
166+
# connection: AzureWebJobsStorage # App Setting/environment variable which contains Storage Account Connection String
167+
# storageQueue:
168+
# handler: src/handlers/storageQueue.printMessage
169+
# events:
170+
# - queue: queue-sample
171+
# x-azure-settings:
172+
# name: message # Specifies which naem is available on `context`
173+
# connection: AzureWebJobsStorage
174+
# timer:
175+
# handler: src/handlers/timer.printMessage
176+
# events:
177+
# - timer:
178+
# x-azure-settings:
179+
# schedule: '*/10 * * * * *'
180+
# eventhub:
181+
# handler: src/handlers/eventHub.printMessage
182+
# events:
183+
# - eventHub:
184+
# x-azure-settings:
185+
# name: eventHubMessages # Specifies which name it's available on `context`
186+
# eventHubName: sample-hub # Specifies the Name of the Event Hub
187+
# consumerGroup: $Default # Specifies the consumerGroup to listen with
188+
# connection: EVENT_HUBS_CONNECTION # App Setting/environment variable which contains Event Hubs Namespace Connection String
189+
# serviceBusQueue:
190+
# handler: src/handlers/serviceBusQueue.printMessage
191+
# events:
192+
# - serviceBus:
193+
# x-azure-settings:
194+
# name: message # Specifies which name is available on `context`
195+
# queueName: sample-queue # Name of the service bus queue to consume
196+
# connection: SERVICE_BUS_CONNECTION # App Setting/environment variable variable which contains Service Bus Namespace Connection String
197+
# serviceBusTopic:
198+
# handler: src/handlers/serviceBusTopic.printMessage
199+
# events:
200+
# - serviceBus:
201+
# x-azure-settings:
202+
# name: message # Specifies which name it's available on `context`
203+
# topicName: sample-topic # Name of the service bus topic to consume
204+
# subscriptionName: sample-subscription # Name of the topic subscription to retrieve from
205+
# connection: SERVICE_BUS_CONNECTION # App Setting/environment variable variable which contains Service Bus Namespace Connection String
206+
207+
```

src/armTemplates/ase.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { HostingEnvironmentResource } from "./resources/hostingEnvironment";
66
import { VirtualNetworkResource } from "./resources/virtualNetwork";
77
import { CompositeArmTemplate } from "./compositeArmTemplate";
88
import { ArmResourceTemplate } from "../models/armTemplates";
9+
import { ServerlessAzureConfig } from "../models/serverless";
910

1011
class AppServiceEnvironmentTemplate extends CompositeArmTemplate {
1112
public constructor() {
@@ -19,8 +20,8 @@ class AppServiceEnvironmentTemplate extends CompositeArmTemplate {
1920
])
2021
}
2122

22-
public getTemplate(): ArmResourceTemplate {
23-
const template = super.getTemplate();
23+
public getTemplate(config: ServerlessAzureConfig): ArmResourceTemplate {
24+
const template = super.getTemplate(config);
2425

2526
template.parameters.appServicePlanSkuName.defaultValue = "I1";
2627
template.parameters.appServicePlanSkuTier.defaultValue = "Isolated";

src/armTemplates/compositeArmTemplate.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class CompositeArmTemplate implements ArmResourceTemplateGenerator {
88
Guard.null(childTemplates);
99
}
1010

11-
public getTemplate(): ArmResourceTemplate {
11+
public getTemplate(config: ServerlessAzureConfig): ArmResourceTemplate {
1212
const template: ArmResourceTemplate = {
1313
$schema:
1414
"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
@@ -18,7 +18,7 @@ export class CompositeArmTemplate implements ArmResourceTemplateGenerator {
1818
};
1919

2020
this.childTemplates.forEach(resource => {
21-
const resourceTemplate = resource.getTemplate();
21+
const resourceTemplate = resource.getTemplate(config);
2222
template.parameters = {
2323
...template.parameters,
2424
...resourceTemplate.parameters

src/armTemplates/premium.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { StorageAccountResource } from "./resources/storageAccount";
44
import { AppServicePlanResource } from "./resources/appServicePlan";
55
import { ArmResourceTemplate } from "../models/armTemplates";
66
import { CompositeArmTemplate } from "./compositeArmTemplate";
7+
import { ServerlessAzureConfig } from "../models/serverless";
78

89
class PremiumPlanTemplate extends CompositeArmTemplate {
910
public constructor() {
@@ -15,8 +16,8 @@ class PremiumPlanTemplate extends CompositeArmTemplate {
1516
])
1617
}
1718

18-
public getTemplate(): ArmResourceTemplate {
19-
const template = super.getTemplate();
19+
public getTemplate(config: ServerlessAzureConfig): ArmResourceTemplate {
20+
const template = super.getTemplate(config);
2021

2122
template.parameters.appServicePlanSkuName.defaultValue = "EP1";
2223
template.parameters.appServicePlanSkuTier.defaultValue = "ElasticPremium";

src/armTemplates/resources/apim.test.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { ApimResource } from "./apim";
22
import { ServerlessAzureConfig } from "../../models/serverless";
33
import md5 from "md5";
4-
import configConstants from "../../config";
4+
import { configConstants } from "../../config/constants";
5+
import { Runtime } from "../../config/runtime";
56

67
describe("APIM Resource", () => {
78
const resourceGroupName = "myResourceGroup";
@@ -22,7 +23,7 @@ describe("APIM Resource", () => {
2223
region,
2324
stage,
2425
resourceGroup: resourceGroupName,
25-
runtime: "nodejs10.x"
26+
runtime: Runtime.NODE10,
2627
},
2728
service: ""
2829
} as any;
@@ -45,7 +46,7 @@ describe("APIM Resource", () => {
4546
region,
4647
stage,
4748
resourceGroup: resourceGroupName,
48-
runtime: "nodejs10.x"
49+
runtime: Runtime.NODE10,
4950
},
5051
service: ""
5152
} as any;

0 commit comments

Comments
 (0)