Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 6e8c430

Browse files
Merge pull request #12 from CodingNagger/feature/s3-deployment
S3 Deployment added for Layers and Lambdas
2 parents 7554075 + 2fbecea commit 6e8c430

File tree

3 files changed

+91
-23
lines changed

3 files changed

+91
-23
lines changed

LambdaDeployerPolicyExample.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@
4949
"arn:aws:lambda:*:*:function:*",
5050
"arn:aws:lambda:*:*:layer:*"
5151
]
52+
},
53+
{
54+
"Sid": "VisualEditor4",
55+
"Effect": "Allow",
56+
"Action": "s3:*",
57+
"Resource": "arn:aws:s3:::aws-lambda-swift-sprinter*"
5258
}
5359
]
5460
}

Makefile

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,20 @@ LAMBDA_HANDLER?=$(SWIFT_EXECUTABLE).helloWorld
3030
# LAMBDA_FUNCTION_NAME=S3Test
3131
# LAMBDA_HANDLER=$(SWIFT_EXECUTABLE).getObject
3232

33+
# AWS Configuration
34+
IAM_ROLE_NAME?=lambda_sprinter_basic_execution
35+
AWS_PROFILE?=default
36+
AWS_BUCKET?=aws-lambda-swift-sprinter
37+
3338
# Internals
3439
LAMBDA_ZIP=lambda.zip
3540
SHARED_LIBS_FOLDER=swift-shared-libs
3641
LAYER_ZIP=swift-lambda-runtime-$(LAYER_VERSION).zip
37-
LAMBDA_BUILD_PATH=.build
38-
IAM_ROLE_NAME=lambda_sprinter_basic_execution
42+
ROOT_BUILD_PATH=./.build
43+
LAYER_BUILD_PATH=$(ROOT_BUILD_PATH)/layer
44+
LAMBDA_BUILD_PATH=$(ROOT_BUILD_PATH)/lambda
45+
TMP_BUILD_PATH=$(ROOT_BUILD_PATH)/tmp
46+
DATETIME=$(shell date +'%y%m%d-%H%M%S')
3947

4048
# use this for local development
4149
MOUNT_ROOT=$(shell pwd)/..
@@ -45,10 +53,6 @@ DOCKER_PROJECT_PATH=aws-lambda-swift-sprinter/$(SWIFT_PROJECT_PATH)
4553
# MOUNT_ROOT=$(shell pwd)
4654
# DOCKER_PROJECT_PATH=$(SWIFT_PROJECT_PATH)
4755

48-
# AWS Configuration
49-
AWS_PROFILE?=default
50-
AWS_BUCKET?=my-s3-bucket
51-
5256
swift_test:
5357
docker run \
5458
--rm \
@@ -110,13 +114,18 @@ test_package:
110114
swift test
111115

112116
create_build_directory:
113-
if [ ! -d "$(LAMBDA_BUILD_PATH)" ]; then mkdir $(LAMBDA_BUILD_PATH); fi
117+
if [ ! -d "$(LAMBDA_BUILD_PATH)" ]; then mkdir -p $(LAMBDA_BUILD_PATH); fi
118+
if [ ! -d "$(LAYER_BUILD_PATH)" ]; then mkdir -p $(LAYER_BUILD_PATH); fi
119+
if [ ! -d "$(TMP_BUILD_PATH)" ]; then mkdir -p $(TMP_BUILD_PATH); fi
114120

115121
package_lambda: clean_lambda create_build_directory build_lambda
116122
zip -r -j $(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) $(SWIFT_PROJECT_PATH)/.build/$(SWIFT_CONFIGURATION)/$(SWIFT_EXECUTABLE)
117123

124+
clean_all: clean_layer clean_lambda
125+
rm -r $(ROOT_BUILD_PATH)
126+
118127
clean_layer:
119-
rm $(LAMBDA_BUILD_PATH)/$(LAYER_ZIP) || true
128+
rm $(LAYER_BUILD_PATH)/$(LAYER_ZIP) || true
120129
rm -r $(SHARED_LIBS_FOLDER) || true
121130

122131
package_layer: create_build_directory clean_layer
@@ -134,34 +143,56 @@ package_layer: create_build_directory clean_layer
134143
--workdir "/src" \
135144
$(SWIFT_DOCKER_IMAGE) \
136145
cp -t $(SHARED_LIBS_FOLDER)/lib $(SHARED_LIBRARIES)
137-
zip -r $(LAMBDA_BUILD_PATH)/$(LAYER_ZIP) bootstrap $(SHARED_LIBS_FOLDER)
146+
zip -r $(LAYER_BUILD_PATH)/$(LAYER_ZIP) bootstrap $(SHARED_LIBS_FOLDER)
147+
148+
upload_build_to_s3: create_lambda_s3_key
149+
aws s3 sync --acl public-read "$(LAMBDA_BUILD_PATH)" s3://$(AWS_BUCKET)/$(LAMBDA_S3_UPLOAD_PATH) --profile $(AWS_PROFILE)
138150

139-
upload_build_to_s3:
140-
aws s3 sync --acl public-read ./.build s3://$(AWS_BUCKET)/ --profile $(AWS_PROFILE)
151+
create_layer_s3_key:
152+
$(eval LAYER_S3_UPLOAD_PATH := layers/$(SWIFT_LAMBDA_LIBRARY))
153+
154+
upload_lambda_layer_with_s3: create_layer_s3_key
155+
aws s3 sync --acl public-read "$(LAYER_BUILD_PATH)" s3://$(AWS_BUCKET)/$(LAYER_S3_UPLOAD_PATH) --profile $(AWS_PROFILE)
156+
aws lambda publish-layer-version --layer-name $(SWIFT_LAMBDA_LIBRARY) --description "AWS Custom Runtime Swift Shared Libraries with NIO" --content "S3Bucket=$(AWS_BUCKET),S3Key=$(LAYER_S3_UPLOAD_PATH)/$(LAYER_ZIP)" --output text --query LayerVersionArn --profile $(AWS_PROFILE) > $(TMP_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt
157+
cat $(TMP_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt
141158

142159
upload_lambda_layer:
143-
aws lambda publish-layer-version --layer-name $(SWIFT_LAMBDA_LIBRARY) --description "AWS Custom Runtime Swift Shared Libraries with NIO" --zip-file fileb://$(LAMBDA_BUILD_PATH)/$(LAYER_ZIP) --output text --query LayerVersionArn --profile $(AWS_PROFILE) > $(LAMBDA_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt
144-
cat $(LAMBDA_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt
160+
aws lambda publish-layer-version --layer-name $(SWIFT_LAMBDA_LIBRARY) --description "AWS Custom Runtime Swift Shared Libraries with NIO" --zip-file fileb://$(LAYER_BUILD_PATH)/$(LAYER_ZIP) --output text --query LayerVersionArn --profile $(AWS_PROFILE) > $(TMP_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt
161+
cat $(TMP_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt
145162

146163
create_role:
147164
aws iam create-role --role-name $(IAM_ROLE_NAME) --description "Allows Lambda functions to call AWS services on your behalf." --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["sts:AssumeRole"],"Principal":{"Service":["lambda.amazonaws.com"]}}]}' --profile $(AWS_PROFILE) || true
148165
aws iam attach-role-policy --role-name $(IAM_ROLE_NAME) --policy-arn "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" --profile $(AWS_PROFILE) || true
149166
$(eval IAM_ROLE_ARN := $(shell aws iam list-roles --query "Roles[? RoleName == '$(IAM_ROLE_NAME)'].Arn" --output text --profile $(AWS_PROFILE)))
150167

151168
create_lambda: create_role package_lambda
152-
$(eval LAMBDA_LAYER_ARN := $(shell cat $(LAMBDA_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt))
169+
$(eval LAMBDA_LAYER_ARN := $(shell cat $(TMP_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt))
170+
$(info "$(LAMBDA_LAYER_ARN)")
171+
aws lambda create-function --function-name $(LAMBDA_FUNCTION_NAME) --runtime provided --handler $(LAMBDA_HANDLER) --role "$(IAM_ROLE_ARN)" --zip-file fileb://$(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) --layers "$(LAMBDA_LAYER_ARN)" --profile $(AWS_PROFILE)
172+
173+
create_lambda_s3_key:
174+
$(eval LAMBDA_S3_UPLOAD_PATH := lambdas/$(LAMBDA_FUNCTION_NAME)/$(DATETIME))
175+
176+
create_lambda_with_s3: create_role package_lambda upload_build_to_s3
177+
$(eval LAMBDA_LAYER_ARN := $(shell cat $(TMP_BUILD_PATH)/$(SWIFT_LAMBDA_LIBRARY)-arn.txt))
153178
$(info "$(LAMBDA_LAYER_ARN)")
154-
aws lambda create-function --function-name $(LAMBDA_FUNCTION_NAME) --runtime provided --handler $(LAMBDA_HANDLER) --role "$(IAM_ROLE_ARN)" --zip-file fileb://$(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) --layers $(LAMBDA_LAYER_ARN) --profile $(AWS_PROFILE)
179+
aws lambda create-function --function-name $(LAMBDA_FUNCTION_NAME) --runtime provided --handler $(LAMBDA_HANDLER) --role "$(IAM_ROLE_ARN)" --code "S3Bucket=$(AWS_BUCKET),S3Key=$(LAMBDA_S3_UPLOAD_PATH)/$(LAMBDA_ZIP)" --layers "$(LAMBDA_LAYER_ARN)" --profile $(AWS_PROFILE)
155180

156181
update_lambda: package_lambda
157182
aws lambda update-function-code --function-name $(LAMBDA_FUNCTION_NAME) --zip-file fileb://$(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) --profile $(AWS_PROFILE)
158183

184+
update_lambda_with_s3: package_lambda upload_build_to_s3
185+
aws lambda update-function-code --function-name $(LAMBDA_FUNCTION_NAME) --s3-bucket $(AWS_BUCKET) --s3-key "$(LAMBDA_S3_UPLOAD_PATH)/$(LAMBDA_ZIP)" --profile $(AWS_PROFILE)
186+
159187
invoke_lambda:
160-
aws lambda invoke --function-name $(LAMBDA_FUNCTION_NAME) --profile $(AWS_PROFILE) --payload "fileb://$(SWIFT_PROJECT_PATH)/event.json" $(LAMBDA_BUILD_PATH)/outfile && echo "\nResult:" && cat $(LAMBDA_BUILD_PATH)/outfile && echo "\n"
188+
aws lambda invoke --function-name $(LAMBDA_FUNCTION_NAME) --profile $(AWS_PROFILE) --payload "fileb://$(SWIFT_PROJECT_PATH)/event.json" $(TMP_BUILD_PATH)/outfile && echo "\nResult:" && cat $(TMP_BUILD_PATH)/outfile && echo "\n"
189+
190+
create_s3_bucket:
191+
aws s3 mb "s3://$(AWS_BUCKET)" --profile $(AWS_PROFILE)
161192

162193
#quick commands - no clean
163194
quick_build_lambda: build_lambda create_build_directory
164195
zip -r -j $(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) $(SWIFT_PROJECT_PATH)/.build/$(SWIFT_CONFIGURATION)/$(SWIFT_EXECUTABLE)
165196

166197
quick_deploy_lambda: quick_build_lambda create_build_directory
167-
aws lambda update-function-code --function-name $(LAMBDA_FUNCTION_NAME) --zip-file fileb://$(LAMBDA_BUILD_PATH)/lambda.zip --profile $(AWS_PROFILE)
198+
aws lambda update-function-code --function-name $(LAMBDA_FUNCTION_NAME) --zip-file fileb://$(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) --profile $(AWS_PROFILE)

README.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ make invoke_lambda \
171171
| Key | Usage | Default |
172172
| --- | --- | --- |
173173
| AWS_PROFILE | An AWS AIM profile you create to authenticate to your account. | default |
174+
| IAM_ROLE_NAME | The execution role created that will be assumed by the Lambda. | lambda_sprinter_basic_execution |
175+
| AWS_BUCKET | The AWS S3 bucket where the layer and lambdas zip files get uploaded. | aws-lambda-swift-sprinter |
174176
| SWIFT_VERSION | Version of Swift used / Matches Dockerfile location too from `docker/` folder. | 5.1 |
175177
| LAYER_VERSION | Version of the Swift layer that will be created and uploaded for the Lambda to run on. | 5-1 |
176178
| SWIFT_EXECUTABLE | Name of the binary file. | HelloWorld |
@@ -215,6 +217,8 @@ There are many ways to achieve a lambda deployment (AWS Console, SAM, CloudForma
215217
- an AWS account for test purpose.
216218
- aws cli: Install the aws cli. Here the [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html).
217219

220+
- If you want to deploy your lambdas and layers using S3 you need to make sure the bucket in the Makefile already exists. If it doesn't you can create it using the command `make create_s3_bucket` which will use the value of the variable `AWS_BUCKET` as a name.
221+
218222
- if your AWS account it doesn't have admin priviledges:
219223
- Review(*) the policy contained in the file **LambdaDeployerPolicyExample.json**
220224
- Attach the policy to your user. [Here](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html) is the official documentation.
@@ -224,17 +228,36 @@ It would be better to restrict the policy to the function and layer you want to
224228
It's suggested to test the following scripts before using in production.
225229

226230
#### 1) Upload the Lambda layer
227-
Create a new lambda layer using the `swift-lambda-runtime.zip` file:
231+
Create a new lambda layer using the `swift-lambda-runtime.zip` file. This step is required once, however you are free to run it if you need to update your layer.
232+
233+
##### Upload the Lambda using S3
228234

229235
```console
230-
make upload_lambda_layer
236+
make upload_lambda_layer_with_s3
231237
```
232238

233-
This step is required once, or if you need to update the layer.
239+
Datetime based versions are created and uploaded to S3 every time your version is created.
240+
241+
##### Upload the Lambda directly
242+
243+
```console
244+
make upload_lambda_layer
245+
```
234246

235247
#### 2) Create the Lambda
236248

237-
Create a new lambda, this might take a few minutes:
249+
You can create a new lambda which might take a few minutes using one of the options below:
250+
251+
##### Create the Lambda using S3
252+
253+
```console
254+
make create_lambda_with_s3
255+
```
256+
257+
Datetime based versions are created and uploaded to S3 every time your version is created.
258+
259+
##### Create the Lambda directly
260+
238261
```console
239262
make create_lambda
240263
```
@@ -248,7 +271,7 @@ The lambda is created with the following parameters:
248271
- HelloWorld.helloWorld
249272
- role: `"$(IAM_ROLE_ARN)"`
250273
- a new role will be created with the name: `lambda_sprinter_basic_execution`
251-
- zip-file: $(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) --> `./build/lambda.zip`
274+
- zip-file: $(LAMBDA_BUILD_PATH)/$(LAMBDA_ZIP) --> `./build/lambda/lambda.zip`
252275
- layers: `$(LAMBDA_LAYER_ARN)`
253276
- it will use the arn contained in the file generated by the `make upload_lambda_layer`
254277

@@ -280,7 +303,15 @@ The lambda invocation may require some policy to access other AWS Resources. Che
280303

281304
#### 5) Update the Lambda (optional)
282305

283-
If it's required to update the lambda code, launch the following command:
306+
If needed, you will also be able to update your Lambda using one of the commands below:
307+
308+
##### Update the Lambda using S3
309+
310+
```console
311+
make update_lambda_with_s3
312+
```
313+
314+
##### Update the Lambda directly
284315

285316
```console
286317
make update_lambda

0 commit comments

Comments
 (0)