diff --git a/docker-compose.yml b/docker-compose.yml index 4649a8550..227462503 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -47,6 +47,10 @@ services: image: microsoft/dotnet:1.0.4-sdk volumes: - ./tmp/serverless-integration-test-aws-csharp:/app + aws-fsharp: + image: microsoft/dotnet:1.0.4-sdk + volumes: + - ./tmp/serverless-integration-test-aws-fsharp:/app google-nodejs: image: node:6.9.1 volumes: diff --git a/docs/providers/aws/cli-reference/create.md b/docs/providers/aws/cli-reference/create.md index 4cbca6f09..6d2a2296c 100644 --- a/docs/providers/aws/cli-reference/create.md +++ b/docs/providers/aws/cli-reference/create.md @@ -48,6 +48,7 @@ Most commonly used templates: - aws-java-gradle - aws-scala-sbt - aws-csharp +- aws-fsharp - plugin ## Examples diff --git a/docs/providers/aws/examples/hello-world/fsharp/Handler.fs b/docs/providers/aws/examples/hello-world/fsharp/Handler.fs new file mode 100644 index 000000000..b9e1806fe --- /dev/null +++ b/docs/providers/aws/examples/hello-world/fsharp/Handler.fs @@ -0,0 +1,17 @@ +namespace AwsDotnetFsharp +open Amazon.Lambda.Core + +[)>] +do () + +type Request = { Key1 : string; Key2 : string; Key3 : string } +type Response = { Message : string; Request : Request } + +module Handler = + open System + open System.IO + open System.Text + + let hello(request:Request) = + { Message="Go Serverless v1.0! Your function executed successfully!" + Request=request } \ No newline at end of file diff --git a/docs/providers/aws/examples/hello-world/fsharp/README.md b/docs/providers/aws/examples/hello-world/fsharp/README.md new file mode 100644 index 000000000..7c7de6acb --- /dev/null +++ b/docs/providers/aws/examples/hello-world/fsharp/README.md @@ -0,0 +1,37 @@ + + +# Hello World F# Example + +## Prerequisites + +* Make sure `serverless` is installed. [See installation guide](../../../guide/installation.md). +* [.Net Core 1.0.1 SDK](https://www.microsoft.com/net/download/core) + * 1.1 isn't currently supported by AWS Lambda +* [NodeJS v4 or higher](https://nodejs.org/en/) +* An AWS Account + +## Build and Package + +From the root of this directory, run `build.cmd`, or `build.sh` if on Linux / Mac. + +This will produce your deployment package at `bin/release/netcoreapp1.0/deploy-package.zip`. + +## Deployment and Invocation + +Once packaged, you can follow [these instructions](https://github.com/serverless/serverless#quick-start) to deploy and remotely invoke the function on AWS Lambda. + +In short the commands you will need to run are (from the root of this directory): + +``` +serverless config credentials --provider aws --key {YourAwsAccessKey} --secret {YourAwsSecret} +serverless deploy -v +serverless invoke -f hello -l +serverless remove +``` + +By default this template deploys to us-east-1, you can change that in "serverless.yml" under the `region: us-east-1` key. \ No newline at end of file diff --git a/docs/providers/aws/examples/hello-world/fsharp/aws-fsharp.fsproj b/docs/providers/aws/examples/hello-world/fsharp/aws-fsharp.fsproj new file mode 100644 index 000000000..f3a1aafd4 --- /dev/null +++ b/docs/providers/aws/examples/hello-world/fsharp/aws-fsharp.fsproj @@ -0,0 +1,24 @@ + + + + netcoreapp1.0 + FsharpHandlers + aws-fsharp + + + + + + + + + + + + + + + + + + diff --git a/docs/providers/aws/examples/hello-world/fsharp/serverless.yml b/docs/providers/aws/examples/hello-world/fsharp/serverless.yml new file mode 100644 index 000000000..c90e1089a --- /dev/null +++ b/docs/providers/aws/examples/hello-world/fsharp/serverless.yml @@ -0,0 +1,87 @@ +# Welcome to Serverless! +# +# This file is the main config file for your service. +# It's very minimal at this point and uses default values. +# You can always add more config options for more control. +# We've included some commented out config examples here. +# Just uncomment any of them to get that config option. +# +# For full config options, check the docs: +# docs.serverless.com +# +# Happy Coding! + +service: aws-fsharp # NOTE: update this with your service name + +# You can pin your service to only deploy with a specific Serverless version +# Check out our docs for more details +# frameworkVersion: "=X.X.X" + +provider: + name: aws + runtime: dotnetcore1.0 + +# you can overwrite defaults here +# stage: dev +# region: us-east-1 + +# you can add statements to the Lambda function's IAM Role here +# iamRoleStatements: +# - Effect: "Allow" +# Action: +# - "s3:ListBucket" +# Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] } +# - Effect: "Allow" +# Action: +# - "s3:PutObject" +# Resource: +# Fn::Join: +# - "" +# - - "arn:aws:s3:::" +# - "Ref" : "ServerlessDeploymentBucket" + +# you can define service wide environment variables here +# environment: +# variable1: value1 + +# you can add packaging information here +package: + artifact: bin/release/netcoreapp1.0/deploy-package.zip +# exclude: +# - exclude-me.js +# - exclude-me-dir/** + +functions: + hello: + handler: FsharpHandlers::AwsDotnetFsharp.Handler::hello + +# The following are a few example events you can configure +# NOTE: Please make sure to change your handler code to work with those events +# Check the event documentation for details +# events: +# - http: +# path: users/create +# method: get +# - s3: ${env:BUCKET} +# - schedule: rate(10 minutes) +# - sns: greeter-topic +# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 +# - alexaSkill +# - iot: +# sql: "SELECT * FROM 'some_topic'" + +# Define function environment variables here +# environment: +# variable2: value2 + +# you can add CloudFormation resource templates here +#resources: +# Resources: +# NewResource: +# Type: AWS::S3::Bucket +# Properties: +# BucketName: my-new-bucket +# Outputs: +# NewOutput: +# Description: "Description for the output" +# Value: "Some output value" diff --git a/docs/providers/aws/guide/services.md b/docs/providers/aws/guide/services.md index ee776f9e2..dd96c4c24 100644 --- a/docs/providers/aws/guide/services.md +++ b/docs/providers/aws/guide/services.md @@ -58,6 +58,7 @@ Here are the available runtimes for AWS Lambda: * aws-java-maven * aws-scala-sbt * aws-csharp +* aws-fsharp Check out the [create command docs](../cli-reference/create) for all the details and options. diff --git a/lib/plugins/create/create.js b/lib/plugins/create/create.js index 7851a43a8..eb62cc843 100644 --- a/lib/plugins/create/create.js +++ b/lib/plugins/create/create.js @@ -16,6 +16,7 @@ const validTemplates = [ 'aws-java-gradle', 'aws-scala-sbt', 'aws-csharp', + 'aws-fsharp', 'azure-nodejs', 'openwhisk-nodejs', 'openwhisk-python', diff --git a/lib/plugins/create/create.test.js b/lib/plugins/create/create.test.js index eabe5a2d6..f77496b3d 100644 --- a/lib/plugins/create/create.test.js +++ b/lib/plugins/create/create.test.js @@ -121,6 +121,28 @@ describe('Create', () => { }); }); + it('should generate scaffolding for "aws-fsharp" template', () => { + process.chdir(tmpDir); + create.options.template = 'aws-fsharp'; + + return create.create().then(() => { + expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'serverless.yml'))) + .to.be.equal(true); + expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'Handler.fs'))) + .to.be.equal(true); + expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, '.gitignore'))) + .to.be.equal(true); + expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'build.sh'))) + .to.be.equal(true); + expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'build.cmd'))) + .to.be.equal(true); + expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'aws-fsharp.fsproj'))) + .to.be.equal(true); + expect(create.serverless.utils.fileExistsSync(path.join(tmpDir, 'global.json'))) + .to.be.equal(true); + }); + }); + it('should generate scaffolding for "aws-python" template', () => { process.chdir(tmpDir); create.options.template = 'aws-python'; diff --git a/lib/plugins/create/templates/aws-csharp/serverless.yml b/lib/plugins/create/templates/aws-csharp/serverless.yml index 5d227388b..1498ed2a5 100644 --- a/lib/plugins/create/templates/aws-csharp/serverless.yml +++ b/lib/plugins/create/templates/aws-csharp/serverless.yml @@ -67,6 +67,7 @@ functions: # - schedule: rate(10 minutes) # - sns: greeter-topic # - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 +# - alexaSkill # - iot: # sql: "SELECT * FROM 'some_topic'" # - cloudwatchEvent: diff --git a/lib/plugins/create/templates/aws-fsharp/Handler.fs b/lib/plugins/create/templates/aws-fsharp/Handler.fs new file mode 100644 index 000000000..e1eb3a208 --- /dev/null +++ b/lib/plugins/create/templates/aws-fsharp/Handler.fs @@ -0,0 +1,17 @@ +namespace AwsDotnetFsharp +open Amazon.Lambda.Core + +[)>] +do () + +type Request = { Key1 : string; Key2 : string; Key3 : string } +type Response = { Message : string; Request : Request } + +module Handler = + open System + open System.IO + open System.Text + + let hello(request:Request) = + { Message="Go Serverless v1.0! Your function executed successfully!" + Request=request } diff --git a/lib/plugins/create/templates/aws-fsharp/aws-fsharp.fsproj b/lib/plugins/create/templates/aws-fsharp/aws-fsharp.fsproj new file mode 100644 index 000000000..f3a1aafd4 --- /dev/null +++ b/lib/plugins/create/templates/aws-fsharp/aws-fsharp.fsproj @@ -0,0 +1,24 @@ + + + + netcoreapp1.0 + FsharpHandlers + aws-fsharp + + + + + + + + + + + + + + + + + + diff --git a/lib/plugins/create/templates/aws-fsharp/build.cmd b/lib/plugins/create/templates/aws-fsharp/build.cmd new file mode 100644 index 000000000..468f8503a --- /dev/null +++ b/lib/plugins/create/templates/aws-fsharp/build.cmd @@ -0,0 +1,2 @@ +dotnet restore +dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip diff --git a/lib/plugins/create/templates/aws-fsharp/build.sh b/lib/plugins/create/templates/aws-fsharp/build.sh new file mode 100644 index 000000000..892b0f289 --- /dev/null +++ b/lib/plugins/create/templates/aws-fsharp/build.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +#install zip +apt-get -qq update +apt-get -qq -y install zip + +dotnet restore + +#create deployment package +dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip diff --git a/lib/plugins/create/templates/aws-fsharp/gitignore b/lib/plugins/create/templates/aws-fsharp/gitignore new file mode 100644 index 000000000..4dc157e7f --- /dev/null +++ b/lib/plugins/create/templates/aws-fsharp/gitignore @@ -0,0 +1,246 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ +*.orig + +# macOS +.DS_Store + +# JetBrains Rider C# IDE +.idea* + +# Serverless directories +.serverless diff --git a/lib/plugins/create/templates/aws-fsharp/global.json b/lib/plugins/create/templates/aws-fsharp/global.json new file mode 100644 index 000000000..8af244a46 --- /dev/null +++ b/lib/plugins/create/templates/aws-fsharp/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "1.0.4" + } +} diff --git a/lib/plugins/create/templates/aws-fsharp/serverless.yml b/lib/plugins/create/templates/aws-fsharp/serverless.yml new file mode 100644 index 000000000..314962e28 --- /dev/null +++ b/lib/plugins/create/templates/aws-fsharp/serverless.yml @@ -0,0 +1,101 @@ +# Welcome to Serverless! +# +# This file is the main config file for your service. +# It's very minimal at this point and uses default values. +# You can always add more config options for more control. +# We've included some commented out config examples here. +# Just uncomment any of them to get that config option. +# +# For full config options, check the docs: +# docs.serverless.com +# +# Happy Coding! + +service: aws-fsharp # NOTE: update this with your service name + +# You can pin your service to only deploy with a specific Serverless version +# Check out our docs for more details +# frameworkVersion: "=X.X.X" + +provider: + name: aws + runtime: dotnetcore1.0 + +# you can overwrite defaults here +# stage: dev +# region: us-east-1 + +# you can add statements to the Lambda function's IAM Role here +# iamRoleStatements: +# - Effect: "Allow" +# Action: +# - "s3:ListBucket" +# Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] } +# - Effect: "Allow" +# Action: +# - "s3:PutObject" +# Resource: +# Fn::Join: +# - "" +# - - "arn:aws:s3:::" +# - "Ref" : "ServerlessDeploymentBucket" +# - "/*" + +# you can define service wide environment variables here +# environment: +# variable1: value1 + +# you can add packaging information here +package: + artifact: bin/release/netcoreapp1.0/deploy-package.zip +# exclude: +# - exclude-me.js +# - exclude-me-dir/** + +functions: + hello: + handler: FsharpHandlers::AwsDotnetFsharp.Handler::hello + +# The following are a few example events you can configure +# NOTE: Please make sure to change your handler code to work with those events +# Check the event documentation for details +# events: +# - http: +# path: users/create +# method: get +# - s3: ${env:BUCKET} +# - schedule: rate(10 minutes) +# - sns: greeter-topic +# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 +# - alexaSkill +# - iot: +# sql: "SELECT * FROM 'some_topic'" +# - cloudwatchEvent: +# event: +# source: +# - "aws.ec2" +# detail-type: +# - "EC2 Instance State-change Notification" +# detail: +# state: +# - pending +# - cloudwatchLog: '/aws/lambda/hello' +# - cognitoUserPool: +# pool: MyUserPool +# trigger: PreSignUp + +# Define function environment variables here +# environment: +# variable2: value2 + +# you can add CloudFormation resource templates here +#resources: +# Resources: +# NewResource: +# Type: AWS::S3::Bucket +# Properties: +# BucketName: my-new-bucket +# Outputs: +# NewOutput: +# Description: "Description for the output" +# Value: "Some output value" diff --git a/tests/templates/test_all_templates b/tests/templates/test_all_templates index 76a345eee..b539c35d1 100755 --- a/tests/templates/test_all_templates +++ b/tests/templates/test_all_templates @@ -9,6 +9,7 @@ function integration-test { } integration-test aws-csharp 'apt-get -qq update && apt-get -qq -y install zip && dotnet restore && dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip' +integration-test aws-fsharp 'apt-get -qq update && apt-get -qq -y install zip && dotnet restore && dotnet lambda package --configuration release --framework netcoreapp1.0 --output-package bin/release/netcoreapp1.0/deploy-package.zip' integration-test aws-groovy-gradle ./gradlew build integration-test aws-java-gradle ./gradlew build integration-test aws-java-maven mvn package