I’ve had to do this multiple times over the past two years. It’s always a shock to me how hard it is.
The Lambda@Edge functions especially. They have 4 phases they can be injected into: viewer-request, origin-request, origin-response, and viewer-response. If you put your code in the wrong place you get hard to debug issues. Additionally you cannot “annotate” a request, so a decision at say “viewer-request” cannot pass information to later stages.
Also, deployments take 15 minutes at least which just further frustrates the debugging process.