Skip to content

Commit 44d6f77

Browse files
committed
update readme
1 parent 483a9be commit 44d6f77

File tree

1 file changed

+39
-32
lines changed

1 file changed

+39
-32
lines changed

Plugins/AWSLambdaDeployer/README.md

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,23 @@ The existing `archive` plugin generates a ZIP to be deployed on AWS. While it re
66

77
Furthermore, most developers will deploy a Lambda function together with some front end infrastructure allowing to invoke the Lambda function. Most common invocation methods are through an HTTP REST API (provided by API Gateway) or processing messages from queues (SQS). This means that, in addition of the deployment of the lambda function itself, the Lambda function developer must create, configure, and link to the Lambda function an API Gateway or a SQS queue.
88

9-
SAM is an open source command line tool that solves this problem. It allows developers to describe the function runtime environment and the additional resources that will trigger the lambda function in a simple YAML file. SAM CLI allows to validate the descriptor file and to deploy the infrastructure into the AWS cloud.
9+
SAM is an open source command line tool that allows Lambda function developers to easily express the function dependencies on other AWS services and deploy the function and its dependencies with an easy-to-use command lien tool. It allows developers to describe the function runtime environment and the additional resources that will trigger the lambda function in a simple YAML file. SAM CLI allows to validate the YAML file and to deploy the infrastructure into the AWS cloud.
1010

1111
It also allows for local testing, by providing a Local Lambda runtime environment and a local API Gateway mock in a docker container.
1212

13-
The `deploy` plugin leverages SAM to create an end-to-end infrastructure and to deploy it on AWS. It relies on configuration provided by the Swift lambda function developer to know how to expose the Lambda function to the external world. Right now, it support a subset of HTTP API Gateway v2 and SQS queues.
13+
The `deploy` plugin leverages SAM to create an end-to-end infrastructure and to deploy it on AWS. It relies on configuration provided by the Swift lambda function developer to know how to expose the Lambda function to the external world. Right now, it supports a subset of HTTP API Gateway v2 and SQS queues.
1414

15-
The Lambda function developer describes the API gateway or SQS queue using the Swift programming language by writing a `Deploy.swift` file (similar to `Package.swift` used by SPM). The plugin transform the `Deploy.swift` data structure into a SAM template. It then calls the SAM CLI to validate and to deploy the template.
15+
The Lambda function developer describes the API gateway or SQS queue using a Swift-based domain specific language (DSL) by writing a `Deploy.swift` file. The plugin transform the `Deploy.swift` data structure into a YAML SAM template. It then calls the SAM CLI to validate and to deploy the template.
1616

1717
## Modifications:
1818

1919
I added two targets to `Package.swift` :
2020

2121
- `AWSLambdaDeployer` is the plugin itself. I followed the same structure and code as the `archive` plugin. Common code between the two plugins has been isolated in a shared `PluginUtils.swift` file. Because of [a limitation in the current Swift package systems for plugins](https://forums.swift.org/t/difficulty-sharing-code-between-swift-package-manager-plugins/61690/11), I symlinked the file from one plugin directory to the other.
2222

23-
- `AWSLambdaDeploymentDescriptor` is a shared library that contains the data structures definition to describe and to generate a JSON SAM deployment file. It models SAM resources such as a Lambda functions and its event sources : HTTP API and SQS queue. It contains the logic to generate the SAM deployment descriptor, using minimum information provided by the Swift lambda function developer. At the moment it provides a very minimal subset of the supported SAM configuration. I am ready to invest more time to cover more resource types and more properties if this proposal is accepted.
23+
- `AWSLambdaDeploymentDescriptor` is a shared library that contains the data structures definition to describe and to generate a YAML SAM deployment file. It models SAM resources such as a Lambda functions and its event sources : HTTP API and SQS queue. It contains the logic to generate the SAM deployment descriptor, using minimum information provided by the Swift lambda function developer. At the moment it provides a very minimal subset of the supported SAM configuration. I am ready to invest more time to cover more resource types and more properties if this proposal is accepted.
2424

25-
I added a new Example project : `SAM`. It contains two Lambda functions, one invoked through HTTP API, and one invoked through SQS. It also defines shared resources such as SQS Queue and a DynamoDB Table. It provides a `Deploy.swift` example to describe the required HTTP API and SQS code and to allow `AWSLambdaDeploymentDescriptor` to generate the SAM deployment descriptor. The project also contains unit testing for the two Lambda functions.
25+
I also added a new example project : `SAM`. It contains two Lambda functions, one invoked through HTTP API, and one invoked through SQS. It also defines shared resources such as SQS Queue and a DynamoDB Table. It provides a `Deploy.swift` example to describe the required HTTP API and SQS code and to allow `AWSLambdaDeploymentDescriptor` to generate the SAM deployment descriptor. The project also contains unit testing for the two Lambda functions.
2626

2727
## Result:
2828

@@ -75,19 +75,21 @@ I add the new `Deploy.swift` file at the top of my project. Here is a simple dep
7575
```swift
7676
import AWSLambdaDeploymentDescriptor
7777

78-
let _ = DeploymentDefinition(
79-
80-
functions: [
81-
.function(
82-
name: "HttpApiLambda",
83-
architecture: .arm64, // optional, defaults to current build platform
84-
eventSources: [
85-
.httpApi(method: .GET, path: "/test"),
86-
],
87-
environment: .variable(["LOG_LEVEL":"debug"]) //optional
88-
)
89-
]
90-
)
78+
DeploymentDescriptor {
79+
// a mandatory description
80+
"Description of this deployment descriptor"
81+
82+
// the lambda function
83+
Function(name: "HttpApiLambda") {
84+
EventSources {
85+
HttpApi(method: .GET, path: "/test") // example of an API for a specific HTTP verb and path
86+
}
87+
// optional environment variables
88+
EnvironmentVariables {
89+
[ "NAME1": "VALUE1" ]
90+
}
91+
}
92+
}
9193
```
9294

9395
3. I add a dependency in my project's `Package.swift`. On a `testTarget`, I add this dependency:
@@ -124,7 +126,7 @@ Similarly to the archiver plugin, the deployer plugin must escape the sandbox be
124126
5. (optionally) Swift lambda function developer may also use SAM to test the code locally.
125127

126128
```bash
127-
sam local invoke -t sam.json -e Tests/LambdaTests/data/apiv2.json HttpApiLambda
129+
sam local invoke -t sam.yaml -e Tests/LambdaTests/data/apiv2.json HttpApiLambda
128130
```
129131

130132
## Command Line Options
@@ -133,26 +135,32 @@ The deployer plugin accepts multiple options on the command line.
133135

134136
```bash
135137
swift package plugin deploy --help
138+
136139
OVERVIEW: A swift plugin to deploy your Lambda function on your AWS account.
137140

138141
REQUIREMENTS: To use this plugin, you must have an AWS account and have `sam` installed.
139142
You can install sam with the following command:
140143
(brew tap aws/tap && brew install aws-sam-cli)
141144

142-
USAGE: swift package --disable-sandbox deploy [--help] [--verbose] [--nodeploy] [--configuration <configuration>] [--archive-path <archive_path>] [--stack-name <stack-name>]
145+
USAGE: swift package --disable-sandbox deploy [--help] [--verbose]
146+
[--archive-path <archive_path>]
147+
[--configuration <configuration>]
148+
[--force] [--nodeploy] [--nolist]
149+
[--stack-name <stack-name>]
143150

144151
OPTIONS:
145152
--verbose Produce verbose output for debugging.
146-
--nodeploy Generates the JSON deployment descriptor, but do not deploy.
147-
--nolist Do not call sam list to list endpoints
148-
--configuration <configuration>
149-
Build for a specific configuration.
150-
Must be aligned with what was used to build and package.
151-
Valid values : [ debug, release ] (default: debug)
152153
--archive-path <archive-path>
153154
The path where the archive plugin created the ZIP archive.
154-
Must be aligned with the value passed to archive --output-path.
155+
Must be aligned with the value passed to archive --output-path plugin.
155156
(default: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager)
157+
--configuration <configuration>
158+
Build for a specific configuration.
159+
Must be aligned with what was used to build and package.
160+
Valid values: [ debug, release ] (default: debug)
161+
--force Overwrites existing SAM deployment descriptor.
162+
--nodeploy Generates the YAML deployment descriptor, but do not deploy.
163+
--nolist Do not list endpoints.
156164
--stack-name <stack-name>
157165
The name of the CloudFormation stack when deploying.
158166
(default: the project name)
@@ -165,24 +173,23 @@ OPTIONS:
165173

166174
SAM is already broadly adopted, well maintained and documented. It does the job. I think it is easier to ask Swift Lambda function developers to install SAM (it is just two `brew` commands) rather than having this project investing in its own mechanism to describe a deployment and to generate the CloudFormation or CDK code to deploy the Lambda function and its dependencies. In the future, we might imagine a multi-framework solution where the plugin could generate code for SAM, or CDK, or Serverless etc ...
167175

168-
#### Deploy.swift
176+
#### Deploy.swift DSL
169177

170178
Swift Lambda function developers must be able to describe the additional infrastructure services required to deploy their functions: a SQS queue, an HTTP API etc.
171179

172180
I assume the typical Lambda function developer knows the Swift programming language, but not the AWS-specific DSL (such as SAM or CloudFormation) required to describe and deploy the project dependencies. I chose to ask the Lambda function developer to describe its deployment with a Swift struct in a top-level `Deploy.swift` file. The `deploy` plugin dynamically compiles this file to generate the SAM JSON deployment descriptor.
173181

174182
The source code to implement this approach is in the `AWSLambdaDeploymentDescriptor` library. This approach is similar to `Package.swift` used by the Swift Package Manager.
175183

176-
This is a strong design decision and [a one-way door](https://shit.management/one-way-and-two-way-door-decisions/). It engages the maintainer of the project on the long term to implement and maintain (close) feature parity between SAM DSL and the Swift `AWSLambdaDeploymentDescriptor` library.
184+
This is a strong design decision and [a one-way door](https://shit.management/one-way-and-two-way-door-decisions/). It engages the maintainer of the project on the long term to implement and maintain (close) feature parity between SAM DSL and the Swift `AWSLambdaDeploymentDescriptor` library and DSL.
177185

178186
One way to mitigate the maintenance work would be to generate the `AWSLambdaDeploymentDescriptor` library automatically, based on the [the SAM schema definition](https://github.com/aws/serverless-application-model/blob/develop/samtranslator/validator/sam_schema/schema.json). The core structs might be generated automatically and we would need to manually maintain only a couple of extensions providing syntactic sugar for Lambda function developers. This approach is similar to AWS SDKs code generation ([Soto](https://github.com/soto-project/soto-codegenerator) and the [AWS SDK for Swift](https://github.com/awslabs/aws-sdk-swift/tree/main/codegen)). This would require a significant one-time engineering effort however and I haven't had time to further explore this idea.
179187

180188
**Alternatives Considered**
181189

182-
One alternative proposed during early reviews is to use a DSL instead of a programmatic approach. A Swift-based DSL might be implemented using [Result Builders](https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md), available since Swift 5.4.
183-
After having read [tutorials](https://theswiftdev.com/result-builders-in-swift/) and watch a [WWDC 2021 session](https://developer.apple.com/videos/play/wwdc2021/10253/), I understand this might provide Swift Lambda function developer a strongly typed, Swift-friendly, DSL to express their SAM deployment descriptor. I will give a try to this approach and propose it in a PR.
190+
The first approach I used to implement `Deploy.swift` was pure programmatic. Developers would have to define a data structure in the initializer of the `DeploymentDescriptor` struct. This approach was similar to current `Package.swift`. After initial review and discussions, @tomerd suggested to use a DSL approach instead as it is simpler to read and write, it requires less punctuation marks, etc.
184191

185-
Another alternative is to not use a programmatic approach to describe the deployment at all (i.e. remove `Deploy.swift` and the `AWSLambdaDeploymentDescriptor` from this PR). In this scenario, the `deploy` plugin would generate a minimum SAM deployment template with default configuration for the current Lambda functions in the build target. The plugin would accept command-line arguments for basic pre-configuration of dependant AWS services, such as `--httpApi` or `--sqs <queue_name>` for example. The Swift Lambda function developer could leverage this SAM template to provide additional infrastructure or configuration elements as required. After having generated the initial SAM template, the `deploy` plugin will not overwrite the changes made by the developer.
192+
An alternative would be to not use a DSL approach to describe the deployment at all (i.e. remove `Deploy.swift` and the `AWSLambdaDeploymentDescriptor` from this PR). In this scenario, the `deploy` plugin would generate a minimum SAM deployment template with default configuration for the current Lambda functions in the build target. The plugin would accept command-line arguments for basic pre-configuration of dependant AWS services, such as `--httpApi` or `--sqs <queue_name>` for example. The Swift Lambda function developer could leverage this SAM template to provide additional infrastructure or configuration elements as required. After having generated the initial SAM template, the `deploy` plugin will not overwrite the changes made by the developer.
186193

187194
This approach removes the need to maintain feature parity between the SAM DSL and the `AWSLambdaDeploymentDescriptor` library.
188195

0 commit comments

Comments
 (0)