examples/basic is our living testbed: we will evolve it in each phase as modules land, rather than waiting until the end.
- Create directories:
modules/scheduled-lambda,modules/email-notification,modules/sms-notification,modules/lambda-image-republish,examples/basic. - Add shared Terraform version constraints/provider stubs (
versions.tf), ignore.terraform.lock.hcl, and add.gitignore. - Wire
tofu fmtvia pre-commit hook. - Add Pixi project file with toolchain (terraform/tofu, python for lambdas)
- Verify: run
terraform fmt -recursive/tofu fmtandterraform validateat repo root; ensure pre-commit passes; ensure CI bootstrap (if added) passes locally.
- Inputs:
source_lambda_repo,source_lambda_tag, optional destination repo name, KMS encryption flag. - Resources: destination ECR repo, permissions for pull/push, data source for source image digest, replication via
null_resource/local-execor pull-through cache rule. - Outputs: destination
lambda_image_urifor scheduled module. - Verify:
terraform planshows repo and replication steps; document manual check (aws ecr describe-imagesfor dest tag). - Example touchpoint: optionally show
examples/basicusing the local image output to feed the scheduled-lambda module (document how to toggle on/off).
- Inputs:
source_dir(Dockerfile directory), optionalrepository_name,image_tag(defaultlatest),build_args,platform(e.g.,linux/amd64), tags. - Resources: ECR repository (or use provided), lifecycle policy, data sources for account/region, and
null_resourcewithlocal-exectodocker buildx buildanddocker pushthe image. - Outputs:
image_uri, repository ARN/URL. - Verify:
terraform planshows repo + build/push steps; document prerequisites (docker login/credentials). - Example touchpoint: allow
examples/basicto build/push a simple placeholder Lambda image from a local Dockerfile as an alternative to the republish module.
- Define inputs:
lambda_image_uri,schedule_expression,sns_topic_arn(single), optionallambda_env,timeout,memory_size,tags. - Create resources: IAM role/policy (CloudWatch Logs +
sns:Publishto provided ARN), Lambda from container image, EventBridge rule/target/permission. - Outputs: Lambda ARN, execution role ARN, log group name, schedule rule name.
- Docs: README with usage matching IDEA example.
- Example touchpoint: scaffold
examples/basicwith this module + stub SNS topic(s) and the container image outputs from Phase 1;terraform validate/planshould pass to prove schedule wiring.
Overview: replace per-result-type topics with one shared SNS topic and use message attributes + subscription filter policies to route results to notification channels.
Success criteria:
- Scheduled lambdas publish to one topic and set a
result_typemessage attribute. - Notification modules accept
result_types(list) and apply SNS filter policies to their subscriptions. - Examples and docs reflect the single-topic pattern.
Decisions and motivations:
- Use SNS filter policies to reduce infrastructure and make multi-type subscriptions easy.
- Keep result types as message attributes to avoid changing payload shapes or handler code.
To-do:
- Update
modules/scheduled-lambdato acceptsns_topic_arn(single) and adjust IAM tosns:Publishon that ARN. - Update notification plumbing module to accept
result_typesand apply SNS filter policy on the subscription. - Update existing per-channel modules to pass through
result_typesand document the attribute name. - Update
src/lambdacron/helpers to publish with aresult_typeattribute and validate allowed types. - Update
examples/basicto use one topic and a singleresult_typessubscription. - Update module READMEs and
IDEA.mdusage examples to match the new wiring.
Overview: turn the existing Python helpers into a reusable, testable library that makes it easy for users to author scheduled lambdas while keeping SNS wiring and logging consistent. This package will also host shared notification handler code (under src/lambdacron/notifications/), while deployment/container wiring remains in Terraform modules.
Success criteria:
- A minimal, well-documented API for defining tasks and dispatching results to SNS.
- Clear guidance in
src/lambdacron/HOWTO-custom-lambda.mdthat matches the library behavior. - Unit tests covering the core dispatch and handler flow using mocked AWS clients.
Decisions and motivations:
- Keep code in
src/lambdacron/to stay close to Terraform modules and examples, while enabling importable Python helpers. - Prefer dependency injection for AWS clients to avoid real AWS calls and keep tests fast.
To-do:
- Refine the base task class to be typed, injectable (boto3 session/client), and structured-logging friendly.
- Add a small SNS dispatch helper that validates topic keys and emits clear errors on mismatches.
- Add
src/lambdacron/notifications/for shared handler logic (SES/Twilio/etc.) that can be imported by notification runtimes. - Update
src/lambdacron/HOWTO-custom-lambda.mdto show the current recommended pattern and env var expectations. - Add pytest cases with moto/mocks to cover SNS publish and mismatch errors.
- Document a minimal example task module that can be used in
examples/basicor in a client repo.
- Build one container per notification channel (email, SMS, print) using shared helpers from
src/lambdacron/notifications/; allow build or republish vialambda-image-buildorlambda-image-republish. - Add a minimal "print" notifier handler that renders the template and logs/prints it for easy testing.
- Terraform: reusable notification plumbing module (SNS FIFO topic -> SQS FIFO queue -> Lambda event source mapping) with SQS access policy output.
- Terraform: per-channel container build/publish; channel modules use the plumbing module and add channel-specific IAM and config.
- Inputs per module:
sns_topic_arn,fifo_queue_name/settings, handler selector/env vars; shared tags/log retention. - Verify:
terraform validate; exampleplan; container build succeeds locally; pytest skeleton runs. - Example touchpoint: extend
examples/basicto include the print notifier + FIFO SNS/SQS wiring to the sample SNS topic.
- Define handler contract: payload supplies template variables only; Lambda renders required subject/text/html templates; no per-message overrides; log delivery status.
- Python code: SES client wrapper; render subject/text/html templates locally with Jinja2; handle throttling/retries and DLQ-safe errors.
- Terraform: Lambda configuration/env for subject/text/html templates plus sender/recipients/config set; permissions for SES send + logs; wire to the SES-specific container image.
- Tests: pytest with sample SNS/SQS events; stub/moto SES; validate error handling and idempotency.
- Verify:
terraform validate; handler unit tests green; document smoke test (publish SNS message to topic -> email delivered/SES sandbox note). - Example touchpoint: wire the email module into
examples/basicwith sample SES template/resources and document the SNS publish -> email expectation.
- Define handler contract: expect message payload with body/recipients; support per-message override of to-numbers; log Twilio SID/error.
- Python code: Twilio REST client wrapper; read SID/auth token from SSM/Secrets; handle rate limits/retries; sanitize phone numbers; DLQ-safe errors.
- Terraform: Lambda configuration/env (from-number, default recipients, secret ARNs), IAM for Secrets Manager/SSM read + logs; wire to the Twilio-specific container image.
- Tests: pytest with mocked Twilio client; cover success/failure paths and secret fetch.
- Verify:
terraform validate; handler unit tests green; document smoke test (publish SNS message to topic -> SMS sent). - Example touchpoint: add the SMS module to
examples/basic(guard secrets/recipients via variables) and include a smoke path in the README.
Overview: make it easy for client teams to build and deploy their own scheduled lambdas by shipping a Python package, public container images for notification channels, and a single Terraform "stack" module that wires the pieces together.
Success criteria:
lambdacronis published to PyPI with documented install/use guidance.- Public ECR image(s) exist for default notification handlers (at least the print notifier), and are referenced in module docs/examples.
- A stack module exists that provisions the shared SNS topic and wires scheduled-lambda + one or more notification modules with minimal inputs.
Decisions and motivations:
- A stack module reduces boilerplate and makes first-time setup approachable.
- Public ECR images remove the need for clients to build their own notification containers.
- PyPI publishing lowers friction for authoring custom lambdas using the shared helpers.
To-do:
- Package
src/lambdacronfor PyPI (metadata, versioning, build/release docs). - Publish
lambdacronto PyPI and document install + usage expectations. - Provide public ECR image(s) for default notification handlers; document the URI(s) and versioning strategy.
- Add module in repo root to create SNS topic + scheduled-lambda with minimal configuration. This, plus notifications, can be reused by end users.
- Update
examples/basicto use the main module and public images where possible. - Verify:
terraform validate; exampleplan; PyPI install works; public ECR image pulls successfully.
- Consolidate prior touchpoints into a clean walkthrough (init, plan, apply, publish test message through SNS->SQS->Lambda handlers).
- Ensure defaults/variables make the example easy to run with minimal secrets, with notes for SES/Twilio sandboxing.
- Verify:
terraform fmt/validateandterraform planin example; capture expected outputs/log markers for manual SNS publish tests.
- Add
make testto run fmt, validate, lint, and Lambda unit tests. - Consider lightweight Terratest for scheduled-lambda wiring (guarded to skip apply by default).
- Add CI workflow (e.g., GitHub Actions) for formatting, validation, and unit tests on PRs.
- Verify: CI passes on clean tree; local
make testpasses.
- Top-level README: module overview, prerequisites (AWS creds, SES/Twilio setup), quickstart commands.
- Module READMEs: inputs/outputs tables and examples (generated or hand-written).
- Changelog/semver plan; tag first release after example
plan/smoke tests documented. - Verify: Docs reference real inputs/outputs; walkthrough commands executed once to ensure no typos.