I was recently working on a project where we're pretty much lifting a Laravel application from EC2 into AWS Lambda. The project has been using Datadog with the PHP Extension for Datadog. The Datadog Agent is installed inside the EC2 instance and everything is working fine.
Although Datadog does not document this, I had a hunch that I could get this to work with AWS Lambda without making any crazy changes. The first thing that helped was the fact we had decided to run Docker on AWS Lambda. I know this is a last resort (I was the author of that Bref documentation), but we had good reasons to pursue this. The application takes about 600MB of disk space and AWS Lambda is limited to 250MB unzipped (50MB zipped). We also would need to install wkhtmltopdf, imagick, redis and gd, besides Datadog.
I ran into this issue on their GitHub repository which made me think perhaps this was not going to work, but as far as I understood, they were trying to use the Datadog Forwarder while I had something else in mind.
My thought process was:
- We're using Docker for Lambda so we pretty much have an Amazon Linux
- We need to figure out how to install the Datadog PHP Extension on Amazon Linux
- The Datadog Lambda Extension would probably be the Agent itself
- PHP running on Lambda would use the Extension to talk to the Lambda Extension
- The Extension uses TCP to talk to the Datadog Agent (localhost on lambda)
Datadog PHP Extension
So I went chasing this process. Following this part of the docs I managed to get Datadog PHP Extension installed on Docker with the following modifications:
RUN yum install -y tar gzip \
&& curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php \
&& ln -s /sbin/ldconfig /usr/local/bin/ldconfig \
&& php datadog-setup.php --php-bin=all \
&& rm -f datadog-setup.php
I ended up with this snippet because the Datadog extension installer was giving me some errors related to tar
and gzip
as well as ldconfig
not being found.
I then had to make sure I could place some ini
files for both cli
and fpm
. Bref already loads ini
files from your
project php/conf.d
directory, so I created 2 folders here:
php/conf.d/cli
php/conf.d/fpm
Then in my Dockerfile I have one stage for CLI and one for FPM:
RUN mv /var/task/php/conf.d/cli/* /var/task/php/conf.d/
RUN mv /var/task/php/conf.d/fpm/* /var/task/php/conf.d/
Datadog Lambda Extension
Next I found this documentation which explained how to install Datadog Lambda Extension for containers. This is the snippet I have for Bref and PHP Extensions:
FROM bref/php-74 as extensions
COPY /opt/bref-extra /opt/bref-extra
COPY /opt/bref-extra /opt/bref-extra
COPY /opt/bref /opt/bref/
COPY /opt/bref-extra /opt/bref-extra
COPY /opt/bref /opt/bref/
COPY /opt/bin/gs /opt/bin/gs
COPY /opt/extensions/ /opt/extensions
Note that the most important aspect for Datadog here is the last line where we copy the extension into our Docker image.
The last thing I needed was some environment variables to stitch this all together. I put the following environment variables on my Lambda in order to be able to figure out how things were working:
DD_API_KEY: !Sub '{{resolve:ssm:/${Environment}/app/services/datadog/key}}'
DD_SERVICE: app-lambda
DD_ENV: !Ref Environment
DD_VERSION: 1.0.0
DD_AGENT_HOSTNAME: 127.0.0.1
DD_TRACE_CLI_ENABLED: true
DD_TRACE_ENABLED: true
DD_TRACE_DEBUG: true
DD_SITE: datadoghq.com
DD_LOG_LEVEL: trace
The DD_LOG_LEVEL
and the DD_TRACE_DEBUG
are not necessary though. They make the logs a bit noisy. I just used
them when I was still debugging and figuring out how things were going. By default, the Datadog Agent will listen
on port 8126
and the Datadog PHP Extension will also talk to localhost:8126
.
Conclusion
This was quite interesting for me because I was stitching together multiple sources of Datadog documentation. Some were PHP-related docs and others were Serverless-related docs. I had this hunch that the Datadog Extension was actually the Agent and that the PHP Extension would communicate with the Agent via TCP which meant that there was nothing that would prevent me from having this running on AWS Lambda. I was super happy when everything was working correctly and one of the nice things is that the CloudWatch logs already get automatically forwarded to Datadog.
Hopefully the folks at Datadog can use this to write some dedicated documentation for it.
As always, hit me up on Twitter with any questions.
Cheers.