Following on my previous post #1 about creating a blog infrastructure with GitHub Issues, GitHub Actions, and AWS Services, I’m moving on writing a Lambda function in Swift, to consume the messages from the SQS queue.
Making a Swift Lambda function
My plan is to use this repo as the source for any code needed for publishing articles. For Lambda, I will use the following:
- Swift Lambda Runtime
- My own GitHub Graph API client to fetch the GitHub issue (might need to update it to run on Lambda, hopefully not)
Going to get started with the package and will update the post as I go.
Package Configuration
Package with targets and dependencies:
// swift-tools-version:5.2
import PackageDescription
let package = Package(
name: "Blog",
dependencies: [
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime", from: "0.3.0"),
.package(url: "https://github.com/eneko/GitHub", from: "0.1.0")
],
targets: [
.target(name: "IssueProcessorLambda", dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"),
.product(name: "AWSLambdaEvents", package: "swift-aws-lambda-runtime"),
])
]
)
Lambda Code
The following code will listen to an SQS event, and dump the received event to CloudWatch (after prepending “Hello world” to it):
import AWSLambdaRuntime
import AWSLambdaEvents
import NIO
struct Handler: EventLoopLambdaHandler {
typealias In = SQS.Event // One or more messages
typealias Out = String // Response type
func handle(context: Lambda.Context, event: In) -> EventLoopFuture<Out> {
let response = """
Hello world
\(event)
"""
context.logger.debug("\(response)")
return context.eventLoop.makeSucceededFuture(response)
}
}
Lambda.run(Handler())
This should be enough for now, to check the integration is working.
AWS SAM template
For deployment, I like using AWS SAM, since it handles creation of the infrastructure, code updates, IAM roles and trigger event configuration. All with a few configuration lines.
This SAM template has the definition for the Issue Processor lambda function, and the trigger event from the inbound SQS queue (see Triggering lambdas with SQS.
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM template
Resources:
IssueProcessorLambda:
Type: AWS::Serverless::Function
Properties:
Handler: Provided
Runtime: provided
CodeUri: .build/lambda/IssueProcessorLambda/lambda.zip
Environment:
Variables:
LOG_LEVEL: debug
Events:
SQSEvent:
Type: SQS
Properties:
Queue: arn:aws:sqs:us-west-2:<account_number>:blog-issue-updates
BatchSize: 10
Enabled: true
Dockerfile & Makefile
I’ve set up a couple of scripts, from the Swift Lambda Runtime examples, together with a Dockerfile
and a Makefile
to make it easy to build and package the Lambda binary on Amazon Linux 2. The files are located at the root of the Swift Package repo. The build and package scripts are in the Scripts
folder.
FROM swift:5.2-amazonlinux2
RUN yum -y install zip
build:
./scripts/build-and-package.sh IssueProcessorLambda
To build and package the lambda we just run make
(or make build
).
Deploying with SAM
The first time, we will do a guided deploy, to properly configure SAM for further deployments. We do this with:
$ sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]: blog-engine
AWS Region [us-east-1]: us-west-2
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]:
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]:
Save arguments to configuration file [Y/n]:
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
...
Reading logs from CloudWatch
If all goes well, we should see our Lambda function being invoked when issues are updated on GitHub, and logs with the events dumped on CloudWatch.
And here it is, the JSON with the Issue Number in the body property of the SQS Message:
On to the next step!
Next steps
- Configure GitHub action to push Issue updates to Amazon SQS (#1) ✅
- Configure an AWS Lambda to process the incoming messages (#2) ✅
- Retrieve entire issue details via GitHub Graph API, or embed in message (#3 & #4) ✅
- Automate creation of blog post on GitHub pages (via direct commit, or pull request) (#7 & #9) ✅
- Send me a notification via email or SMS with the url of the new blog post (using AWS SNS)
- Potentially store a mapping of GitHub issues to blog URLs (and file paths) on a DynamoDB table
This article was written as an issue on my Blog repository on GitHub (see Issue #2)