Various services use webhooks to deliver data to applications. Webhook data is usually sent to HTTP API endpoints.
To receive webhooks, each API endpoint must be registered in the service's configuration. When the same service instance is used for several test environments problems arise. The service may limit maximum number of webhook receivers. Moreover, it could be difficult to manually manage list of endpoints, especially when addresses change often.
The aim of this app is to simplify webhook delivery and management. It provides a single receiver of webhooks that forwards webhook events to all receivers discovered in the Kubernetes cluster. List of receivers is periodically refreshed, which makes the app suitable for use with temporary preview environments.
There are 2 versions of the deployment configuration:
- External (
k8s/versions/external-webhooks
) – handles external webhooks (sent from the Internet) - Internal (
k8s/versions/internal-webhooks-stripe-cli
) – uses cluster-internal source of webhooks, e.g. an app that generates webhooks. Version presented in the repository is built for Stripe CLI but after minor adjustments can be used with other similar services too.
Both versions assume that services that should receive webhooks are defined as services with common name, possibly in
different namespaces.
However, by introducing changes in soruce code, the app can be adjusted for use with other service
discovery methods.
- Choose one of the two versions:
external-webhooks
orinternal-webhooks-stripe-cli
- Clone this repository
- Copy
k8s/versions/<version>/webhook-forwarder-user-config.dist.yaml
tok8s/versions/<version>/webhook-forwarder-user-config.yaml
and fill fields marked withTODO
. See Configuration section for more details - Use
kustomize
to generate final config (kustomize build ./k8s/versions/<version>
) - Apply the configuration to your Kubernetes cluster
- Define any additional policies required by your cluster
Environmental variable name | Description | Example |
---|---|---|
LOG_LEVEL | Logging verbosity level | debug |
HEADERS_TO_FORWARD | Comma separated list of headers that should be forwarded | app-signature,content-type |
HEADERS_TO_ADD | Comma separated list of additional headers that should sent with the forwarded webhook | key:value,key2:value2 |
TARGET_NAME | Name of the destination service/ingress in K8s that should receive webhooks (see CLIENT_DISCOVERY_MODE to choose between service and ingress) |
backend-svc |
WEBHOOK_DESTINATION_ENDPOINT | Path of the endpoint that should receive webhooks | api/webhook |
IGNORE_DESTINATION_SSL_ERRORS | Ignore SSL errors when forwarding webhook to services | false |
CLIENT_DISCOVERY_MODE | Determines how clients are discovered. Available modes: SERVICE – discovers K8s services, INGRESS – discovers hosts in K8s ingresses, STATIC – uses client set in STATIC_CLIENT (useful for testing/debugging) |
SERVICE |
STATIC_CLIENT | Set address that should receive webhooks | http://localhost:4000 |
When using the INGRESS
discovery mode, you may encounter issues/limitations, e.g. SSL termination may not work while
accessing pods via a managed load balancer from inside the cluster. Check out the following links for further
explanations/solutions:
- Issue reported in K8s repo
- Another issue
- Workaround for Digital Ocean Kubernetes
- Other community solution
- App is designed to run on Docker
- It can be also started locally:
- First install dependencies
npm install
- Then build
npm run build
and startnode dist/app.js
- Or run in development mode
npm run dev
- First install dependencies
npm install
npm test
It's worth to mention some other methods that can also be sufficient in some situation:
- Nginx mirroring module: ngx_http_mirror_module module
- In case of services that provide tools for forwarding webhooks to local destinations: running instance of the tool as a sidecar container for each webhook receiver