diff --git a/.gitignore b/.gitignore index dc546ee3..04708b0f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ .swift-version xcuserdata Package.resolved +.serverless diff --git a/Examples/LambdaFunctions/README.md b/Examples/LambdaFunctions/README.md index 9d42790f..3c46a092 100644 --- a/Examples/LambdaFunctions/README.md +++ b/Examples/LambdaFunctions/README.md @@ -4,6 +4,13 @@ This sample project is a collection of Lambda functions that demonstrates how to write a simple Lambda function in Swift, and how to package and deploy it to the AWS Lambda platform. +The scripts are prepared to work from the `LambdaFunctions` folder. + +``` +git clone https://github.com/swift-server/swift-aws-lambda-runtime.git +cd swift-aws-lambda-runtime/Examples/LambdaFunctions +``` + Note: The example scripts assume you have [jq](https://stedolan.github.io/jq/download/) command line tool installed. ## Deployment instructions using AWS CLI @@ -85,3 +92,86 @@ The SAM template will provide an output labelled `LambdaApiGatewayEndpoint` whic ***Warning:*** This SAM template is only intended as a sample and creates a publicly accessible HTTP endpoint. For all other samples use the AWS Lambda console. + +### Deployment instructions using Serverless Framework (serverless.com) + +[Serverless framework](https://www.serverless.com/open-source/) (Serverless) is a provider agnostic, open-source framework for building serverless applications. This framework allows you to easily deploy other AWS resources and more complex deployment mechanisms such a CI pipelines. Serverless Framework offers solutions for not only deploying but also testing, monitoring, alerting, and security and is widely adopted by the industry and offers along the open-source version a paid one. + +***Note:*** Deploying using Serverless will automatically create resources within your AWS account. Charges may apply for these resources. + +To use Serverless to deploy this sample to AWS: + +1. Install the AWS CLI by following the [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html). + +2. Install Serverless by following the [instructions](https://www.serverless.com/framework/docs/getting-started/). +If you already have installed be sure you have the latest version. +The examples have been tested with the version 1.72.0. + +``` +Serverless --version +Framework Core: 1.72.0 (standalone) +Plugin: 3.6.13 +SDK: 2.3.1 +Components: 2.30.12 +``` + +3. Build, package and deploy the Lambda + + ``` + ./scripts/serverless-deploy.sh + ``` + +The script will ask you which sample Lambda you wish to deploy. + +The `serverless-deploy.sh` script passes through any parameters to the Serverless deploy command. + +4. Testing + +For the APIGateway sample: + +The Serverless template will provide an endpoint which you can use to test the Lambda. + +Outuput example: + +``` +... +... +Serverless: Stack update finished... +Service Information +service: apigateway-swift-aws +stage: dev +region: us-east-1 +stack: apigateway-swift-aws-dev +resources: 12 +api keys: + None +endpoints: + GET - https://r39lvhfng3.execute-api.us-east-1.amazonaws.com/api +functions: + httpGet: apigateway-swift-aws-dev-httpGet +layers: + None + +Stack Outputs +HttpGetLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:XXXXXXXXX:function:apigateway-swift-aws-dev-httpGet:1 +ServerlessDeploymentBucketName: apigateway-swift-aws-dev-serverlessdeploymentbuck-ud51msgcrj1e +HttpApiUrl: https://r39lvhfng3.execute-api.us-east-1.amazonaws.com +``` + +For example: + + ``` + curl https://r39lvhfng3.execute-api.us-east-1.amazonaws.com/api + ``` + +***Warning:*** This Serverless template is only intended as a sample and creates a publicly accessible HTTP endpoint. + +For all other samples use the AWS Lambda console. + +4. Remove + + ``` + ./scripts/serverless-remove.sh + ``` + +The script will ask you which sample Lambda you wish to remove from the previous depolyment. \ No newline at end of file diff --git a/Examples/LambdaFunctions/APIGateway-template.yml b/Examples/LambdaFunctions/scripts/SAM/APIGateway-template.yml similarity index 100% rename from Examples/LambdaFunctions/APIGateway-template.yml rename to Examples/LambdaFunctions/scripts/SAM/APIGateway-template.yml diff --git a/Examples/LambdaFunctions/Benchmark-template.yml b/Examples/LambdaFunctions/scripts/SAM/Benchmark-template.yml similarity index 100% rename from Examples/LambdaFunctions/Benchmark-template.yml rename to Examples/LambdaFunctions/scripts/SAM/Benchmark-template.yml diff --git a/Examples/LambdaFunctions/CurrencyExchange-template.yml b/Examples/LambdaFunctions/scripts/SAM/CurrencyExchange-template.yml similarity index 100% rename from Examples/LambdaFunctions/CurrencyExchange-template.yml rename to Examples/LambdaFunctions/scripts/SAM/CurrencyExchange-template.yml diff --git a/Examples/LambdaFunctions/ErrorHandling-template.yml b/Examples/LambdaFunctions/scripts/SAM/ErrorHandling-template.yml similarity index 100% rename from Examples/LambdaFunctions/ErrorHandling-template.yml rename to Examples/LambdaFunctions/scripts/SAM/ErrorHandling-template.yml diff --git a/Examples/LambdaFunctions/HelloWorld-template.yml b/Examples/LambdaFunctions/scripts/SAM/HelloWorld-template.yml similarity index 100% rename from Examples/LambdaFunctions/HelloWorld-template.yml rename to Examples/LambdaFunctions/scripts/SAM/HelloWorld-template.yml diff --git a/Examples/LambdaFunctions/scripts/build-and-package.sh b/Examples/LambdaFunctions/scripts/build-and-package.sh index 45bbea39..b59f2314 100755 --- a/Examples/LambdaFunctions/scripts/build-and-package.sh +++ b/Examples/LambdaFunctions/scripts/build-and-package.sh @@ -16,14 +16,15 @@ set -eu executable=$1 +workspace="$(pwd)/../.." echo "-------------------------------------------------------------------------" echo "building \"$executable\" lambda" echo "-------------------------------------------------------------------------" -docker run --rm -v "$(pwd)/../..":/workspace -w /workspace/Examples/LambdaFunctions builder bash -cl "swift build --product $executable -c release -Xswiftc -g" +docker run --rm -v "$workspace":/workspace -w /workspace/Examples/LambdaFunctions builder bash -cl "swift build --product $executable -c release -Xswiftc -g" echo "done" echo "-------------------------------------------------------------------------" echo "packaging \"$executable\" lambda" echo "-------------------------------------------------------------------------" -docker run --rm -v "$(pwd)/../..":/workspace -w /workspace/Examples/LambdaFunctions builder bash -cl "./scripts/package.sh $executable" +docker run --rm -v "$workspace":/workspace -w /workspace/Examples/LambdaFunctions builder bash -cl "./scripts/package.sh $executable" diff --git a/Examples/LambdaFunctions/scripts/config.sh b/Examples/LambdaFunctions/scripts/config.sh new file mode 100755 index 00000000..d6ec4b7f --- /dev/null +++ b/Examples/LambdaFunctions/scripts/config.sh @@ -0,0 +1,39 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2017-2018 Apple Inc. and the SwiftAWSLambdaRuntime project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## + +DIR="$(cd "$(dirname "$0")" && pwd)" + +executables=( $(swift package dump-package | sed -e 's|: null|: ""|g' | jq '.products[] | (select(.type.executable)) | .name' | sed -e 's|"||g') ) + +if [[ ${#executables[@]} = 0 ]]; then + echo "no executables found" + exit 1 +elif [[ ${#executables[@]} = 1 ]]; then + executable=${executables[0]} +elif [[ ${#executables[@]} > 1 ]]; then + echo "multiple executables found:" + for executable in ${executables[@]}; do + echo " * $executable" + done + echo "" + read -p "select which executables to deploy: " executable +fi + +echo "-------------------------------------------------------------------------" +echo "CONFIG" +echo "-------------------------------------------------------------------------" +echo "DIR: $DIR" +echo "executable: $executable" +echo "-------------------------------------------------------------------------" \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/deploy.sh b/Examples/LambdaFunctions/scripts/deploy.sh index 19db4a25..619826eb 100755 --- a/Examples/LambdaFunctions/scripts/deploy.sh +++ b/Examples/LambdaFunctions/scripts/deploy.sh @@ -21,21 +21,10 @@ lambda_name=SwiftSample # S3 bucket name to upload zip file (must exist in AWS S3) s3_bucket=swift-lambda-test -executables=( $(swift package dump-package | sed -e 's|: null|: ""|g' | jq '.products[] | (select(.type.executable)) | .name' | sed -e 's|"||g') ) +workspace="$(pwd)/../.." -if [[ ${#executables[@]} = 0 ]]; then - echo "no executables found" - exit 1 -elif [[ ${#executables[@]} = 1 ]]; then - executable=${executables[0]} -elif [[ ${#executables[@]} > 1 ]]; then - echo "multiple executables found:" - for executable in ${executables[@]}; do - echo " * $executable" - done - echo "" - read -p "select which executables to deploy: " executable -fi +DIR="$(cd "$(dirname "$0")" && pwd)" +source $DIR/config.sh echo -e "\ndeploying $executable" @@ -47,7 +36,7 @@ docker build . -t builder echo "-------------------------------------------------------------------------" echo "building \"$executable\" lambda" echo "-------------------------------------------------------------------------" -docker run --rm -v `pwd`/../..:/workspace -w /workspace builder \ +docker run --rm -v $workspace:/workspace -w /workspace builder \ bash -cl "cd Examples/LambdaFunctions && \ swift build --product $executable -c release -Xswiftc -g" echo "done" diff --git a/Examples/LambdaFunctions/scripts/sam-deploy.sh b/Examples/LambdaFunctions/scripts/sam-deploy.sh index 3a937828..779ed0e9 100755 --- a/Examples/LambdaFunctions/scripts/sam-deploy.sh +++ b/Examples/LambdaFunctions/scripts/sam-deploy.sh @@ -14,22 +14,7 @@ ##===----------------------------------------------------------------------===## DIR="$(cd "$(dirname "$0")" && pwd)" - -executables=( $(swift package dump-package | sed -e 's|: null|: ""|g' | jq '.products[] | (select(.type.executable)) | .name' | sed -e 's|"||g') ) - -if [[ ${#executables[@]} = 0 ]]; then - echo "no executables found" - exit 1 -elif [[ ${#executables[@]} = 1 ]]; then - executable=${executables[0]} -elif [[ ${#executables[@]} > 1 ]]; then - echo "multiple executables found:" - for executable in ${executables[@]}; do - echo " * $executable" - done - echo "" - read -p "select which executables to deploy: " executable -fi +source $DIR/config.sh echo -e "\ndeploying $executable" @@ -44,4 +29,4 @@ echo "-------------------------------------------------------------------------" echo "deploying using SAM" echo "-------------------------------------------------------------------------" -sam deploy --template "${executable}-template.yml" $@ +sam deploy --template "./scripts/SAM/${executable}-template.yml" $@ \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/serverless-deploy.sh b/Examples/LambdaFunctions/scripts/serverless-deploy.sh new file mode 100755 index 00000000..7e2d7cb0 --- /dev/null +++ b/Examples/LambdaFunctions/scripts/serverless-deploy.sh @@ -0,0 +1,32 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2017-2018 Apple Inc. and the SwiftAWSLambdaRuntime project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## + +DIR="$(cd "$(dirname "$0")" && pwd)" +source $DIR/config.sh + +echo -e "\ndeploying $executable" + +echo "-------------------------------------------------------------------------" +echo "preparing docker build image" +echo "-------------------------------------------------------------------------" +docker build . -q -t builder + +$DIR/build-and-package.sh ${executable} + +echo "-------------------------------------------------------------------------" +echo "deploying using Serverless" +echo "-------------------------------------------------------------------------" + +serverless deploy --config "./scripts/serverless/${executable}-template.yml" --stage dev -v \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/serverless-remove.sh b/Examples/LambdaFunctions/scripts/serverless-remove.sh new file mode 100755 index 00000000..f6b228c5 --- /dev/null +++ b/Examples/LambdaFunctions/scripts/serverless-remove.sh @@ -0,0 +1,25 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2017-2018 Apple Inc. and the SwiftAWSLambdaRuntime project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## + +DIR="$(cd "$(dirname "$0")" && pwd)" +source $DIR/config.sh + +echo -e "\nremoving $executable" + +echo "-------------------------------------------------------------------------" +echo "removing using Serverless" +echo "-------------------------------------------------------------------------" + +serverless remove --config "./scripts/serverless/${executable}-template.yml" --stage dev -v \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/serverless/APIGateway-template.yml b/Examples/LambdaFunctions/scripts/serverless/APIGateway-template.yml new file mode 100644 index 00000000..6787ad0f --- /dev/null +++ b/Examples/LambdaFunctions/scripts/serverless/APIGateway-template.yml @@ -0,0 +1,28 @@ +service: apigateway-swift-aws + +package: + artifact: .build/lambda/APIGateway/lambda.zip + +provider: + name: aws + httpApi: + payload: '2.0' + runtime: provided + logs: + httpApi: true + iamRoleStatements: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + +functions: + httpGet: + handler: APIGateway + memorySize: 128 + events: + - httpApi: + method: GET + path: /api \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/serverless/Benchmark-template.yml b/Examples/LambdaFunctions/scripts/serverless/Benchmark-template.yml new file mode 100644 index 00000000..74099441 --- /dev/null +++ b/Examples/LambdaFunctions/scripts/serverless/Benchmark-template.yml @@ -0,0 +1,20 @@ +service: benchmark-swift-aws + +package: + artifact: .build/lambda/Benchmark/lambda.zip + +provider: + name: aws + runtime: provided + iamRoleStatements: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + +functions: + benchmarkFunction: + handler: Benchmark + memorySize: 128 \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/serverless/CurrencyExchange-template.yml b/Examples/LambdaFunctions/scripts/serverless/CurrencyExchange-template.yml new file mode 100644 index 00000000..7e5c6b09 --- /dev/null +++ b/Examples/LambdaFunctions/scripts/serverless/CurrencyExchange-template.yml @@ -0,0 +1,20 @@ +service: currency-swift-aws + +package: + artifact: .build/lambda/CurrencyExchange/lambda.zip + +provider: + name: aws + runtime: provided + iamRoleStatements: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + +functions: + currencyExchangeFunction: + handler: CurrencyExchange + memorySize: 128 \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/serverless/ErrorHandling-template.yml b/Examples/LambdaFunctions/scripts/serverless/ErrorHandling-template.yml new file mode 100644 index 00000000..367be490 --- /dev/null +++ b/Examples/LambdaFunctions/scripts/serverless/ErrorHandling-template.yml @@ -0,0 +1,20 @@ +service: errorhandling-swift-aws + +package: + artifact: .build/lambda/ErrorHandling/lambda.zip + +provider: + name: aws + runtime: provided + iamRoleStatements: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + +functions: + errorHandlingFunction: + handler: ErrorHandling + memorySize: 128 \ No newline at end of file diff --git a/Examples/LambdaFunctions/scripts/serverless/HelloWorld-template.yml b/Examples/LambdaFunctions/scripts/serverless/HelloWorld-template.yml new file mode 100644 index 00000000..276f9909 --- /dev/null +++ b/Examples/LambdaFunctions/scripts/serverless/HelloWorld-template.yml @@ -0,0 +1,20 @@ +service: helloworld-swift-aws + +package: + artifact: .build/lambda/HelloWorld/lambda.zip + +provider: + name: aws + runtime: provided + iamRoleStatements: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + +functions: + hello: + handler: HelloWorld + memorySize: 128 \ No newline at end of file