You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Plugins/AWSLambdaDeployer/README.md
+39-32Lines changed: 39 additions & 32 deletions
Original file line number
Diff line number
Diff line change
@@ -6,23 +6,23 @@ The existing `archive` plugin generates a ZIP to be deployed on AWS. While it re
6
6
7
7
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.
8
8
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.
10
10
11
11
It also allows for local testing, by providing a Local Lambda runtime environment and a local API Gateway mock in a docker container.
12
12
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.
14
14
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.
16
16
17
17
## Modifications:
18
18
19
19
I added two targets to `Package.swift` :
20
20
21
21
-`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.
22
22
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.
24
24
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.
26
26
27
27
## Result:
28
28
@@ -75,19 +75,21 @@ I add the new `Deploy.swift` file at the top of my project. Here is a simple dep
75
75
```swift
76
76
importAWSLambdaDeploymentDescriptor
77
77
78
-
let_=DeploymentDefinition(
79
-
80
-
functions: [
81
-
.function(
82
-
name: "HttpApiLambda",
83
-
architecture: .arm64, // optional, defaults to current build platform
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.
156
164
--stack-name <stack-name>
157
165
The name of the CloudFormation stack when deploying.
158
166
(default: the project name)
@@ -165,24 +173,23 @@ OPTIONS:
165
173
166
174
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 ...
167
175
168
-
#### Deploy.swift
176
+
#### Deploy.swift DSL
169
177
170
178
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.
171
179
172
180
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.
173
181
174
182
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.
175
183
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.
177
185
178
186
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.
179
187
180
188
**Alternatives Considered**
181
189
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.
184
191
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.
186
193
187
194
This approach removes the need to maintain feature parity between the SAM DSL and the `AWSLambdaDeploymentDescriptor` library.
0 commit comments