1+ #! /bin/bash
2+ # #===----------------------------------------------------------------------===##
3+ # #
4+ # # This source file is part of the SwiftAWSLambdaRuntime open source project
5+ # #
6+ # # Copyright (c) 2017-2024 Apple Inc. and the SwiftAWSLambdaRuntime project authors
7+ # # Licensed under Apache License v2.0
8+ # #
9+ # # See LICENSE.txt for license information
10+ # # See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
11+ # #
12+ # # SPDX-License-Identifier: Apache-2.0
13+ # #
14+ # #===----------------------------------------------------------------------===##
15+
16+ # Stop the script execution if an error occurs
17+ set -e -o pipefail
18+
19+ check_prerequisites () {
20+ # check if docker is installed
21+ which docker > /dev/null || (echo " Docker is not installed. Please install Docker and try again." && exit 1)
22+
23+ # check if aws cli is installed
24+ which aws > /dev/null || (echo " AWS CLI is not installed. Please install AWS CLI and try again." && exit 1)
25+
26+ # check if user has an access key and secret access key
27+ echo " This script creates and deploys a Lambda function on your AWS Account.
28+
29+ You must have an AWS account and know an AWS access key, secret access key, and an optional session token.
30+ These values are read from '~/.aws/credentials'.
31+ "
32+
33+ read -r -p " Are you ready to create your first Lambda function in Swift? [y/n] " continue
34+ if [[ ! $continue =~ ^[Yy]$ ]]; then
35+ echo " OK, try again later when you feel ready"
36+ exit 1
37+ fi
38+ }
39+
40+ create_lambda_execution_role () {
41+ role_name=$1
42+
43+ # Allow the Lambda service to assume the IAM role
44+ cat << EOF > trust-policy.json
45+ {
46+ "Version": "2012-10-17",
47+ "Statement": [
48+ {
49+ "Effect": "Allow",
50+ "Principal": {
51+ "Service": "lambda.amazonaws.com"
52+ },
53+ "Action": "sts:AssumeRole"
54+ }
55+ ]
56+ }
57+ EOF
58+
59+ # Create the IAM role
60+ echo " 🔐 Create the IAM role for the Lambda function"
61+ aws iam create-role \
62+ --role-name " ${role_name} " \
63+ --assume-role-policy-document file://trust-policy.json > /dev/null 2>&1
64+
65+ # Attach basic permissions to the role
66+ # The AWSLambdaBasicExecutionRole policy grants permissions to write logs to CloudWatch Logs
67+ echo " 🔒 Attach basic permissions to the role"
68+ aws iam attach-role-policy \
69+ --role-name " ${role_name} " \
70+ --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole > /dev/null 2>&1
71+
72+ echo " ⏰ Waiting 10 secs for IAM role to propagate..."
73+ sleep 10
74+ }
75+
76+ create_swift_project () {
77+ echo " ⚡️ Create your Swift Lambda project"
78+ swift package init --type executable --name MyLambda > /dev/null
79+
80+ echo " 📦 Add the AWS Lambda Swift runtime to your project"
81+ # The following commands are commented out until the `lambad-init` plugin will be release
82+ # swift package add-dependency https://github.com/swift-server/swift-aws-lambda-runtime.git --branch main
83+ # swift package add-dependency https://github.com/swift-server/swift-aws-lambda-events.git --branch main
84+ # swift package add-target-dependency AWSLambdaRuntime MyLambda --package swift-aws-lambda-runtime
85+ # swift package add-target-dependency AWSLambdaEvents MyLambda --package swift-aws-lambda-events
86+ cat << EOF > Package.swift
87+ // swift-tools-version:6.0
88+
89+ import PackageDescription
90+
91+ let package = Package(
92+ name: "swift-aws-lambda-runtime-example",
93+ platforms: [.macOS(.v15)],
94+ products: [
95+ .executable(name: "MyLambda", targets: ["MyLambda"])
96+ ],
97+ dependencies: [
98+ .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main")
99+ ],
100+ targets: [
101+ .executableTarget(
102+ name: "MyLambda",
103+ dependencies: [
104+ .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime")
105+ ],
106+ path: "."
107+ )
108+ ]
109+ )
110+ EOF
111+
112+ echo " 📝 Write the Swift code"
113+ # The following command is commented out until the `lambad-init` plugin will be release
114+ # swift package lambda-init --allow-writing-to-package-directory
115+ cat << EOF > Sources/main.swift
116+ import AWSLambdaRuntime
117+
118+ let runtime = LambdaRuntime {
119+ (event: String, context: LambdaContext) in
120+ "Hello \(event)"
121+ }
122+
123+ try await runtime.run()
124+ EOF
125+
126+ echo " 📦 Compile and package the function for deployment (this might take a while)"
127+ swift package archive --allow-network-connections docker > /dev/null 2>&1
128+ }
129+
130+ deploy_lambda_function () {
131+ echo " 🚀 Deploy to AWS Lambda"
132+
133+ # retrieve your AWS Account ID
134+ echo " 🔑 Retrieve your AWS Account ID"
135+ AWS_ACCOUNT_ID=$( aws sts get-caller-identity --query Account --output text)
136+ export AWS_ACCOUNT_ID
137+
138+ # Check if the role already exists
139+ echo " 🔍 Check if a Lambda execution IAM role already exists"
140+ aws iam get-role --role-name lambda_basic_execution > /dev/null 2>&1 || create_lambda_execution_role lambda_basic_execution
141+
142+ # Create the Lambda function
143+ echo " 🚀 Create the Lambda function"
144+ aws lambda create-function \
145+ --function-name MyLambda \
146+ --zip-file fileb://.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/MyLambda/MyLambda.zip \
147+ --runtime provided.al2 \
148+ --handler provided \
149+ --architectures " $( uname -m) " \
150+ --role arn:aws:iam::" ${AWS_ACCOUNT_ID} " :role/lambda_basic_execution > /dev/null 2>&1
151+
152+ echo " ⏰ Waiting 10 secs for the Lambda function to be ready..."
153+ sleep 10
154+ }
155+
156+ invoke_lambda_function () {
157+ # Invoke the Lambda function
158+ echo " 🔗 Invoke the Lambda function"
159+ aws lambda invoke \
160+ --function-name MyLambda \
161+ --cli-binary-format raw-in-base64-out \
162+ --payload ' "Lambda Swift"' \
163+ output.txt > /dev/null 2>&1
164+
165+ echo " 👀 Your Lambda function returned:"
166+ cat output.txt && rm output.txt
167+ }
168+
169+ main () {
170+ #
171+ # Check prerequisites
172+ #
173+ check_prerequisites
174+
175+ #
176+ # Create the Swift project
177+ #
178+ create_swift_project
179+
180+ #
181+ # Now the function is ready to be deployed to AWS Lambda
182+ #
183+ deploy_lambda_function
184+
185+ #
186+ # Invoke the Lambda function
187+ #
188+ invoke_lambda_function
189+
190+ echo " "
191+ echo " 🎉 Done! Your first Lambda function in Swift is now deployed on AWS Lambda. 🚀"
192+ }
193+
194+ main " $@ "
0 commit comments