{"id":18188894,"url":"https://github.com/mlafeldt/launchdarkly-dynamo-store","last_synced_at":"2025-04-02T04:31:46.279Z","repository":{"id":57554375,"uuid":"131059785","full_name":"mlafeldt/launchdarkly-dynamo-store","owner":"mlafeldt","description":"DynamoDB Store for LaunchDarkly's Go SDK","archived":false,"fork":false,"pushed_at":"2020-09-09T07:31:12.000Z","size":706,"stargazers_count":11,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-16T10:23:58.558Z","etag":null,"topics":["dynamodb","feature-flags","feature-toggles","golang","launchdarkly","serverless"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlafeldt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-25T20:27:18.000Z","updated_at":"2022-08-17T07:19:06.000Z","dependencies_parsed_at":"2022-09-26T18:51:20.326Z","dependency_job_id":null,"html_url":"https://github.com/mlafeldt/launchdarkly-dynamo-store","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlafeldt%2Flaunchdarkly-dynamo-store","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlafeldt%2Flaunchdarkly-dynamo-store/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlafeldt%2Flaunchdarkly-dynamo-store/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlafeldt%2Flaunchdarkly-dynamo-store/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlafeldt","download_url":"https://codeload.github.com/mlafeldt/launchdarkly-dynamo-store/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246757462,"owners_count":20828901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamodb","feature-flags","feature-toggles","golang","launchdarkly","serverless"],"created_at":"2024-11-03T03:05:06.348Z","updated_at":"2025-04-02T04:31:41.271Z","avatar_url":"https://github.com/mlafeldt.png","language":"Go","funding_links":[],"categories":["Open Source"],"sub_categories":[],"readme":"# DynamoDB Store for LaunchDarkly's Go SDK\n\n[![CircleCI](https://circleci.com/gh/mlafeldt/launchdarkly-dynamo-store.svg?style=svg\u0026circle-token=5bd6fb4a2be7d94577cc359c6a74235aed4adc74)](https://circleci.com/gh/mlafeldt/launchdarkly-dynamo-store)\n[![GoDoc](https://godoc.org/github.com/mlafeldt/launchdarkly-dynamo-store/dynamodb?status.svg)](https://godoc.org/github.com/mlafeldt/launchdarkly-dynamo-store/dynamodb)\n\n**Note: LaunchDarkly has implemented [its own DynamoDB store](https://github.com/launchdarkly/go-server-sdk/tree/v4/lddynamodb) based on the one I started here.**\n\n---\n\nThis project provides the building blocks that, taken together, allow you to create a *serverless flag storage pipeline for LaunchDarkly* as described in [this presentation](https://speakerdeck.com/mlafeldt/implementing-feature-flags-in-serverless-environments).\n\nBy caching feature flag data in DynamoDB, LaunchDarkly clients don't need to call out to the LaunchDarkly API every time they're created. This is useful for environments like AWS Lambda where workloads can be sensitive to cold starts.\n\nTo that end, the following building blocks are provided:\n\n- [A DynamoDB-backed feature store](https://godoc.org/github.com/mlafeldt/launchdarkly-dynamo-store/dynamodb) for the [LaunchDarkly Go SDK](https://github.com/launchdarkly/go-client).\n- [A serverless service](serverless.yml) to persist feature flag data from LaunchDarkly in DynamoDB. See below for details.\n- [An example Lambda function](_examples/lambda) that reads feature flags from DynamoDB without querying the LaunchDarkly API.\n\n## Architecture\n\n![](pipeline.png)\n\n## The Serverless Service\n\nThe service is based on the [Serverless Framework](https://serverless.com/framework/). In addition to the `serverless` command-line tool, you can use the accompanied Makefile for convenience.\n\nHere's how to deploy and operate the service in AWS:\n\n```bash\n# Set AWS credentials and region\n$ export AWS_ACCESS_KEY_ID=...\n$ export AWS_SECRET_ACCESS_KEY=...\n$ export AWS_REGION=...\n\n# Write your LaunchDarkly SDK key to the AWS Parameter Store. The service uses\n# this key to talk to the LaunchDarkly API, but really any client might use it.\n$ aws ssm put-parameter --name /launchdarkly/staging/sdkkey --value $SDK_KEY --type SecureString --overwrite\n\n# Deploy a service that handles feature flags for the staging environment\n$ make deploy ENV=staging\n$ make staging  # shortcut\n\n# Invoke the service manually\n$ serverless invoke --function store --stage staging\n\n# Print the webhook URL (see \"LaunchDarkly Webhook Configuration\" below)\n$ make url ENV=staging\n\n# Show service logs\n$ make logs-store ENV=staging\n\n# Remove the service and its resources from AWS\n$ make destroy ENV=staging\n```\n\nTo set up a service for caching production flags, replace all occurrences of `staging` with `production`.\n\nAlso note that `staging` is the default environment, which means you may omit `ENV=staging`.\n\n## LaunchDarkly Webhook Configuration\n\nWe want LaunchDarkly to invoke our serverless service every time a feature flag (or segment) is modified. This ensures that the data cached in DynamoDB stays up-to-date.\n\nTo achieve this, we need to set up a webhook in LaunchDarkly (listed under *Integrations*). The webhook configuration is straightforward: paste the output of `make url` into the *URL* field and use  the following JSON document as the *Policy*:\n\n```json\n[\n  {\n    \"resources\": [\n      \"proj/*:env/staging:flag/*\"\n    ],\n    \"actions\": [\n      \"*\"\n    ],\n    \"effect\": \"allow\"\n  },\n  {\n    \"resources\": [\n      \"proj/*:env/staging:segment/*\"\n    ],\n    \"actions\": [\n      \"*\"\n    ],\n    \"effect\": \"allow\"\n  }\n]\n```\n\n(For production, replace `staging` accordingly.)\n\n## Optional: Webhook Signature Verification\n\nLaunchDarkly can also sign webhook payloads so you can verify that requests are generated by LaunchDarkly and not some rogue third party.\n\nTo enable webhook signature verification, configure a *Secret* in the LaunchDarkly UI. Then write that same secret to the Parameter Store and redeploy the serverless service for it to validate all future webhook requests:\n\n```bash\n$ aws ssm put-parameter --name /launchdarkly/staging/webhooksecret --value $SECRET --type SecureString --overwrite\n$ make staging\n```\n\n(For production, replace `staging` accordingly.)\n\n## Author\n\nThis project is being developed by [Mathias Lafeldt](https://twitter.com/mlafeldt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlafeldt%2Flaunchdarkly-dynamo-store","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlafeldt%2Flaunchdarkly-dynamo-store","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlafeldt%2Flaunchdarkly-dynamo-store/lists"}