惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
T
ThreatConnect
SecWiki News
SecWiki News
F
Future of Privacy Forum
AWS News Blog
AWS News Blog
C
Cisco Blogs
A
Arctic Wolf
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Scott Helme
Scott Helme
V
V2EX
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
K
Kaspersky official blog
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News | PayPal Newsroom
Schneier on Security
Schneier on Security
NISL@THU
NISL@THU
Microsoft Azure Blog
Microsoft Azure Blog
量子位
The Hacker News
The Hacker News
Stack Overflow Blog
Stack Overflow Blog
Security Latest
Security Latest
M
Microsoft Research Blog - Microsoft Research
Google Online Security Blog
Google Online Security Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
InfoQ
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
The Cloudflare Blog
Microsoft Security Blog
Microsoft Security Blog
Martin Fowler
Martin Fowler
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Troy Hunt's Blog
F
Fox-IT International blog
S
Security @ Cisco Blogs
博客园 - 司徒正美
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Comments on: Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
L
LINUX DO - 最新话题
GbyAI
GbyAI
Project Zero
Project Zero
腾讯CDC
T
Tailwind CSS Blog

Lobsters

Human proof for FOSS contributions Extremely simple internet radio controlled via IRC Announcing BABLR Splitting Konsole views from Helix to run tools | AksDev GitHub - yugr/rust-slides Serving files over HTTP three ways: synchronous, epoll, and io_uring The User Is Visibly Frustrated uv must be installed to build a standalone Python distribution Encyclical Letter of His Holiness Leo XIV Magnifica Humanitas (15 May 2026) Using AI to write better code more slowly The Open/Closed Problem in AI A Simple Makefile Tutorial On C extensions, portability, and alternative compilers The social contract of writing Building a Host-Tuned GCC to Make GCC Compile Faster Switching to Colemak | Pedro Alves Fully in-browser container builds Nix's Substituter List Is Not a Routing Table What are you doing this week? Scoped Error in Rust Lambda on Lambda: Serverless Haskell on AWS | Blog Announcing feed-repeat v1.0 Scaling Akvorado BMP RIB with sharding EYG news: A host of CLI improvements, new guides and new effects The Eternal Sloptember JS Crossword C array types are weird; and related topics Flatpak will depend on systemd – OSnews Migrating from Go to Rust | corrode Rust Consulting Building Pi With Pi abyss * your_dotfiles_are_not_a_distro Vivado Licensing Options How my minimal, memory-safe Go rsync steers clear of vulnerabilities From AFSK to Goertzel the entropy layer of a wavelet codec, on its own 10,000 Lines Later: When a Tool Became a Compiler - Rob Durst - Gleam Gathering 2026 Debian SE Linux and PinTheft fht-compositor: A dynamic tiling Wayland compositor A Network Allow-List Won't Stop Exfiltration — André Graf Does bulk memmove speed up std::remove_if? (No.) What is Git made of? wake up! 16b 声明式部分更新 | Blog | Chrome for Developers Don't Roll Your Own ... Dianne Skoll's Web Site - Remind “Long-Term Support” doesn’t mean what you think The Architecture of Open Source Applications (Volume 1)Berkeley DB Pardon MIE? - ironPeak Blog seriot.ch It's time to talk about my writerdeck hershey Cuneiforth: A Forth for your Chifir z386: An Open-Source 80386 Built Around Original Microcode waylandcraft - Minecraft Mod On the <dl> HP QuickWeb, Singular And Pointless mvm - a fast virtual machine for Go That one time I used Go panics for flow control A new suite of modern tools coming for editing and publishing RFCs From the Tabletop… The Digital Antiquarian .NET (OK, C#) finally gets union types🎉: Exploring the .NET 11 preview - Part 2 Revised^7 Report on Scheme, Large: Procedural Fascicle Draft is now public The Soul of Maintaining a New Machine - Third Draft | Books in Progress
~jack/lambda-on-lambda - Serverless Haskell on AWS - sourcehut git
git.sr.ht by · 2026-05-26 · via Lobsters

This repository is an end-to-end demonstration of how to build OCI container images for deployment to AWS Lambda, as well as OpenTofu workspaces to provision the AWS resources. The container images can also run under Docker for local testing. It is designed to be a "concept sketch" of what real infrastructure might look like: more than a ClickOps guide that won't scale, but not a full end-to-end deployment where it's too hard to understand all the moving parts. The idea is that you will be able to map each part of this demonstration onto your IaC and CI/CD processes in a way that makes sense for your tools.

#Infrastructure overview

To deploy a Lambda Function to AWS using containers, Lambda needs to told to reference a container image existing in an ECR repository. The cleanest separation I've found for this is to have two distinct workspaces connected by an image build/push step:

  1. The first workspace provides the ECR repositories only, and exports information about them as outputs for the second workspace to find.
  2. The second workspace imports the repository information from the first, and uses variables to be told which image tags to deploy.

scripts/build-and-push-image is the image build/push step. It stands in for a CI/CD system by building the container images, pushing them to ECR, and updating a .tfvars.json file with the image tags.

#Recommendations for deploying Haskell to AWS Lambda

#Infrastructure

  • Use the two-workspace pattern above to split your infrastructure-as-code from your code's build->push->deploy lifecycle;
  • Avoid ECR Lifecycle Policies on your ECR Repositories, as they are not very expressive and risk deleting images that your Lambda Functions depend on. Regrettably, you will probably have to find a third-party tool to do this or implement garbage collection yourself.
  • Push images using tags like YYYYMMDD-HHMM-abcdef12(-dirty)that includes date/time information as well as git SHA, so you know when the image was built, as well as what code it was built from.
    • Make the non-dirty tags immutable so people don't overwrite them by accident and change behaviour of existing functions;
    • Optionally allow the dirty tags and keep them mutable, in case developers need to push from a dirty worktree in development; and
  • Always use container images (not .zip files), to avoid having to figure out static linking or troubleshoot linker issues in the Lambda environment.

#Function configuration and implementation

  • Allocate at least 512MB to your functions, to avoid GC issues;
  • For Lambda Functions that implement web services:
    • Write in your web framework of choice;
    • Let the Lambda Web Adapter handle the Lambda integration;
    • Integrate with an API Gateway HTTP API if you want scale-to-zero or have low traffic; and
    • Integrate with an Application Load Balancer if you have consistently high traffic and have calculated that the overall costs will be lower.
  • For "raw" Lambda functions, where you are exchanging JSON:

#Limitations of this demo

#The lambda functions are x86_64-linux only

To avoid a rabbit hole of Nix remote-building, cross-compiling, or other build-system wrangling (QEMU/binfmt_misc, etc.), the Haskell-based Lambda Functions are built for x86_64-linux only. aarch64-linux Lambda Functions are about 30% cheaper than x86_64-linux ones, so when you have enough scale for that to matter, it might be worth exploring how to do that.

#Everything uses AWS credentials from your environment

Your infrastructure-as-code workspaces should have their own permissions to manipulate AWS resources, while the build-and-push-image script (or your CI/CD system) should only be allowed to log into ECR and push images. The ECR User Guide has a page on IAM permissions for pushing an image to an Amazon ECR private repository.

#Lambda Functions are configured from image tags, not digests

The image_tags.auto.tfvars.json file only contains image tags, which are read by the 03-lambda-functions workspace. This makes it easy to answer "what is this Lambda Function configured to run?" as well as "what code revision was built, and when was it built?", but if you need to harden your container workflows (e.g. you are required to use signed images or audited supply chains) then you'll need to use digests instead.

#Versions, Aliases, and CodeDeploy are all completely absent

Lambda Versions allow you to snapshot function configurations on deploy. Aliases let you create a mutable named reference to one or two Versions (with traffic splitting), and avoids redeploying every integration when you release a new Version. AWS CodeDeploy allows controlled rollouts and rollbacks of Alias changes, by listening to pre- and post-traffic hooks and CloudWatch Alarms. A more mature deployment may want to use one or more of these features.

#Old images are never deleted

This means your storage costs will grow slowly but without bound (e.g., $0.10/GB-month in us-east-1). You should implement some kind of garbage collection process. I recommend implementing a scheduled task to do this, perhaps a Lambda Function triggered from EventBridge Scheduler.

The garbage-collection task might want to look for images that are not referenced by anything and were pushed more than 30 days ago.

  • Consider listing the images in a report for manual approval instead of deleting them, at least while ironing the bugs out of your GC process;
  • Be sure to check for image references reachable through references to function versions, as well as from aliases pointing to function versions and the code currently configured on the function itself (the $LATEST version);
  • Consider scoping the garbage-collector to only check repositories with a particular tag, so that a cleanup process for Lambda Functions doesn't wipe images from a repository used for AWS Elastic Container Service (ECS) or Elastic Kubernetes Service (EKS).

#How to use this repository

Although the code in this repo works, it's mostly intended to be read. I've commented everything heavily. Begin by reading workspaces 02-ecr-repositories and 03-lambda-functions, as well as scripts/build-and-push-image.

If you want to run it yourself, you will need Nix to build the container images and to enter the development shell:

$ nix develop
$ <...set up your AWS credentials, however you do that...>
$ tofu -chdir=workspaces/02-ecr-repositories apply
$ scripts/build-and-push-image server
$ tofu -chdir=workspaces/03-lambda-functions apply

#Cleaning up

Although these resources are not expensive, cleaning them up will prevent AWS from charging you:

$ nix develop
$ <...set up your AWS credentials, however you do that...>
$ tofu -chdir=workspaces/03-lambda-functions destroy
$ tofu -chdir=workspaces/02-ecr-repositories destroy

#Repository Layout

#nix: Nix helpers

Nix is used to prepare the container images, but your pipeline can use Docker or whatever else makes sense to you. Two supporting AWS utilities, the Runtime Interface Emulator and the Lambda Web Adapter, are packaged into a nixpkgs overlay so that we can include them in built images. make-lambda-container.nix packages a binary into a container while making it invokable locally (via the Lambda API) for testing. make-lambda-web-container.nix is similar, but packages a web server instead of a binary that speaks the Lambda APIs.

#server: Demo Haskell server

A simple Cabal package that defines a normal Haskell web server (using servant) and warp with two endpoints:

  • /hello will return a static "hello world" JSON blob; and
  • /crash will raise an exception. Useful for testing.

#simple: Simple AWS Lambda Function

Uses the hal (Haskell AWS Lambda) package to Implement a Lambda Function taking requests of the form {"n": "6"} to {"n_factorial": "720"}. To work on large numbers, they are parsed and returned as strings in the JSON.

#workspaces: OpenTofu workspaces

#01-your-first-lambda

A simple workspace that creates a JS-based Lambda Function, to show the major moving parts of declaring a Lambda Function in OpenTofu: its log group, the execution role, and the function itself.

#02-ecr-repositories

I believe that uploading container images to Amazon ECR is the best way to use Haskell as the implementation language for AWS Lambda Functions. This workspace declares the ECR Repositories that other workspaces in this repo rely upon.

Each repository will hold the images for a single Lambda Function, and images will be tagged with the date/time of push (in UTC) as well as a git short SHA (e.g. 20260520-0919-abcdef12(-dirty)).

Images in these repositories persist forever unless removed.

#03-lambda-functions

A workspace that declares Lambda Functions which use OCI images as their code source. If you are running this locally, you will need to use scripts/build-and-push-image to build and upload the container images and populate the workspaces/03-lambda-functions/image_tags.auto.tfvars.json file that tells OpenTofu exactly which images to deploy for each function.

#scripts: Build/deploy/testing scripts

#build-and-launch-image

Build an image and launch it using docker run. You can then test it locally and terminate it with Ctrl-C.

#build-and-push-image

This script stands in for the build-and-push steps of a CI/CD pipeline. It reads repository names from the workspaces/02-ecr-repositories OpenTofu state and passes the computed image tags down to the workspaces/03-lambda-functions state.

#invoke-haskell-lambda-simple-aws

Invoke the factorial-computing lambda once it has been deployed to AWS.

#invoke-haskell-lambda-simple-local

Use curl to invoke the factorial-computing lambda from a locally running container.