---
title: Azure Container Apps
description: >-
  Instrument Azure Container Apps with Datadog to collect traces, logs, and
  custom metrics, using either in-container or sidecar serverless-init
  instrumentation.
breadcrumbs: Docs > Serverless > Azure Container Apps
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Azure Container Apps

## Overview{% #overview %}

Azure Container Apps is a fully managed serverless platform for deploying and scaling containerized applications. Datadog monitors Container Apps in two layers:

- The Azure Integration collects standard metrics and logs.
- The Datadog `serverless-init` Agent adds distributed tracing, enhanced metrics, custom metrics, and direct log collection. [Enhanced metrics](https://docs.datadoghq.com/integrations/azure-container-apps.md#metrics) are distinguished with the `azure.app_containerapps.enhanced.*` namespace.

First, set up the [Azure Integration](https://docs.datadoghq.com/integrations/azure.md) to collect metrics and logs.

Then, use the guides below to instrument your application using agentic onboarding or manual instrumentation.

## Set up with agentic onboarding{% #set-up-with-agentic-onboarding %}

Use [agentic onboarding](https://docs.datadoghq.com/agentic_onboarding/setup.md) to set up monitoring for your Azure Container Apps with AI assistance. Two complementary paths use the same Datadog account:

- **AI Setup CLI**: A standalone terminal tool. Use it when you don't want to install an MCP server.
- **MCP server**: Set up from your IDE through a coding assistant such as Claude Code or Cursor.

{% tab title="AI Setup CLI" %}
Run the CLI in your project directory (requires Node.js 22+). It links your Datadog account, then instruments your Azure Container Apps service:

```
npx @datadog/ai-setup-cli --product serverless --serverless-compute-type=azure-container-apps
```

Omit `--product` to run interactively, or add `--site` to target your Datadog site.
{% /tab %}

{% tab title="MCP server" %}
Use the Datadog MCP Server's [`serverless_onboarding`](https://docs.datadoghq.com/agentic_onboarding/setup.md?tab=serverlessmonitoring#mcp-server) tool. After you connect, try a prompt like:

```
Help me monitor my Azure Container Apps services with Datadog
```

{% /tab %}

## Manual instrumentation{% #manual-instrumentation %}

{% collapsible-section %}
##### In-Container vs. Sidecar

| Aspect            | In-Container                                             | Sidecar                                                                                                                                                                   |
| ----------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Deployment        | One container (your app, wrapped with the Datadog Agent) | Two containers (your app, Datadog Agent)                                                                                                                                  |
| Image changes     | Increases app image size.                                | No change to app image.                                                                                                                                                   |
| Cost overhead     | Less than sidecar (no extra container).                  | Extra vCPU/memory. Overallocating the sidecar wastes resources; underallocating leads to premature scaling.                                                               |
| Logging           | Direct stdout/stderr access.                             | Requires a shared volume and log library routing to a log file. Uncaught errors require extra handling, since they are not automatically handled by your logging library. |
| Failure isolation | In rare cases, Datadog Agent bugs can affect your app.   | Datadog Agent faults are isolated.                                                                                                                                        |
| Best for          | Simpler setup, lower cost, and direct log piping.        | Multiple containers per service, Agent isolation, and performance-sensitive workloads.                                                                                    |

{% /collapsible-section %}

{% section displayed-if="Instrumentation method is In-Container" %}
This section only applies to users who meet the following criteria: Instrumentation method is In-Container

{% section displayed-if="Runtime is Python" %}
This section only applies to users who meet the following criteria: Runtime is Python

### In-Container: Python{% #in-container-python %}
Install the Datadog Python SDK
Add `ddtrace` to your `requirements.txt` or `pyproject.toml`. You can find the latest version on [PyPI](https://pypi.org/project/ddtrace/):

In the `requirements.txt` file:

```
ddtrace==<VERSION>
```

Alternatively, you can install the SDK in your Dockerfile:

In the `Dockerfile` file:

```
RUN pip install ddtrace
```

Then, wrap your start command with `ddtrace-run`:

In the `Dockerfile` file:

```
CMD ["ddtrace-run", "python", "app.py"]
```

For more information, see [Tracing Python applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/python.md).
Install serverless-init
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

Add the following instructions and arguments to your Dockerfile.

In the `Dockerfile` file:

```
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["ddtrace-run", "python", "path/to/your/python/app.py"]
```

{% collapsible-section %}
#### Alternative configuration

Datadog expects `serverless-init` to be the top-level application, with the rest of your app's command line passed in for `serverless-init` to execute.

If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.

```
CMD ["/app/datadog-init", "ddtrace-run", "python", "path/to/your/python/app.py"]
```

If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.

```
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "ddtrace-run", "python", "path/to/your/python/app.py"]
```

As long as your command to run is passed as an argument to `datadog-init`, you receive full instrumentation.
{% /collapsible-section %}
Set up logs
To enable logging, set the environment variable `DD_LOGS_ENABLED=true`. This allows `serverless-init` to read logs from stdout and stderr.

Datadog also recommends the following environment variables:

- `ENV PYTHONUNBUFFERED=1`: Makes Python output appear immediately in container logs instead of being buffered.
- `ENV DD_LOGS_INJECTION=true`: Enable log/trace correlation for supported loggers.
- `ENV DD_SOURCE=python`: Enable advanced Datadog log parsing.

If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as `structlog`:

```
import structlog

def tracer_injection(logger, log_method, event_dict):
    event_dict.update(tracer.get_log_correlation_context())
    return event_dict

structlog.configure(
    processors=[
        tracer_injection,
        structlog.processors.EventRenamer("msg"),
        structlog.processors.JSONRenderer()
    ],
    logger_factory=structlog.WriteLoggerFactory(file=sys.stdout),
)

logger = structlog.get_logger()

logger.info("Hello world!")
```

For more information, see [Correlating Python Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/python.md).
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:

- `DD_API_KEY`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys), used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.
- `DD_SITE`: Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, <YOUR_DATADOG_SITE>.

For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=python#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=python#code-examples-5). In serverless, only the *distribution* metric type is supported.
Enable profiling (preview)
To enable the [Continuous Profiler](https://docs.datadoghq.com/profiler.md), set the environment variable `DD_PROFILING_ENABLED=true`.

{% alert level="info" %}
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
{% /alert %}
{% /section %}

{% section displayed-if="Runtime is Node.js" %}
This section only applies to users who meet the following criteria: Runtime is Node.js

### In-Container: Node.js{% #in-container-nodejs %}
Install the Datadog Node.js SDK
In your main application, install the `dd-trace` package.

```
npm install dd-trace
```

Initialize the Node.js tracer with the `NODE_OPTIONS` environment variable:

In the `Dockerfile` file:

```
ENV NODE_OPTIONS="--require dd-trace/init"
```

For more information, see [Tracing Node.js applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/nodejs.md).
Install serverless-init
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

Add the following instructions and arguments to your Dockerfile.

In the `Dockerfile` file:

```
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["/nodejs/bin/node", "/path/to/your/app.js"]
```

{% collapsible-section %}
#### Alternative configuration

Datadog expects `serverless-init` to be the top-level application, with the rest of your app's command line passed in for `serverless-init` to execute.

If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.

```
CMD ["/app/datadog-init", "/nodejs/bin/node", "/path/to/your/app.js"]
```

If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.

```
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "/nodejs/bin/node", "/path/to/your/app.js"]
```

As long as your command to run is passed as an argument to `datadog-init`, you receive full instrumentation.
{% /collapsible-section %}
Set up logs
To enable logging, set the environment variable `DD_LOGS_ENABLED=true`. This allows `serverless-init` to read logs from stdout and stderr.

Datadog also recommends setting the environment variables `DD_LOGS_INJECTION=true` and `DD_SOURCE=nodejs` to enable advanced Datadog log parsing.

If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as `winston`:

```
const { createLogger, format, transports } = require('winston');

const logger = createLogger({
  level: 'info',
  exitOnError: false,
  format: format.json(),
  transports: [
    new transports.Console()
  ],
});

logger.info('Hello world!');
```

For more information, see [Correlating Node.js Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/nodejs.md).
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:

- `DD_API_KEY`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys), used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.
- `DD_SITE`: Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, <YOUR_DATADOG_SITE>.

For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=nodejs#code-examples-5). In serverless, only the *distribution* metric type is supported.
Enable profiling (preview)
To enable the [Continuous Profiler](https://docs.datadoghq.com/profiler.md), set the environment variable `DD_PROFILING_ENABLED=true`.

{% alert level="info" %}
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
{% /alert %}
{% /section %}

{% section displayed-if="Runtime is Go" %}
This section only applies to users who meet the following criteria: Runtime is Go

### In-Container: Go{% #in-container-go %}
Install the Datadog Go SDK
In your main application, add the SDK from `dd-trace-go`.

```
go get github.com/DataDog/dd-trace-go/v2/ddtrace/tracer
```

Add the following to your application code to initialize the tracer:

```
tracer.Start()
defer tracer.Stop()
```

You can also add additional packages:

```
# Enable Profiling
go get github.com/DataDog/dd-trace-go/v2/profiler

# Patch /net/http
go get github.com/DataDog/dd-trace-go/contrib/net/http/v2
```

For more information, see [Tracing Go Applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/go.md) and the [Tracer README](https://github.com/DataDog/dd-trace-go?tab=readme-ov-file#installing).
Install serverless-init
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

Add the following instructions and arguments to your Dockerfile.

In the `Dockerfile` file:

```
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["./your-binary"]
```

{% collapsible-section %}
#### Alternative configuration

Datadog expects `serverless-init` to be the top-level application, with the rest of your app's command line passed in for `serverless-init` to execute.

If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.

```
CMD ["/app/datadog-init", "./your-binary"]
```

If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.

```
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "./your-binary"]
```

As long as your command to run is passed as an argument to `datadog-init`, you receive full instrumentation.
{% /collapsible-section %}
Set up logs
To enable logging, set the environment variable `DD_LOGS_ENABLED=true`. This allows `serverless-init` to read logs from stdout and stderr.

Datadog also recommends setting the environment variable `DD_SOURCE=go` to enable advanced Datadog log parsing.

If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as `logrus`:

```
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.AddHook(&dd_logrus.DDContextLogHook{})

logrus.WithContext(ctx).Info("Hello World!")
```

For more information, see [Correlating Go Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/go.md).
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:

- `DD_API_KEY`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys), used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.
- `DD_SITE`: Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, <YOUR_DATADOG_SITE>.

For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=go#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=go#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is Java" %}
This section only applies to users who meet the following criteria: Runtime is Java

### In-Container: Java{% #in-container-java %}
Install the Datadog Java SDK
Add the Datadog Java SDK to your Dockerfile:

In the `Dockerfile` file:

```
ADD 'https://dtdg.co/latest-java-tracer' agent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:agent.jar"
```

Add the SDK artifacts.

{% tab title="Maven" %}

```
<dependency>
  <groupId>com.datadoghq</groupId>
  <artifactId>dd-trace-api</artifactId>
  <version>DD_TRACE_JAVA_VERSION_HERE</version>
</dependency>
```

{% /tab %}

{% tab title="Gradle" %}

```
implementation 'com.datadoghq:dd-trace-api:DD_TRACE_JAVA_VERSION_HERE'
```

{% /tab %}

See [dd-trace-java releases](https://github.com/DataDog/dd-trace-java/releases) for the latest tracer version.

Add the `@Trace` annotation to any method you want to trace.

For more information, see [Tracing Java Applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/java.md).
Install serverless-init
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

Add the following instructions and arguments to your Dockerfile.

In the `Dockerfile` file:

```
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["./mvnw", "spring-boot:run"]
```

{% collapsible-section %}
#### Alternative configuration

Datadog expects `serverless-init` to be the top-level application, with the rest of your app's command line passed in for `serverless-init` to execute.

If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.

```
CMD ["/app/datadog-init", "./mvnw", "spring-boot:run"]
```

If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.

```
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "./mvnw", "spring-boot:run"]
```

As long as your command to run is passed as an argument to `datadog-init`, you receive full instrumentation.
{% /collapsible-section %}
Set up logs
To enable logging, set the environment variable `DD_LOGS_ENABLED=true`. This allows `serverless-init` to read logs from stdout and stderr.

Datadog also recommends setting the environment variables `DD_LOGS_INJECTION=true` and `DD_SOURCE=java` to enable advanced Datadog log parsing.

If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in *compact* JSON format. For example, you can use a third-party logging library such as `Log4j 2`:

```
private static final Logger logger = LogManager.getLogger(App.class);
logger.info("Hello World!");
```

In the `resources/log4j2.xml` file:

```
<Configuration>
  <Appenders>
    <Console name="Console"><JsonLayout compact="true" eventEol="true" properties="true"/></Console>
  </Appenders>
  <Loggers><Root level="info"><AppenderRef ref="Console"/></Root></Loggers>
</Configuration>
```

For more information, see [Correlating Java Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/java.md).
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:

- `DD_API_KEY`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys), used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.
- `DD_SITE`: Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, <YOUR_DATADOG_SITE>.

For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=java#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=java#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is .NET" %}
This section only applies to users who meet the following criteria: Runtime is .NET

### In-Container: .NET{% #in-container-net %}
Install the Datadog .NET SDK
Install the Datadog .NET SDK in your Dockerfile.

Because GitHub requests are rate limited, you must pass a GitHub token saved in the environment variable `GITHUB_TOKEN` as a [Docker build secret](https://docs.docker.com/build/building/secrets/) `--secret id=github-token,env=GITHUB_TOKEN`.

{% tab title="Standard Linux (glibc)" %}
In the `Dockerfile` file:

```
RUN --mount=type=secret,id=github-token,env=GITHUB_TOKEN \
    chmod +x /app/dotnet.sh && /app/dotnet.sh
```

{% /tab %}

{% tab title="Alpine (musl)" %}
In the `Dockerfile` file:

```
# For alpine use datadog-dotnet-apm-2.57.0-musl.tar.gz
ARG TRACER_VERSION
ADD https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm-${TRACER_VERSION}.tar.gz /tmp/datadog-dotnet-apm.tar.gz

RUN mkdir -p /dd_tracer/dotnet/ && tar -xzvf /tmp/datadog-dotnet-apm.tar.gz -C /dd_tracer/dotnet/ && rm /tmp/datadog-dotnet-apm.tar.gz
```

{% /tab %}

For more information, see [Tracing .NET applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/dotnet-core.md?tab=linux).
Install serverless-init
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

Add the following instructions and arguments to your Dockerfile.

In the `Dockerfile` file:

```
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["dotnet", "dotnet.dll"]
```

{% collapsible-section %}
#### Alternative configuration

Datadog expects `serverless-init` to be the top-level application, with the rest of your app's command line passed in for `serverless-init` to execute.

If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.

```
CMD ["/app/datadog-init", "dotnet", "dotnet.dll"]
```

If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.

```
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "dotnet", "dotnet.dll"]
```

As long as your command to run is passed as an argument to `datadog-init`, you receive full instrumentation.
{% /collapsible-section %}
Set up logs
To enable logging, set the environment variable `DD_LOGS_ENABLED=true`. This allows `serverless-init` to read logs from stdout and stderr.

Datadog also recommends setting the environment variables `DD_LOGS_INJECTION=true` and `DD_SOURCE=csharp` to enable advanced Datadog log parsing.

If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as `Serilog`:

```
using Serilog;

builder.Host.UseSerilog((context, config) =>
{
    config.WriteTo.Console(new Serilog.Formatting.Json.JsonFormatter(renderMessage: true));
});

logger.LogInformation("Hello World!");
```

For more information, see [Correlating .NET Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/dotnet.md).
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:

- `DD_API_KEY`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys), used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.
- `DD_SITE`: Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, <YOUR_DATADOG_SITE>.

For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=dotnet#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=dotnet#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is Ruby" %}
This section only applies to users who meet the following criteria: Runtime is Ruby

### In-Container: Ruby{% #in-container-ruby %}
Install the Datadog Ruby SDK
Add the `datadog` gem to your Gemfile:

In the `Gemfile` file:

```
source 'https://rubygems.org'
gem 'datadog'
```

See [Tracing Ruby applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/ruby.md#instrument-your-application) for additional information on how to configure the SDK and enable auto instrumentation.
Install serverless-init
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

Add the following instructions and arguments to your Dockerfile.

In the `Dockerfile` file:

```
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["rails", "server", "-b", "0.0.0.0"]
```

{% collapsible-section %}
#### Alternative configuration

Datadog expects `serverless-init` to be the top-level application, with the rest of your app's command line passed in for `serverless-init` to execute.

If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.

```
CMD ["/app/datadog-init", "rails", "server", "-b", "0.0.0.0"]
```

If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.

```
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "rails", "server", "-b", "0.0.0.0"]
```

As long as your command to run is passed as an argument to `datadog-init`, you receive full instrumentation.
{% /collapsible-section %}
Set up logs
To enable logging, set the environment variable `DD_LOGS_ENABLED=true`. This allows `serverless-init` to read logs from stdout and stderr.

Datadog also recommends setting the environment variable `DD_SOURCE=ruby` to enable advanced Datadog log parsing.

To enable log-trace correlation, you need to include `Datadog::Tracing.log_correlation` in your log format. For example:

```
logger = Logger.new(STDOUT)
logger.formatter = proc do |severity, datetime, progname, msg|
  "[#{datetime}] #{severity}: [#{Datadog::Tracing.log_correlation}] #{msg}\n"
end

logger.info "Hello world!"
```

For more information, see [Correlating Ruby Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/ruby.md).
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:

- `DD_API_KEY`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys), used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.
- `DD_SITE`: Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, <YOUR_DATADOG_SITE>.

For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=ruby#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=ruby#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is PHP" %}
This section only applies to users who meet the following criteria: Runtime is PHP

### In-Container: PHP{% #in-container-php %}
Install the Datadog PHP SDK
Install the Datadog PHP SDK in your Dockerfile.

In the `Dockerfile` file:

```
RUN curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php \
  && php datadog-setup.php --php-bin=all
```

When running the `datadog-setup.php` script, you can also enable Application Security and Profiling by using the `--enable-appsec` and `--enable-profiling` flags, respectively.

If you are using Alpine Linux, you need to install `libgcc_s` prior to running the installer:

```
apk add libgcc
```

For more information, see [Tracing PHP applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/php.md).
Install serverless-init
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

Add the following instructions and arguments to your Dockerfile.

In the `Dockerfile` file:

```
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["apache2-foreground"]
```

{% collapsible-section %}
#### Alternative configuration

Datadog expects `serverless-init` to be the top-level application, with the rest of your app's command line passed in for `serverless-init` to execute.

If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.

```
CMD ["/app/datadog-init", "apache2-foreground"]
```

If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.

```
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "apache2-foreground"]
```

As long as your command to run is passed as an argument to `datadog-init`, you receive full instrumentation.
{% /collapsible-section %}
Set up logs
To enable logging, set the environment variable `DD_LOGS_ENABLED=true`. This allows `serverless-init` to read logs from stdout and stderr.

Datadog also recommends setting the environment variables `DD_LOGS_INJECTION=true` and `DD_SOURCE=php` to enable advanced Datadog log parsing.

For more information, see [Correlating PHP Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/php.md).
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:

- `DD_API_KEY`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys), used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.
- `DD_SITE`: Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, <YOUR_DATADOG_SITE>.

For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=php#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=php#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}
{% /section %}

{% section displayed-if="Instrumentation method is Sidecar" %}
This section only applies to users who meet the following criteria: Instrumentation method is Sidecar

{% section displayed-if="Runtime is Python" %}
This section only applies to users who meet the following criteria: Runtime is Python

### Sidecar: Python{% #sidecar-python %}
Install the Datadog Python SDK
Add `ddtrace` to your `requirements.txt` or `pyproject.toml`. You can find the latest version on [PyPI](https://pypi.org/project/ddtrace/):

In the `requirements.txt` file:

```
ddtrace==<VERSION>
```

Alternatively, you can install the SDK in your Dockerfile:

In the `Dockerfile` file:

```
RUN pip install ddtrace
```

Then, wrap your start command with `ddtrace-run`:

In the `Dockerfile` file:

```
CMD ["ddtrace-run", "python", "app.py"]
```

For more information, see [Tracing Python applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/python.md).
Install serverless-init as a sidecar
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

{% tab title="Datadog CLI" %}
#### Locally{% #locally-2 %}

Install the Datadog CLI:

```
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

To set up the Datadog sidecar for your applications, configure the [Datadog site](https://docs.datadoghq.com/getting_started/site.md) and Datadog API key, and run the `instrument` command *after* your normal deployment:

```
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

You can also instrument multiple applications using the full resource IDs:

```
datadog-ci container-app instrument \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
```

##### Azure Cloud Shell{% #azure-cloud-shell-2 %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly.

```
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

Additional parameters can be found in the [CLI documentation](https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-container-app#arguments).
{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Container Apps](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) wraps the [`azurerm_container_app`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_app) resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_container_app_environment" "my_env" {
    name                = "my-container-app-env" // Replace with your container app environment name
    resource_group_name = "my-resource-group"    // Replace with your resource group name
    location            = "eastus"
}

module "my_container_app" {
  source  = "DataDog/container-app-datadog/azurerm"
  version = "~> 1.0"

  name                         = "my-container-app" // Replace with your container app name
  resource_group_name          = "my-resource-group" // Replace with your resource group name
  container_app_environment_id = azurerm_container_app_environment.my_env.id

  datadog_api_key = var.datadog_api_key
  datadog_site    = "datadoghq.com" // Replace with your Datadog site
  datadog_service = "my-service"    // Replace with your service name
  datadog_env     = "dev"           // Replace with your environment (e.g. prod, staging, dev)
  datadog_version = "0.1.0"         // Replace with your application version

  revision_mode         = "Single"
  workload_profile_name = "Consumption"
  ingress = {
    external_enabled = true
    target_port      = 8080
    traffic_weight = [{
      percentage      = 100
      latest_revision = true
    }]
  }
  template = {
    container = [{
      cpu    = 0.5
      memory = "1Gi"
      image  = "docker.io/your-docker-image:latest" // Replace with your Docker image
      name   = "main"
    }]
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Container App module](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) only deploys the Container App resource, so you need to build and push your container separately.

See the Environment variables section for more information on the configuration options available through the `env`.

Make sure the container port for the main container matches the one exposed in your Dockerfile/service.

If you haven't already, initialize your Terraform project:

```
terraform init
```

To deploy your app, run:

```
terraform apply
```

{% /tab %}

{% tab title="Bicep" %}
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:

```
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'

resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  // ...
  properties: {
    template: {
      volumes: [
        {
          name: 'shared-volume'
          storageType: 'EmptyDir'
        }
        // Additional volumes
      ]
      containers: [
        {
          name: 'main'
          image: 'index.docker.io/your/image:tag' // Replace with your Application Image
          resources: {
            cpu: 1
            memory: '2Gi'
          }
          env: [
            { name: 'DD_ENV', value: env }
            { name: 'DD_SERVICE', value: name }
            { name: 'DD_VERSION', value: version }
            { name: 'DD_LOGS_INJECTION', value: 'true' }
            // Additional tracing/application env vars
          ]
          volumeMounts: [
            { volumeName: 'shared-volume', mountPath: '/shared-volume' }
            // Additional volume mounts
          ]
        }
        {
          name: 'datadog-sidecar'
          image: 'index.docker.io/datadog/serverless-init:latest'
          resources: {
            cpu: '0.5'
            memory: '1Gi'
          }
          env: [
            { name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
            { name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
            { name: 'DD_API_KEY', value: datadogApiKey }
            { name: 'DD_SITE', value: datadogSite }
            { name: 'DD_SERVICE', value: service }
            { name: 'DD_ENV', value: env }
            { name: 'DD_VERSION', value: version }
            // set this to wherever you write logs in the shared volume:
            { name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
          ]
          volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
        }
      ]
      scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
    }
  }
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "datadogApiKey": {
      "type": "securestring"
    },
    "datadogSite": {
      "type": "string"
    },
    "service": {
      "type": "string",
      "defaultValue": "my-service"
    },
    "env": {
      "type": "string",
      "defaultValue": "dev"
    },
    "version": {
      "type": "string",
      "defaultValue": "0.0.0"
    }
  },
  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2024-03-01",
      // ...
      "properties": {
        "template": {
          "volumes": [
            {
              "name": "shared-volume",
              "storageType": "EmptyDir"
            }
            // Additional volumes
          ],
          "containers": [
            {
              "name": "main",
              "image": "index.docker.io/your/image:tag", // Replace with your Application Image
              "resources": {
                "cpu": 1,
                "memory": "2Gi"
              },
              "env": [
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                // Additional tracing/application env vars
                {
                  "name": "DD_LOGS_INJECTION",
                  "value": "true"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
                // Additional volume mounts
              ]
            },
            {
              "name": "datadog-sidecar",
              "image": "index.docker.io/datadog/serverless-init:latest",
              "resources": {
                "cpu": "0.5",
                "memory": "1Gi"
              },
              "env": [
                {
                  "name": "DD_AZURE_SUBSCRIPTION_ID",
                  "value": "[subscription().subscriptionId]"
                },
                {
                  "name": "DD_AZURE_RESOURCE_GROUP",
                  "value": "[resourceGroup().name]"
                },
                {
                  "name": "DD_API_KEY",
                  "value": "[parameters('datadogApiKey')]"
                },
                {
                  "name": "DD_SITE",
                  "value": "[parameters('datadogSite')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                {
                  "name": "DD_SERVERLESS_LOG_PATH",
                  // set this to wherever you write logs in the shared volume:
                  "value": "/shared-volume/logs/app.log"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 1,
            "rules": []
          }
        }
      }
    }
  ]
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}
#### Application environment variables{% #application-environment-variables-2 %}

Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.

| Name         | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `DD_SERVICE` | How you want to tag your service. For example, `sidecar-azure`. |
| `DD_ENV`     | How you want to tag your env. For example, `prod`.              |
| `DD_VERSION` | How you want to tag your application version.                   |

#### Sidecar container{% #sidecar-container-2 %}

1. In the Azure Portal, navigate to **Application** > **Revisions and replicas**. Select **Create new revision**.
1. On the **Container** tab, under **Container image**, select **Add**. Choose **App container**.
1. In the **Add a container** form, provide the following:
   - **Name**: `datadog`
   - **Image source**: Docker Hub or other registries
   - **Image type**: `Public`
   - **Registry login server**: `docker.io`
   - **Image and tag**: `datadog/serverless-init:<YOUR_TAG>`
   - Define your container resource allocation based on your usage.
1. Add a volume mount using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
1. Set the environment variables in the following table:

##### Sidecar environment variables{% #sidecar-environment-variables-2 %}

| Name                       | Description                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_AZURE_SUBSCRIPTION_ID` | **Required**. Your Azure subscription ID.                                                                                                                                |
| `DD_AZURE_RESOURCE_GROUP`  | **Required**. Your Azure resource group.                                                                                                                                 |
| `DD_API_KEY`               | **Required**. Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).                                                                          |
| `DD_SITE`                  | Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, `datadoghq.com`.                                                                   |
| `DD_SERVICE`               | How you want to tag your service. For example, `sidecar-azure`.                                                                                                          |
| `DD_ENV`                   | How you want to tag your env. For example, `prod`.                                                                                                                       |
| `DD_VERSION`               | How you want to tag your application version.                                                                                                                            |
| `DD_SERVERLESS_LOG_PATH`   | If using the agent for log collection, where you write your logs. For example, `/LogFiles/*.log`. This must match the logging path set up in your application container. |

#### Logging{% #logging-2 %}

If using the Datadog Agent for log collection, add a volume mount to the sidecar container *and* your application containers using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type **Ephemeral storage** when creating your volume. The examples on this page use the volume name `logs` and the mount path `/LogFiles`.

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format"
   alt="Adding a volume mount to a container in Azure" /%}

{% /tab %}
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in `DD_SERVERLESS_LOG_PATH`. You can also set a custom format for log/trace correlation and other features. Datadog recommends setting the following environment variables:

- `ENV PYTHONUNBUFFERED=1`: In your main container. Makes Python output appear immediately in container logs instead of being buffered.
- `ENV DD_LOGS_INJECTION=true`: In your main container. Enable log/trace correlation for supported loggers.
- `DD_SOURCE=python`: In your sidecar container. Enable advanced Datadog log parsing.

Then, update your logging library. For example, you can use Python's native `logging` library:

```
LOG_FILE = "/LogFiles/app.log"
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)

FORMAT = ('%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] '
        '[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] '
        '- %(message)s')

logging.basicConfig(
    level=logging.INFO,
    format=FORMAT,
    handlers=[
        logging.FileHandler(LOG_FILE),
        logging.StreamHandler(sys.stdout)
    ]
)
logger = logging.getLogger(__name__)
logger.level = logging.INFO

logger.info('Hello world!')
```

For more information, see [Correlating Python Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/python.md).
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=python#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=python#code-examples-5). In serverless, only the *distribution* metric type is supported.
Enable profiling (preview)
To enable the [Continuous Profiler](https://docs.datadoghq.com/profiler.md), set the environment variable `DD_PROFILING_ENABLED=true` in your application container.

{% alert level="info" %}
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
{% /alert %}
{% /section %}

{% section displayed-if="Runtime is Node.js" %}
This section only applies to users who meet the following criteria: Runtime is Node.js

### Sidecar: Node.js{% #sidecar-nodejs %}
Install the Datadog Node.js SDK
In your main application, install the `dd-trace` package.

```
npm install dd-trace
```

Initialize the Node.js tracer with the `NODE_OPTIONS` environment variable:

In the `Dockerfile` file:

```
ENV NODE_OPTIONS="--require dd-trace/init"
```

For more information, see [Tracing Node.js applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/nodejs.md).
Install serverless-init as a sidecar
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

{% tab title="Datadog CLI" %}
#### Locally{% #locally-3-2 %}

Install the Datadog CLI:

```
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

To set up the Datadog sidecar for your applications, configure the [Datadog site](https://docs.datadoghq.com/getting_started/site.md) and Datadog API key, and run the `instrument` command *after* your normal deployment:

```
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

You can also instrument multiple applications using the full resource IDs:

```
datadog-ci container-app instrument \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
```

##### Azure Cloud Shell{% #azure-cloud-shell-3-2 %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly.

```
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

Additional parameters can be found in the [CLI documentation](https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-container-app#arguments).
{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Container Apps](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) wraps the [`azurerm_container_app`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_app) resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_container_app_environment" "my_env" {
    name                = "my-container-app-env" // Replace with your container app environment name
    resource_group_name = "my-resource-group"    // Replace with your resource group name
    location            = "eastus"
}

module "my_container_app" {
  source  = "DataDog/container-app-datadog/azurerm"
  version = "~> 1.0"

  name                         = "my-container-app" // Replace with your container app name
  resource_group_name          = "my-resource-group" // Replace with your resource group name
  container_app_environment_id = azurerm_container_app_environment.my_env.id

  datadog_api_key = var.datadog_api_key
  datadog_site    = "datadoghq.com" // Replace with your Datadog site
  datadog_service = "my-service"    // Replace with your service name
  datadog_env     = "dev"           // Replace with your environment (e.g. prod, staging, dev)
  datadog_version = "0.1.0"         // Replace with your application version

  revision_mode         = "Single"
  workload_profile_name = "Consumption"
  ingress = {
    external_enabled = true
    target_port      = 8080
    traffic_weight = [{
      percentage      = 100
      latest_revision = true
    }]
  }
  template = {
    container = [{
      cpu    = 0.5
      memory = "1Gi"
      image  = "docker.io/your-docker-image:latest" // Replace with your Docker image
      name   = "main"
    }]
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Container App module](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) only deploys the Container App resource, so you need to build and push your container separately.

See the Environment variables section for more information on the configuration options available through the `env`.

Make sure the container port for the main container matches the one exposed in your Dockerfile/service.

If you haven't already, initialize your Terraform project:

```
terraform init
```

To deploy your app, run:

```
terraform apply
```

{% /tab %}

{% tab title="Bicep" %}
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:

```
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'

resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  // ...
  properties: {
    template: {
      volumes: [
        {
          name: 'shared-volume'
          storageType: 'EmptyDir'
        }
        // Additional volumes
      ]
      containers: [
        {
          name: 'main'
          image: 'index.docker.io/your/image:tag' // Replace with your Application Image
          resources: {
            cpu: 1
            memory: '2Gi'
          }
          env: [
            { name: 'DD_ENV', value: env }
            { name: 'DD_SERVICE', value: name }
            { name: 'DD_VERSION', value: version }
            { name: 'DD_LOGS_INJECTION', value: 'true' }
            // Additional tracing/application env vars
          ]
          volumeMounts: [
            { volumeName: 'shared-volume', mountPath: '/shared-volume' }
            // Additional volume mounts
          ]
        }
        {
          name: 'datadog-sidecar'
          image: 'index.docker.io/datadog/serverless-init:latest'
          resources: {
            cpu: '0.5'
            memory: '1Gi'
          }
          env: [
            { name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
            { name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
            { name: 'DD_API_KEY', value: datadogApiKey }
            { name: 'DD_SITE', value: datadogSite }
            { name: 'DD_SERVICE', value: service }
            { name: 'DD_ENV', value: env }
            { name: 'DD_VERSION', value: version }
            // set this to wherever you write logs in the shared volume:
            { name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
          ]
          volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
        }
      ]
      scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
    }
  }
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "datadogApiKey": {
      "type": "securestring"
    },
    "datadogSite": {
      "type": "string"
    },
    "service": {
      "type": "string",
      "defaultValue": "my-service"
    },
    "env": {
      "type": "string",
      "defaultValue": "dev"
    },
    "version": {
      "type": "string",
      "defaultValue": "0.0.0"
    }
  },
  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2024-03-01",
      // ...
      "properties": {
        "template": {
          "volumes": [
            {
              "name": "shared-volume",
              "storageType": "EmptyDir"
            }
            // Additional volumes
          ],
          "containers": [
            {
              "name": "main",
              "image": "index.docker.io/your/image:tag", // Replace with your Application Image
              "resources": {
                "cpu": 1,
                "memory": "2Gi"
              },
              "env": [
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                // Additional tracing/application env vars
                {
                  "name": "DD_LOGS_INJECTION",
                  "value": "true"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
                // Additional volume mounts
              ]
            },
            {
              "name": "datadog-sidecar",
              "image": "index.docker.io/datadog/serverless-init:latest",
              "resources": {
                "cpu": "0.5",
                "memory": "1Gi"
              },
              "env": [
                {
                  "name": "DD_AZURE_SUBSCRIPTION_ID",
                  "value": "[subscription().subscriptionId]"
                },
                {
                  "name": "DD_AZURE_RESOURCE_GROUP",
                  "value": "[resourceGroup().name]"
                },
                {
                  "name": "DD_API_KEY",
                  "value": "[parameters('datadogApiKey')]"
                },
                {
                  "name": "DD_SITE",
                  "value": "[parameters('datadogSite')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                {
                  "name": "DD_SERVERLESS_LOG_PATH",
                  // set this to wherever you write logs in the shared volume:
                  "value": "/shared-volume/logs/app.log"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 1,
            "rules": []
          }
        }
      }
    }
  ]
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}
#### Application environment variables{% #application-environment-variables-3-2 %}

Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.

| Name         | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `DD_SERVICE` | How you want to tag your service. For example, `sidecar-azure`. |
| `DD_ENV`     | How you want to tag your env. For example, `prod`.              |
| `DD_VERSION` | How you want to tag your application version.                   |

#### Sidecar container{% #sidecar-container-3-2 %}

1. In the Azure Portal, navigate to **Application** > **Revisions and replicas**. Select **Create new revision**.
1. On the **Container** tab, under **Container image**, select **Add**. Choose **App container**.
1. In the **Add a container** form, provide the following:
   - **Name**: `datadog`
   - **Image source**: Docker Hub or other registries
   - **Image type**: `Public`
   - **Registry login server**: `docker.io`
   - **Image and tag**: `datadog/serverless-init:<YOUR_TAG>`
   - Define your container resource allocation based on your usage.
1. Add a volume mount using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
1. Set the environment variables in the following table:

##### Sidecar environment variables{% #sidecar-environment-variables-3-2 %}

| Name                       | Description                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_AZURE_SUBSCRIPTION_ID` | **Required**. Your Azure subscription ID.                                                                                                                                |
| `DD_AZURE_RESOURCE_GROUP`  | **Required**. Your Azure resource group.                                                                                                                                 |
| `DD_API_KEY`               | **Required**. Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).                                                                          |
| `DD_SITE`                  | Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, `datadoghq.com`.                                                                   |
| `DD_SERVICE`               | How you want to tag your service. For example, `sidecar-azure`.                                                                                                          |
| `DD_ENV`                   | How you want to tag your env. For example, `prod`.                                                                                                                       |
| `DD_VERSION`               | How you want to tag your application version.                                                                                                                            |
| `DD_SERVERLESS_LOG_PATH`   | If using the agent for log collection, where you write your logs. For example, `/LogFiles/*.log`. This must match the logging path set up in your application container. |

#### Logging{% #logging-3-2 %}

If using the Datadog Agent for log collection, add a volume mount to the sidecar container *and* your application containers using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type **Ephemeral storage** when creating your volume. The examples on this page use the volume name `logs` and the mount path `/LogFiles`.

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format"
   alt="Adding a volume mount to a container in Azure" /%}

{% /tab %}
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in `DD_SERVERLESS_LOG_PATH`. In Node.js, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as `winston`:

```
const { createLogger, format, transports } = require('winston');

const LOG_FILE = "/LogFiles/app.log"

const logger = createLogger({
  level: 'info',
  exitOnError: false,
  format: format.json(),
  transports: [
    new transports.File({ filename: LOG_FILE }),
    new transports.Console()
  ],
});

logger.info('Hello world!');
```

Datadog recommends setting the environment variables `DD_LOGS_INJECTION=true` (in your main container) and `DD_SOURCE=nodejs` (in your sidecar container) to enable advanced Datadog log parsing.

For more information, see [Correlating Node.js Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/nodejs.md).
Send custom metrics
To send custom metrics, [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=nodejs#code-examples-5). In serverless, only the *distribution* metric type is supported.
Enable profiling (preview)
To enable the [Continuous Profiler](https://docs.datadoghq.com/profiler.md), set the environment variable `DD_PROFILING_ENABLED=true` in your application container.

{% alert level="info" %}
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
{% /alert %}
{% /section %}

{% section displayed-if="Runtime is Go" %}
This section only applies to users who meet the following criteria: Runtime is Go

### Sidecar: Go{% #sidecar-go %}
Install the Datadog Go SDK
In your main application, add the SDK from `dd-trace-go`.

```
go get github.com/DataDog/dd-trace-go/v2/ddtrace/tracer
```

Add the following to your application code to initialize the tracer:

```
tracer.Start()
defer tracer.Stop()
```

You can also add additional packages:

```
# Enable Profiling
go get github.com/DataDog/dd-trace-go/v2/profiler

# Patch /net/http
go get github.com/DataDog/dd-trace-go/contrib/net/http/v2
```

For more information, see [Tracing Go Applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/go.md) and the [Tracer README](https://github.com/DataDog/dd-trace-go?tab=readme-ov-file#installing).
Install serverless-init as a sidecar
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

{% tab title="Datadog CLI" %}
#### Locally{% #locally-4-2 %}

Install the Datadog CLI:

```
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

To set up the Datadog sidecar for your applications, configure the [Datadog site](https://docs.datadoghq.com/getting_started/site.md) and Datadog API key, and run the `instrument` command *after* your normal deployment:

```
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

You can also instrument multiple applications using the full resource IDs:

```
datadog-ci container-app instrument \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
```

##### Azure Cloud Shell{% #azure-cloud-shell-4-2 %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly.

```
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

Additional parameters can be found in the [CLI documentation](https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-container-app#arguments).
{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Container Apps](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) wraps the [`azurerm_container_app`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_app) resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_container_app_environment" "my_env" {
    name                = "my-container-app-env" // Replace with your container app environment name
    resource_group_name = "my-resource-group"    // Replace with your resource group name
    location            = "eastus"
}

module "my_container_app" {
  source  = "DataDog/container-app-datadog/azurerm"
  version = "~> 1.0"

  name                         = "my-container-app" // Replace with your container app name
  resource_group_name          = "my-resource-group" // Replace with your resource group name
  container_app_environment_id = azurerm_container_app_environment.my_env.id

  datadog_api_key = var.datadog_api_key
  datadog_site    = "datadoghq.com" // Replace with your Datadog site
  datadog_service = "my-service"    // Replace with your service name
  datadog_env     = "dev"           // Replace with your environment (e.g. prod, staging, dev)
  datadog_version = "0.1.0"         // Replace with your application version

  revision_mode         = "Single"
  workload_profile_name = "Consumption"
  ingress = {
    external_enabled = true
    target_port      = 8080
    traffic_weight = [{
      percentage      = 100
      latest_revision = true
    }]
  }
  template = {
    container = [{
      cpu    = 0.5
      memory = "1Gi"
      image  = "docker.io/your-docker-image:latest" // Replace with your Docker image
      name   = "main"
    }]
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Container App module](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) only deploys the Container App resource, so you need to build and push your container separately.

See the Environment variables section for more information on the configuration options available through the `env`.

Make sure the container port for the main container matches the one exposed in your Dockerfile/service.

If you haven't already, initialize your Terraform project:

```
terraform init
```

To deploy your app, run:

```
terraform apply
```

{% /tab %}

{% tab title="Bicep" %}
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:

```
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'

resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  // ...
  properties: {
    template: {
      volumes: [
        {
          name: 'shared-volume'
          storageType: 'EmptyDir'
        }
        // Additional volumes
      ]
      containers: [
        {
          name: 'main'
          image: 'index.docker.io/your/image:tag' // Replace with your Application Image
          resources: {
            cpu: 1
            memory: '2Gi'
          }
          env: [
            { name: 'DD_ENV', value: env }
            { name: 'DD_SERVICE', value: name }
            { name: 'DD_VERSION', value: version }
            { name: 'DD_LOGS_INJECTION', value: 'true' }
            // Additional tracing/application env vars
          ]
          volumeMounts: [
            { volumeName: 'shared-volume', mountPath: '/shared-volume' }
            // Additional volume mounts
          ]
        }
        {
          name: 'datadog-sidecar'
          image: 'index.docker.io/datadog/serverless-init:latest'
          resources: {
            cpu: '0.5'
            memory: '1Gi'
          }
          env: [
            { name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
            { name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
            { name: 'DD_API_KEY', value: datadogApiKey }
            { name: 'DD_SITE', value: datadogSite }
            { name: 'DD_SERVICE', value: service }
            { name: 'DD_ENV', value: env }
            { name: 'DD_VERSION', value: version }
            // set this to wherever you write logs in the shared volume:
            { name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
          ]
          volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
        }
      ]
      scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
    }
  }
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "datadogApiKey": {
      "type": "securestring"
    },
    "datadogSite": {
      "type": "string"
    },
    "service": {
      "type": "string",
      "defaultValue": "my-service"
    },
    "env": {
      "type": "string",
      "defaultValue": "dev"
    },
    "version": {
      "type": "string",
      "defaultValue": "0.0.0"
    }
  },
  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2024-03-01",
      // ...
      "properties": {
        "template": {
          "volumes": [
            {
              "name": "shared-volume",
              "storageType": "EmptyDir"
            }
            // Additional volumes
          ],
          "containers": [
            {
              "name": "main",
              "image": "index.docker.io/your/image:tag", // Replace with your Application Image
              "resources": {
                "cpu": 1,
                "memory": "2Gi"
              },
              "env": [
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                // Additional tracing/application env vars
                {
                  "name": "DD_LOGS_INJECTION",
                  "value": "true"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
                // Additional volume mounts
              ]
            },
            {
              "name": "datadog-sidecar",
              "image": "index.docker.io/datadog/serverless-init:latest",
              "resources": {
                "cpu": "0.5",
                "memory": "1Gi"
              },
              "env": [
                {
                  "name": "DD_AZURE_SUBSCRIPTION_ID",
                  "value": "[subscription().subscriptionId]"
                },
                {
                  "name": "DD_AZURE_RESOURCE_GROUP",
                  "value": "[resourceGroup().name]"
                },
                {
                  "name": "DD_API_KEY",
                  "value": "[parameters('datadogApiKey')]"
                },
                {
                  "name": "DD_SITE",
                  "value": "[parameters('datadogSite')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                {
                  "name": "DD_SERVERLESS_LOG_PATH",
                  // set this to wherever you write logs in the shared volume:
                  "value": "/shared-volume/logs/app.log"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 1,
            "rules": []
          }
        }
      }
    }
  ]
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}
#### Application environment variables{% #application-environment-variables-4-2 %}

Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.

| Name         | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `DD_SERVICE` | How you want to tag your service. For example, `sidecar-azure`. |
| `DD_ENV`     | How you want to tag your env. For example, `prod`.              |
| `DD_VERSION` | How you want to tag your application version.                   |

#### Sidecar container{% #sidecar-container-4-2 %}

1. In the Azure Portal, navigate to **Application** > **Revisions and replicas**. Select **Create new revision**.
1. On the **Container** tab, under **Container image**, select **Add**. Choose **App container**.
1. In the **Add a container** form, provide the following:
   - **Name**: `datadog`
   - **Image source**: Docker Hub or other registries
   - **Image type**: `Public`
   - **Registry login server**: `docker.io`
   - **Image and tag**: `datadog/serverless-init:<YOUR_TAG>`
   - Define your container resource allocation based on your usage.
1. Add a volume mount using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
1. Set the environment variables in the following table:

##### Sidecar environment variables{% #sidecar-environment-variables-4-2 %}

| Name                       | Description                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_AZURE_SUBSCRIPTION_ID` | **Required**. Your Azure subscription ID.                                                                                                                                |
| `DD_AZURE_RESOURCE_GROUP`  | **Required**. Your Azure resource group.                                                                                                                                 |
| `DD_API_KEY`               | **Required**. Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).                                                                          |
| `DD_SITE`                  | Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, `datadoghq.com`.                                                                   |
| `DD_SERVICE`               | How you want to tag your service. For example, `sidecar-azure`.                                                                                                          |
| `DD_ENV`                   | How you want to tag your env. For example, `prod`.                                                                                                                       |
| `DD_VERSION`               | How you want to tag your application version.                                                                                                                            |
| `DD_SERVERLESS_LOG_PATH`   | If using the agent for log collection, where you write your logs. For example, `/LogFiles/*.log`. This must match the logging path set up in your application container. |

#### Logging{% #logging-4-2 %}

If using the Datadog Agent for log collection, add a volume mount to the sidecar container *and* your application containers using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type **Ephemeral storage** when creating your volume. The examples on this page use the volume name `logs` and the mount path `/LogFiles`.

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format"
   alt="Adding a volume mount to a container in Azure" /%}

{% /tab %}
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in `DD_SERVERLESS_LOG_PATH`. In Go, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as `logrus`:

```
const LOG_FILE = "/LogFiles/app.log"

os.MkdirAll(filepath.Dir(LOG_FILE), 0755)
logFile, err := os.OpenFile(LOG_FILE, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
defer logFile.Close()

logrus.SetOutput(logFile)
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.AddHook(&dd_logrus.DDContextLogHook{})

logrus.WithContext(ctx).Info("Hello World!")
```

Datadog recommends setting the environment variable `DD_SOURCE=go` in your sidecar container to enable advanced Datadog log parsing.

For more information, see [Correlating Go Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/go.md).
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=go#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=go#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is Java" %}
This section only applies to users who meet the following criteria: Runtime is Java

### Sidecar: Java{% #sidecar-java %}
Install the Datadog Java SDK
Add the Datadog Java SDK to your Dockerfile:

In the `Dockerfile` file:

```
ADD 'https://dtdg.co/latest-java-tracer' agent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:agent.jar"
```

Add the SDK artifacts.

{% tab title="Maven" %}

```
<dependency>
  <groupId>com.datadoghq</groupId>
  <artifactId>dd-trace-api</artifactId>
  <version>DD_TRACE_JAVA_VERSION_HERE</version>
</dependency>
```

{% /tab %}

{% tab title="Gradle" %}

```
implementation 'com.datadoghq:dd-trace-api:DD_TRACE_JAVA_VERSION_HERE'
```

{% /tab %}

See [dd-trace-java releases](https://github.com/DataDog/dd-trace-java/releases) for the latest tracer version.

Add the `@Trace` annotation to any method you want to trace.

For more information, see [Tracing Java Applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/java.md).
Install serverless-init as a sidecar
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

{% tab title="Datadog CLI" %}
#### Locally{% #locally-5-2 %}

Install the Datadog CLI:

```
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

To set up the Datadog sidecar for your applications, configure the [Datadog site](https://docs.datadoghq.com/getting_started/site.md) and Datadog API key, and run the `instrument` command *after* your normal deployment:

```
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

You can also instrument multiple applications using the full resource IDs:

```
datadog-ci container-app instrument \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
```

##### Azure Cloud Shell{% #azure-cloud-shell-5-2 %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly.

```
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

Additional parameters can be found in the [CLI documentation](https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-container-app#arguments).
{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Container Apps](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) wraps the [`azurerm_container_app`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_app) resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_container_app_environment" "my_env" {
    name                = "my-container-app-env" // Replace with your container app environment name
    resource_group_name = "my-resource-group"    // Replace with your resource group name
    location            = "eastus"
}

module "my_container_app" {
  source  = "DataDog/container-app-datadog/azurerm"
  version = "~> 1.0"

  name                         = "my-container-app" // Replace with your container app name
  resource_group_name          = "my-resource-group" // Replace with your resource group name
  container_app_environment_id = azurerm_container_app_environment.my_env.id

  datadog_api_key = var.datadog_api_key
  datadog_site    = "datadoghq.com" // Replace with your Datadog site
  datadog_service = "my-service"    // Replace with your service name
  datadog_env     = "dev"           // Replace with your environment (e.g. prod, staging, dev)
  datadog_version = "0.1.0"         // Replace with your application version

  revision_mode         = "Single"
  workload_profile_name = "Consumption"
  ingress = {
    external_enabled = true
    target_port      = 8080
    traffic_weight = [{
      percentage      = 100
      latest_revision = true
    }]
  }
  template = {
    container = [{
      cpu    = 0.5
      memory = "1Gi"
      image  = "docker.io/your-docker-image:latest" // Replace with your Docker image
      name   = "main"
    }]
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Container App module](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) only deploys the Container App resource, so you need to build and push your container separately.

See the Environment variables section for more information on the configuration options available through the `env`.

Make sure the container port for the main container matches the one exposed in your Dockerfile/service.

If you haven't already, initialize your Terraform project:

```
terraform init
```

To deploy your app, run:

```
terraform apply
```

{% /tab %}

{% tab title="Bicep" %}
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:

```
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'

resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  // ...
  properties: {
    template: {
      volumes: [
        {
          name: 'shared-volume'
          storageType: 'EmptyDir'
        }
        // Additional volumes
      ]
      containers: [
        {
          name: 'main'
          image: 'index.docker.io/your/image:tag' // Replace with your Application Image
          resources: {
            cpu: 1
            memory: '2Gi'
          }
          env: [
            { name: 'DD_ENV', value: env }
            { name: 'DD_SERVICE', value: name }
            { name: 'DD_VERSION', value: version }
            { name: 'DD_LOGS_INJECTION', value: 'true' }
            // Additional tracing/application env vars
          ]
          volumeMounts: [
            { volumeName: 'shared-volume', mountPath: '/shared-volume' }
            // Additional volume mounts
          ]
        }
        {
          name: 'datadog-sidecar'
          image: 'index.docker.io/datadog/serverless-init:latest'
          resources: {
            cpu: '0.5'
            memory: '1Gi'
          }
          env: [
            { name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
            { name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
            { name: 'DD_API_KEY', value: datadogApiKey }
            { name: 'DD_SITE', value: datadogSite }
            { name: 'DD_SERVICE', value: service }
            { name: 'DD_ENV', value: env }
            { name: 'DD_VERSION', value: version }
            // set this to wherever you write logs in the shared volume:
            { name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
          ]
          volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
        }
      ]
      scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
    }
  }
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "datadogApiKey": {
      "type": "securestring"
    },
    "datadogSite": {
      "type": "string"
    },
    "service": {
      "type": "string",
      "defaultValue": "my-service"
    },
    "env": {
      "type": "string",
      "defaultValue": "dev"
    },
    "version": {
      "type": "string",
      "defaultValue": "0.0.0"
    }
  },
  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2024-03-01",
      // ...
      "properties": {
        "template": {
          "volumes": [
            {
              "name": "shared-volume",
              "storageType": "EmptyDir"
            }
            // Additional volumes
          ],
          "containers": [
            {
              "name": "main",
              "image": "index.docker.io/your/image:tag", // Replace with your Application Image
              "resources": {
                "cpu": 1,
                "memory": "2Gi"
              },
              "env": [
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                // Additional tracing/application env vars
                {
                  "name": "DD_LOGS_INJECTION",
                  "value": "true"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
                // Additional volume mounts
              ]
            },
            {
              "name": "datadog-sidecar",
              "image": "index.docker.io/datadog/serverless-init:latest",
              "resources": {
                "cpu": "0.5",
                "memory": "1Gi"
              },
              "env": [
                {
                  "name": "DD_AZURE_SUBSCRIPTION_ID",
                  "value": "[subscription().subscriptionId]"
                },
                {
                  "name": "DD_AZURE_RESOURCE_GROUP",
                  "value": "[resourceGroup().name]"
                },
                {
                  "name": "DD_API_KEY",
                  "value": "[parameters('datadogApiKey')]"
                },
                {
                  "name": "DD_SITE",
                  "value": "[parameters('datadogSite')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                {
                  "name": "DD_SERVERLESS_LOG_PATH",
                  // set this to wherever you write logs in the shared volume:
                  "value": "/shared-volume/logs/app.log"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 1,
            "rules": []
          }
        }
      }
    }
  ]
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}
#### Application environment variables{% #application-environment-variables-5-2 %}

Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.

| Name         | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `DD_SERVICE` | How you want to tag your service. For example, `sidecar-azure`. |
| `DD_ENV`     | How you want to tag your env. For example, `prod`.              |
| `DD_VERSION` | How you want to tag your application version.                   |

#### Sidecar container{% #sidecar-container-5-2 %}

1. In the Azure Portal, navigate to **Application** > **Revisions and replicas**. Select **Create new revision**.
1. On the **Container** tab, under **Container image**, select **Add**. Choose **App container**.
1. In the **Add a container** form, provide the following:
   - **Name**: `datadog`
   - **Image source**: Docker Hub or other registries
   - **Image type**: `Public`
   - **Registry login server**: `docker.io`
   - **Image and tag**: `datadog/serverless-init:<YOUR_TAG>`
   - Define your container resource allocation based on your usage.
1. Add a volume mount using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
1. Set the environment variables in the following table:

##### Sidecar environment variables{% #sidecar-environment-variables-5-2 %}

| Name                       | Description                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_AZURE_SUBSCRIPTION_ID` | **Required**. Your Azure subscription ID.                                                                                                                                |
| `DD_AZURE_RESOURCE_GROUP`  | **Required**. Your Azure resource group.                                                                                                                                 |
| `DD_API_KEY`               | **Required**. Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).                                                                          |
| `DD_SITE`                  | Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, `datadoghq.com`.                                                                   |
| `DD_SERVICE`               | How you want to tag your service. For example, `sidecar-azure`.                                                                                                          |
| `DD_ENV`                   | How you want to tag your env. For example, `prod`.                                                                                                                       |
| `DD_VERSION`               | How you want to tag your application version.                                                                                                                            |
| `DD_SERVERLESS_LOG_PATH`   | If using the agent for log collection, where you write your logs. For example, `/LogFiles/*.log`. This must match the logging path set up in your application container. |

#### Logging{% #logging-5-2 %}

If using the Datadog Agent for log collection, add a volume mount to the sidecar container *and* your application containers using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type **Ephemeral storage** when creating your volume. The examples on this page use the volume name `logs` and the mount path `/LogFiles`.

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format"
   alt="Adding a volume mount to a container in Azure" /%}

{% /tab %}
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in `DD_SERVERLESS_LOG_PATH`. In Java, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as `Log4j 2`:

```
private static final Logger logger = LogManager.getLogger(App.class);
logger.info("Hello World!");
```

In the `resources/log4j2.xml` file:

```
<Configuration>
  <Appenders>
    <Console name="Console"><JsonLayout compact="true" eventEol="true" properties="true"/></Console>
    <File name="FileAppender" fileName="/LogFiles/app.log">
      <JsonLayout compact="true" eventEol="true" properties="true"/>
    </File>
  </Appenders>
  <Loggers><Root level="info"><AppenderRef ref="FileAppender"/></Root></Loggers>
</Configuration>
```

Datadog recommends setting the environment variables `DD_LOGS_INJECTION=true` (in your main container) and `DD_SOURCE=java` (in your sidecar container) to enable advanced Datadog log parsing.

For more information, see [Correlating Java Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/java.md).
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=java#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=java#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is .NET" %}
This section only applies to users who meet the following criteria: Runtime is .NET

### Sidecar: .NET{% #sidecar-net %}
Install the Datadog .NET SDK
Install the Datadog .NET SDK in your Dockerfile.

{% tab title="Standard Linux (glibc)" %}
In the `Dockerfile` file:

```
ARG TRACER_VERSION
RUN curl -L -s "https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm_${TRACER_VERSION}_amd64.deb" --output datadog-dotnet-apm.deb && \
   dpkg -i datadog-dotnet-apm.deb
```

{% /tab %}

{% tab title="Alpine (musl)" %}
In the `Dockerfile` file:

```
# For alpine use datadog-dotnet-apm-2.57.0-musl.tar.gz
ARG TRACER_VERSION
ADD https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm-${TRACER_VERSION}.tar.gz /tmp/datadog-dotnet-apm.tar.gz

RUN mkdir -p /dd_tracer/dotnet/ && tar -xzvf /tmp/datadog-dotnet-apm.tar.gz -C /dd_tracer/dotnet/ && rm /tmp/datadog-dotnet-apm.tar.gz
```

{% /tab %}

See the [dd-trace-dotnet releases](https://github.com/DataDog/dd-trace-dotnet/releases/) to view the latest tracer version.

For more information, see [Tracing .NET applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/dotnet-core.md?tab=linux).
Install serverless-init as a sidecar
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

{% tab title="Datadog CLI" %}
#### Locally{% #locally-6-2 %}

Install the Datadog CLI:

```
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

To set up the Datadog sidecar for your applications, configure the [Datadog site](https://docs.datadoghq.com/getting_started/site.md) and Datadog API key, and run the `instrument` command *after* your normal deployment:

```
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

You can also instrument multiple applications using the full resource IDs:

```
datadog-ci container-app instrument \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
```

##### Azure Cloud Shell{% #azure-cloud-shell-6-2 %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly.

```
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

Additional parameters can be found in the [CLI documentation](https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-container-app#arguments).
{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Container Apps](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) wraps the [`azurerm_container_app`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_app) resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_container_app_environment" "my_env" {
    name                = "my-container-app-env" // Replace with your container app environment name
    resource_group_name = "my-resource-group"    // Replace with your resource group name
    location            = "eastus"
}

module "my_container_app" {
  source  = "DataDog/container-app-datadog/azurerm"
  version = "~> 1.0"

  name                         = "my-container-app" // Replace with your container app name
  resource_group_name          = "my-resource-group" // Replace with your resource group name
  container_app_environment_id = azurerm_container_app_environment.my_env.id

  datadog_api_key = var.datadog_api_key
  datadog_site    = "datadoghq.com" // Replace with your Datadog site
  datadog_service = "my-service"    // Replace with your service name
  datadog_env     = "dev"           // Replace with your environment (e.g. prod, staging, dev)
  datadog_version = "0.1.0"         // Replace with your application version

  revision_mode         = "Single"
  workload_profile_name = "Consumption"
  ingress = {
    external_enabled = true
    target_port      = 8080
    traffic_weight = [{
      percentage      = 100
      latest_revision = true
    }]
  }
  template = {
    container = [{
      cpu    = 0.5
      memory = "1Gi"
      image  = "docker.io/your-docker-image:latest" // Replace with your Docker image
      name   = "main"
    }]
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Container App module](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) only deploys the Container App resource, so you need to build and push your container separately.

See the Environment variables section for more information on the configuration options available through the `env`.

Make sure the container port for the main container matches the one exposed in your Dockerfile/service.

If you haven't already, initialize your Terraform project:

```
terraform init
```

To deploy your app, run:

```
terraform apply
```

{% /tab %}

{% tab title="Bicep" %}
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:

```
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'

resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  // ...
  properties: {
    template: {
      volumes: [
        {
          name: 'shared-volume'
          storageType: 'EmptyDir'
        }
        // Additional volumes
      ]
      containers: [
        {
          name: 'main'
          image: 'index.docker.io/your/image:tag' // Replace with your Application Image
          resources: {
            cpu: 1
            memory: '2Gi'
          }
          env: [
            { name: 'DD_ENV', value: env }
            { name: 'DD_SERVICE', value: name }
            { name: 'DD_VERSION', value: version }
            { name: 'DD_LOGS_INJECTION', value: 'true' }
            // Additional tracing/application env vars
          ]
          volumeMounts: [
            { volumeName: 'shared-volume', mountPath: '/shared-volume' }
            // Additional volume mounts
          ]
        }
        {
          name: 'datadog-sidecar'
          image: 'index.docker.io/datadog/serverless-init:latest'
          resources: {
            cpu: '0.5'
            memory: '1Gi'
          }
          env: [
            { name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
            { name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
            { name: 'DD_API_KEY', value: datadogApiKey }
            { name: 'DD_SITE', value: datadogSite }
            { name: 'DD_SERVICE', value: service }
            { name: 'DD_ENV', value: env }
            { name: 'DD_VERSION', value: version }
            // set this to wherever you write logs in the shared volume:
            { name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
          ]
          volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
        }
      ]
      scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
    }
  }
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "datadogApiKey": {
      "type": "securestring"
    },
    "datadogSite": {
      "type": "string"
    },
    "service": {
      "type": "string",
      "defaultValue": "my-service"
    },
    "env": {
      "type": "string",
      "defaultValue": "dev"
    },
    "version": {
      "type": "string",
      "defaultValue": "0.0.0"
    }
  },
  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2024-03-01",
      // ...
      "properties": {
        "template": {
          "volumes": [
            {
              "name": "shared-volume",
              "storageType": "EmptyDir"
            }
            // Additional volumes
          ],
          "containers": [
            {
              "name": "main",
              "image": "index.docker.io/your/image:tag", // Replace with your Application Image
              "resources": {
                "cpu": 1,
                "memory": "2Gi"
              },
              "env": [
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                // Additional tracing/application env vars
                {
                  "name": "DD_LOGS_INJECTION",
                  "value": "true"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
                // Additional volume mounts
              ]
            },
            {
              "name": "datadog-sidecar",
              "image": "index.docker.io/datadog/serverless-init:latest",
              "resources": {
                "cpu": "0.5",
                "memory": "1Gi"
              },
              "env": [
                {
                  "name": "DD_AZURE_SUBSCRIPTION_ID",
                  "value": "[subscription().subscriptionId]"
                },
                {
                  "name": "DD_AZURE_RESOURCE_GROUP",
                  "value": "[resourceGroup().name]"
                },
                {
                  "name": "DD_API_KEY",
                  "value": "[parameters('datadogApiKey')]"
                },
                {
                  "name": "DD_SITE",
                  "value": "[parameters('datadogSite')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                {
                  "name": "DD_SERVERLESS_LOG_PATH",
                  // set this to wherever you write logs in the shared volume:
                  "value": "/shared-volume/logs/app.log"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 1,
            "rules": []
          }
        }
      }
    }
  ]
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}
#### Application environment variables{% #application-environment-variables-6-2 %}

Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.

| Name         | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `DD_SERVICE` | How you want to tag your service. For example, `sidecar-azure`. |
| `DD_ENV`     | How you want to tag your env. For example, `prod`.              |
| `DD_VERSION` | How you want to tag your application version.                   |

#### Sidecar container{% #sidecar-container-6-2 %}

1. In the Azure Portal, navigate to **Application** > **Revisions and replicas**. Select **Create new revision**.
1. On the **Container** tab, under **Container image**, select **Add**. Choose **App container**.
1. In the **Add a container** form, provide the following:
   - **Name**: `datadog`
   - **Image source**: Docker Hub or other registries
   - **Image type**: `Public`
   - **Registry login server**: `docker.io`
   - **Image and tag**: `datadog/serverless-init:<YOUR_TAG>`
   - Define your container resource allocation based on your usage.
1. Add a volume mount using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
1. Set the environment variables in the following table:

##### Sidecar environment variables{% #sidecar-environment-variables-6-2 %}

| Name                       | Description                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_AZURE_SUBSCRIPTION_ID` | **Required**. Your Azure subscription ID.                                                                                                                                |
| `DD_AZURE_RESOURCE_GROUP`  | **Required**. Your Azure resource group.                                                                                                                                 |
| `DD_API_KEY`               | **Required**. Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).                                                                          |
| `DD_SITE`                  | Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, `datadoghq.com`.                                                                   |
| `DD_SERVICE`               | How you want to tag your service. For example, `sidecar-azure`.                                                                                                          |
| `DD_ENV`                   | How you want to tag your env. For example, `prod`.                                                                                                                       |
| `DD_VERSION`               | How you want to tag your application version.                                                                                                                            |
| `DD_SERVERLESS_LOG_PATH`   | If using the agent for log collection, where you write your logs. For example, `/LogFiles/*.log`. This must match the logging path set up in your application container. |

#### Logging{% #logging-6-2 %}

If using the Datadog Agent for log collection, add a volume mount to the sidecar container *and* your application containers using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type **Ephemeral storage** when creating your volume. The examples on this page use the volume name `logs` and the mount path `/LogFiles`.

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format"
   alt="Adding a volume mount to a container in Azure" /%}

{% /tab %}
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to that file set in `DD_SERVERLESS_LOG_PATH`. In .NET, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as `Serilog`:

```
using Serilog;

const string LOG_FILE = "/LogFiles/app.log";

builder.Host.UseSerilog((context, config) =>
{
    // Ensure the directory exists
    Directory.CreateDirectory(Path.GetDirectoryName(LOG_FILE)!);

    config.WriteTo.Console(new Serilog.Formatting.Json.JsonFormatter(renderMessage: true))
          .WriteTo.File(new Serilog.Formatting.Json.JsonFormatter(renderMessage: true), LOG_FILE);
});

logger.LogInformation("Hello World!");
```

Datadog recommends setting the environment variables `DD_LOGS_INJECTION=true` (in your main container) and `DD_SOURCE=csharp` (in your sidecar container) to enable advanced Datadog log parsing.

For more information, see [Correlating .NET Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/dotnet.md).
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=dotnet#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=dotnet#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is Ruby" %}
This section only applies to users who meet the following criteria: Runtime is Ruby

### Sidecar: Ruby{% #sidecar-ruby %}
Install the Datadog Ruby SDK
Add the `datadog` gem to your Gemfile:

In the `Gemfile` file:

```
source 'https://rubygems.org'
gem 'datadog'
```

See [Tracing Ruby applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/ruby.md#instrument-your-application) for additional information on how to configure the SDK and enable auto instrumentation.
Install serverless-init as a sidecar
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

{% tab title="Datadog CLI" %}
#### Locally{% #locally-7-2 %}

Install the Datadog CLI:

```
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

To set up the Datadog sidecar for your applications, configure the [Datadog site](https://docs.datadoghq.com/getting_started/site.md) and Datadog API key, and run the `instrument` command *after* your normal deployment:

```
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

You can also instrument multiple applications using the full resource IDs:

```
datadog-ci container-app instrument \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
```

##### Azure Cloud Shell{% #azure-cloud-shell-7-2 %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly.

```
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

Additional parameters can be found in the [CLI documentation](https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-container-app#arguments).
{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Container Apps](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) wraps the [`azurerm_container_app`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_app) resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_container_app_environment" "my_env" {
    name                = "my-container-app-env" // Replace with your container app environment name
    resource_group_name = "my-resource-group"    // Replace with your resource group name
    location            = "eastus"
}

module "my_container_app" {
  source  = "DataDog/container-app-datadog/azurerm"
  version = "~> 1.0"

  name                         = "my-container-app" // Replace with your container app name
  resource_group_name          = "my-resource-group" // Replace with your resource group name
  container_app_environment_id = azurerm_container_app_environment.my_env.id

  datadog_api_key = var.datadog_api_key
  datadog_site    = "datadoghq.com" // Replace with your Datadog site
  datadog_service = "my-service"    // Replace with your service name
  datadog_env     = "dev"           // Replace with your environment (e.g. prod, staging, dev)
  datadog_version = "0.1.0"         // Replace with your application version

  revision_mode         = "Single"
  workload_profile_name = "Consumption"
  ingress = {
    external_enabled = true
    target_port      = 8080
    traffic_weight = [{
      percentage      = 100
      latest_revision = true
    }]
  }
  template = {
    container = [{
      cpu    = 0.5
      memory = "1Gi"
      image  = "docker.io/your-docker-image:latest" // Replace with your Docker image
      name   = "main"
    }]
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Container App module](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) only deploys the Container App resource, so you need to build and push your container separately.

See the Environment variables section for more information on the configuration options available through the `env`.

Make sure the container port for the main container matches the one exposed in your Dockerfile/service.

If you haven't already, initialize your Terraform project:

```
terraform init
```

To deploy your app, run:

```
terraform apply
```

{% /tab %}

{% tab title="Bicep" %}
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:

```
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'

resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  // ...
  properties: {
    template: {
      volumes: [
        {
          name: 'shared-volume'
          storageType: 'EmptyDir'
        }
        // Additional volumes
      ]
      containers: [
        {
          name: 'main'
          image: 'index.docker.io/your/image:tag' // Replace with your Application Image
          resources: {
            cpu: 1
            memory: '2Gi'
          }
          env: [
            { name: 'DD_ENV', value: env }
            { name: 'DD_SERVICE', value: name }
            { name: 'DD_VERSION', value: version }
            { name: 'DD_LOGS_INJECTION', value: 'true' }
            // Additional tracing/application env vars
          ]
          volumeMounts: [
            { volumeName: 'shared-volume', mountPath: '/shared-volume' }
            // Additional volume mounts
          ]
        }
        {
          name: 'datadog-sidecar'
          image: 'index.docker.io/datadog/serverless-init:latest'
          resources: {
            cpu: '0.5'
            memory: '1Gi'
          }
          env: [
            { name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
            { name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
            { name: 'DD_API_KEY', value: datadogApiKey }
            { name: 'DD_SITE', value: datadogSite }
            { name: 'DD_SERVICE', value: service }
            { name: 'DD_ENV', value: env }
            { name: 'DD_VERSION', value: version }
            // set this to wherever you write logs in the shared volume:
            { name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
          ]
          volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
        }
      ]
      scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
    }
  }
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "datadogApiKey": {
      "type": "securestring"
    },
    "datadogSite": {
      "type": "string"
    },
    "service": {
      "type": "string",
      "defaultValue": "my-service"
    },
    "env": {
      "type": "string",
      "defaultValue": "dev"
    },
    "version": {
      "type": "string",
      "defaultValue": "0.0.0"
    }
  },
  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2024-03-01",
      // ...
      "properties": {
        "template": {
          "volumes": [
            {
              "name": "shared-volume",
              "storageType": "EmptyDir"
            }
            // Additional volumes
          ],
          "containers": [
            {
              "name": "main",
              "image": "index.docker.io/your/image:tag", // Replace with your Application Image
              "resources": {
                "cpu": 1,
                "memory": "2Gi"
              },
              "env": [
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                // Additional tracing/application env vars
                {
                  "name": "DD_LOGS_INJECTION",
                  "value": "true"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
                // Additional volume mounts
              ]
            },
            {
              "name": "datadog-sidecar",
              "image": "index.docker.io/datadog/serverless-init:latest",
              "resources": {
                "cpu": "0.5",
                "memory": "1Gi"
              },
              "env": [
                {
                  "name": "DD_AZURE_SUBSCRIPTION_ID",
                  "value": "[subscription().subscriptionId]"
                },
                {
                  "name": "DD_AZURE_RESOURCE_GROUP",
                  "value": "[resourceGroup().name]"
                },
                {
                  "name": "DD_API_KEY",
                  "value": "[parameters('datadogApiKey')]"
                },
                {
                  "name": "DD_SITE",
                  "value": "[parameters('datadogSite')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                {
                  "name": "DD_SERVERLESS_LOG_PATH",
                  // set this to wherever you write logs in the shared volume:
                  "value": "/shared-volume/logs/app.log"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 1,
            "rules": []
          }
        }
      }
    }
  ]
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}
#### Application environment variables{% #application-environment-variables-7-2 %}

Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.

| Name         | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `DD_SERVICE` | How you want to tag your service. For example, `sidecar-azure`. |
| `DD_ENV`     | How you want to tag your env. For example, `prod`.              |
| `DD_VERSION` | How you want to tag your application version.                   |

#### Sidecar container{% #sidecar-container-7-2 %}

1. In the Azure Portal, navigate to **Application** > **Revisions and replicas**. Select **Create new revision**.
1. On the **Container** tab, under **Container image**, select **Add**. Choose **App container**.
1. In the **Add a container** form, provide the following:
   - **Name**: `datadog`
   - **Image source**: Docker Hub or other registries
   - **Image type**: `Public`
   - **Registry login server**: `docker.io`
   - **Image and tag**: `datadog/serverless-init:<YOUR_TAG>`
   - Define your container resource allocation based on your usage.
1. Add a volume mount using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
1. Set the environment variables in the following table:

##### Sidecar environment variables{% #sidecar-environment-variables-7-2 %}

| Name                       | Description                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_AZURE_SUBSCRIPTION_ID` | **Required**. Your Azure subscription ID.                                                                                                                                |
| `DD_AZURE_RESOURCE_GROUP`  | **Required**. Your Azure resource group.                                                                                                                                 |
| `DD_API_KEY`               | **Required**. Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).                                                                          |
| `DD_SITE`                  | Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, `datadoghq.com`.                                                                   |
| `DD_SERVICE`               | How you want to tag your service. For example, `sidecar-azure`.                                                                                                          |
| `DD_ENV`                   | How you want to tag your env. For example, `prod`.                                                                                                                       |
| `DD_VERSION`               | How you want to tag your application version.                                                                                                                            |
| `DD_SERVERLESS_LOG_PATH`   | If using the agent for log collection, where you write your logs. For example, `/LogFiles/*.log`. This must match the logging path set up in your application container. |

#### Logging{% #logging-7-2 %}

If using the Datadog Agent for log collection, add a volume mount to the sidecar container *and* your application containers using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type **Ephemeral storage** when creating your volume. The examples on this page use the volume name `logs` and the mount path `/LogFiles`.

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format"
   alt="Adding a volume mount to a container in Azure" /%}

{% /tab %}
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in `DD_SERVERLESS_LOG_PATH`. You can also set a custom format for log/trace correlation and other features. Datadog recommends setting the environment variable `DD_SOURCE=ruby` in your sidecar container to enable advanced Datadog log parsing.

Then, update your logging library. For example, you can use Ruby's native `logger` library:

```
LOG_FILE = "/LogFiles/app.log"
FileUtils.mkdir_p(File.dirname(LOG_FILE))

logger = Logger.new(LOG_FILE)
logger.formatter = proc do |severity, datetime, progname, msg|
  "[#{datetime}] #{severity}: [#{Datadog::Tracing.log_correlation}] #{msg}\n"
end

logger.info "Hello World!"
```

For more information, see [Correlating Ruby Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/ruby.md).
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=ruby#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=ruby#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}

{% section displayed-if="Runtime is PHP" %}
This section only applies to users who meet the following criteria: Runtime is PHP

### Sidecar: PHP{% #sidecar-php %}
Install the Datadog PHP SDK
Install the Datadog PHP SDK in your Dockerfile.

In the `Dockerfile` file:

```
RUN curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php \
  && php datadog-setup.php --php-bin=all
```

When running the `datadog-setup.php` script, you can also enable Application Security and Profiling by using the `--enable-appsec` and `--enable-profiling` flags, respectively.

If you are using Alpine Linux, you need to install `libgcc_s` prior to running the installer:

```
apk add libgcc
```

For more information, see [Tracing PHP applications](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/php.md).
Install serverless-init as a sidecar
Datadog publishes new releases of the `serverless-init` container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:

| hub.docker.com          | gcr.io                           | public.ecr.aws                         |
| ----------------------- | -------------------------------- | -------------------------------------- |
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |

Images are tagged based on semantic versioning, with each new version receiving three relevant tags:

- `1`, `1-alpine`: use these to track the latest minor releases, without breaking changes
- `1.x.x`, `1.x.x-alpine`: use these to pin to a precise version of the library
- `latest`, `latest-alpine`: use these to follow the latest version release, which may include breaking changes

{% tab title="Datadog CLI" %}
#### Locally{% #locally-8-2 %}

Install the Datadog CLI:

```
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

To set up the Datadog sidecar for your applications, configure the [Datadog site](https://docs.datadoghq.com/getting_started/site.md) and Datadog API key, and run the `instrument` command *after* your normal deployment:

```
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

You can also instrument multiple applications using the full resource IDs:

```
datadog-ci container-app instrument \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
  --resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
```

##### Azure Cloud Shell{% #azure-cloud-shell-8-2 %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly.

```
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
```

Additional parameters can be found in the [CLI documentation](https://github.com/DataDog/datadog-ci/tree/master/packages/plugin-container-app#arguments).
{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Container Apps](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) wraps the [`azurerm_container_app`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_app) resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_container_app_environment" "my_env" {
    name                = "my-container-app-env" // Replace with your container app environment name
    resource_group_name = "my-resource-group"    // Replace with your resource group name
    location            = "eastus"
}

module "my_container_app" {
  source  = "DataDog/container-app-datadog/azurerm"
  version = "~> 1.0"

  name                         = "my-container-app" // Replace with your container app name
  resource_group_name          = "my-resource-group" // Replace with your resource group name
  container_app_environment_id = azurerm_container_app_environment.my_env.id

  datadog_api_key = var.datadog_api_key
  datadog_site    = "datadoghq.com" // Replace with your Datadog site
  datadog_service = "my-service"    // Replace with your service name
  datadog_env     = "dev"           // Replace with your environment (e.g. prod, staging, dev)
  datadog_version = "0.1.0"         // Replace with your application version

  revision_mode         = "Single"
  workload_profile_name = "Consumption"
  ingress = {
    external_enabled = true
    target_port      = 8080
    traffic_weight = [{
      percentage      = 100
      latest_revision = true
    }]
  }
  template = {
    container = [{
      cpu    = 0.5
      memory = "1Gi"
      image  = "docker.io/your-docker-image:latest" // Replace with your Docker image
      name   = "main"
    }]
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Container App module](https://registry.terraform.io/modules/DataDog/container-app-datadog/azurerm/latest) only deploys the Container App resource, so you need to build and push your container separately.

See the Environment variables section for more information on the configuration options available through the `env`.

Make sure the container port for the main container matches the one exposed in your Dockerfile/service.

If you haven't already, initialize your Terraform project:

```
terraform init
```

To deploy your app, run:

```
terraform apply
```

{% /tab %}

{% tab title="Bicep" %}
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:

```
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'

resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
  // ...
  properties: {
    template: {
      volumes: [
        {
          name: 'shared-volume'
          storageType: 'EmptyDir'
        }
        // Additional volumes
      ]
      containers: [
        {
          name: 'main'
          image: 'index.docker.io/your/image:tag' // Replace with your Application Image
          resources: {
            cpu: 1
            memory: '2Gi'
          }
          env: [
            { name: 'DD_ENV', value: env }
            { name: 'DD_SERVICE', value: name }
            { name: 'DD_VERSION', value: version }
            { name: 'DD_LOGS_INJECTION', value: 'true' }
            // Additional tracing/application env vars
          ]
          volumeMounts: [
            { volumeName: 'shared-volume', mountPath: '/shared-volume' }
            // Additional volume mounts
          ]
        }
        {
          name: 'datadog-sidecar'
          image: 'index.docker.io/datadog/serverless-init:latest'
          resources: {
            cpu: '0.5'
            memory: '1Gi'
          }
          env: [
            { name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
            { name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
            { name: 'DD_API_KEY', value: datadogApiKey }
            { name: 'DD_SITE', value: datadogSite }
            { name: 'DD_SERVICE', value: service }
            { name: 'DD_ENV', value: env }
            { name: 'DD_VERSION', value: version }
            // set this to wherever you write logs in the shared volume:
            { name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
          ]
          volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
        }
      ]
      scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
    }
  }
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:

```
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "datadogApiKey": {
      "type": "securestring"
    },
    "datadogSite": {
      "type": "string"
    },
    "service": {
      "type": "string",
      "defaultValue": "my-service"
    },
    "env": {
      "type": "string",
      "defaultValue": "dev"
    },
    "version": {
      "type": "string",
      "defaultValue": "0.0.0"
    }
  },
  "resources": [
    {
      "type": "Microsoft.App/containerApps",
      "apiVersion": "2024-03-01",
      // ...
      "properties": {
        "template": {
          "volumes": [
            {
              "name": "shared-volume",
              "storageType": "EmptyDir"
            }
            // Additional volumes
          ],
          "containers": [
            {
              "name": "main",
              "image": "index.docker.io/your/image:tag", // Replace with your Application Image
              "resources": {
                "cpu": 1,
                "memory": "2Gi"
              },
              "env": [
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                // Additional tracing/application env vars
                {
                  "name": "DD_LOGS_INJECTION",
                  "value": "true"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
                // Additional volume mounts
              ]
            },
            {
              "name": "datadog-sidecar",
              "image": "index.docker.io/datadog/serverless-init:latest",
              "resources": {
                "cpu": "0.5",
                "memory": "1Gi"
              },
              "env": [
                {
                  "name": "DD_AZURE_SUBSCRIPTION_ID",
                  "value": "[subscription().subscriptionId]"
                },
                {
                  "name": "DD_AZURE_RESOURCE_GROUP",
                  "value": "[resourceGroup().name]"
                },
                {
                  "name": "DD_API_KEY",
                  "value": "[parameters('datadogApiKey')]"
                },
                {
                  "name": "DD_SITE",
                  "value": "[parameters('datadogSite')]"
                },
                {
                  "name": "DD_SERVICE",
                  "value": "[parameters('service')]"
                },
                {
                  "name": "DD_ENV",
                  "value": "[parameters('env')]"
                },
                {
                  "name": "DD_VERSION",
                  "value": "[parameters('version')]"
                },
                {
                  "name": "DD_SERVERLESS_LOG_PATH",
                  // set this to wherever you write logs in the shared volume:
                  "value": "/shared-volume/logs/app.log"
                }
              ],
              "volumeMounts": [
                {
                  "volumeName": "shared-volume",
                  "mountPath": "/shared-volume"
                }
              ]
            }
          ],
          "scale": {
            "minReplicas": 1,
            "maxReplicas": 1,
            "rules": []
          }
        }
      }
    }
  ]
}
```

Redeploy your updated template:

```
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

See the **Manual** tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}
#### Application environment variables{% #application-environment-variables-8-2 %}

Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.

| Name         | Description                                                     |
| ------------ | --------------------------------------------------------------- |
| `DD_SERVICE` | How you want to tag your service. For example, `sidecar-azure`. |
| `DD_ENV`     | How you want to tag your env. For example, `prod`.              |
| `DD_VERSION` | How you want to tag your application version.                   |

#### Sidecar container{% #sidecar-container-8-2 %}

1. In the Azure Portal, navigate to **Application** > **Revisions and replicas**. Select **Create new revision**.
1. On the **Container** tab, under **Container image**, select **Add**. Choose **App container**.
1. In the **Add a container** form, provide the following:
   - **Name**: `datadog`
   - **Image source**: Docker Hub or other registries
   - **Image type**: `Public`
   - **Registry login server**: `docker.io`
   - **Image and tag**: `datadog/serverless-init:<YOUR_TAG>`
   - Define your container resource allocation based on your usage.
1. Add a volume mount using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
1. Set the environment variables in the following table:

##### Sidecar environment variables{% #sidecar-environment-variables-8-2 %}

| Name                       | Description                                                                                                                                                              |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `DD_AZURE_SUBSCRIPTION_ID` | **Required**. Your Azure subscription ID.                                                                                                                                |
| `DD_AZURE_RESOURCE_GROUP`  | **Required**. Your Azure resource group.                                                                                                                                 |
| `DD_API_KEY`               | **Required**. Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).                                                                          |
| `DD_SITE`                  | Your [Datadog site](https://docs.datadoghq.com/getting_started/site.md). For example, `datadoghq.com`.                                                                   |
| `DD_SERVICE`               | How you want to tag your service. For example, `sidecar-azure`.                                                                                                          |
| `DD_ENV`                   | How you want to tag your env. For example, `prod`.                                                                                                                       |
| `DD_VERSION`               | How you want to tag your application version.                                                                                                                            |
| `DD_SERVERLESS_LOG_PATH`   | If using the agent for log collection, where you write your logs. For example, `/LogFiles/*.log`. This must match the logging path set up in your application container. |

#### Logging{% #logging-8-2 %}

If using the Datadog Agent for log collection, add a volume mount to the sidecar container *and* your application containers using [replica-scoped storage](https://learn.microsoft.com/en-us/azure/container-apps/storage-mounts?pivots=azure-cli&tabs=smb#replica-scoped-storage). Use type **Ephemeral storage** when creating your volume. The examples on this page use the volume name `logs` and the mount path `/LogFiles`.

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format"
   alt="Adding a volume mount to a container in Azure" /%}

{% /tab %}
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in `DD_SERVERLESS_LOG_PATH`. For example:

```
const LOG_FILE = "/LogFiles/app.log";

function logInfo($message) {
    Log::build([
        'driver' => 'single',
        'path' => LOG_FILE,
    ])->info($message);
}

logInfo('Hello World!');
```

Datadog recommends setting the environment variables `DD_LOGS_INJECTION=true` (in your main container) and `DD_SOURCE=php` (in your sidecar container) to enable advanced Datadog log parsing.

For more information, see [Correlating PHP Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces/php.md).
Send custom metrics
To send custom metrics, [install the DogStatsD client](https://docs.datadoghq.com/extend/dogstatsd.md?tab=php#install-the-dogstatsd-client) and [view code examples](https://docs.datadoghq.com/metrics/custom_metrics/dogstatsd_metrics_submission.md?tab=php#code-examples-5). In serverless, only the *distribution* metric type is supported.
{% /section %}
{% /section %}

## Environment variables{% #environment-variables %}

{% section displayed-if="Instrumentation method is In-Container" %}
This section only applies to users who meet the following criteria: Instrumentation method is In-Container

| Variable                   | Description                                                                                                                                                                                                                                                                                                                                              |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DD_API_KEY`               | [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) - **Required**                                                                                                                                                                                                                                                               |
| `DD_SITE`                  | [Datadog site](https://docs.datadoghq.com/getting_started/site.md) - **Required**                                                                                                                                                                                                                                                                        |
| `DD_SERVICE`               | Datadog Service name. **Required**                                                                                                                                                                                                                                                                                                                       |
| `DD_AZURE_SUBSCRIPTION_ID` | Azure Subscription ID. **Required**                                                                                                                                                                                                                                                                                                                      |
| `DD_AZURE_RESOURCE_GROUP`  | Azure Resource Group name. **Required**                                                                                                                                                                                                                                                                                                                  |
| `DD_LOGS_ENABLED`          | When true, send logs (stdout and stderr) to Datadog. Defaults to false.                                                                                                                                                                                                                                                                                  |
| `DD_LOGS_INJECTION`        | When true, enrich all logs with trace data for supported loggers. See [Correlate Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces.md) for more information.                                                                                                                                                   |
| `DD_VERSION`               | See [Unified Service Tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging.md).                                                                                                                                                                                                                                            |
| `DD_ENV`                   | See [Unified Service Tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging.md).                                                                                                                                                                                                                                            |
| `DD_SOURCE`                | Set the log source to enable a [Log Pipeline](https://docs.datadoghq.com/logs/log_configuration/pipelines.md) for advanced parsing. To automatically apply language-specific parsing rules, set it to your application language (`python`, `nodejs`, `go`, `java`, `csharp`, `ruby`, or `php`), or use your custom pipeline. Defaults to `containerapp`. |
| `DD_TAGS`                  | Add custom tags to your logs, metrics, and traces. Tags should be comma separated in key/value format (for example: `key1:value1,key2:value2`).                                                                                                                                                                                                          |

{% section displayed-if="Runtime is Java" %}
This section only applies to users who meet the following criteria: Runtime is Java

For Java, also set `JAVA_TOOL_OPTIONS` (**Required** for tracing) to the path to the Datadog Java agent. For example, `-javaagent:/path/to/dd-java-agent.jar`.
{% /section %}
{% /section %}

{% section displayed-if="Instrumentation method is Sidecar" %}
This section only applies to users who meet the following criteria: Instrumentation method is Sidecar

| Variable                   | Description                                                                                                                                                                                                                                                                                                                                              | Container             |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| `DD_API_KEY`               | [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys) - **Required**                                                                                                                                                                                                                                                               | Sidecar container     |
| `DD_SITE`                  | [Datadog site](https://docs.datadoghq.com/getting_started/site.md) - **Required**                                                                                                                                                                                                                                                                        | Sidecar container     |
| `DD_SERVICE`               | Datadog Service name. **Required**                                                                                                                                                                                                                                                                                                                       | Both containers       |
| `DD_AZURE_SUBSCRIPTION_ID` | Azure Subscription ID. **Required**                                                                                                                                                                                                                                                                                                                      | Sidecar container     |
| `DD_AZURE_RESOURCE_GROUP`  | Azure Resource Group name. **Required**                                                                                                                                                                                                                                                                                                                  | Sidecar container     |
| `DD_SERVERLESS_LOG_PATH`   | The path where the sidecar should tail logs from. Recommended to set to `/shared-volume/logs/app.log`.                                                                                                                                                                                                                                                   | Sidecar container     |
| `DD_LOGS_INJECTION`        | When true, enrich all logs with trace data for supported loggers. See [Correlate Logs and Traces](https://docs.datadoghq.com/tracing/other_telemetry/connect_logs_and_traces.md) for more information.                                                                                                                                                   | Application container |
| `DD_VERSION`               | See [Unified Service Tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging.md).                                                                                                                                                                                                                                            | Both containers       |
| `DD_ENV`                   | See [Unified Service Tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging.md).                                                                                                                                                                                                                                            | Both containers       |
| `DD_SOURCE`                | Set the log source to enable a [Log Pipeline](https://docs.datadoghq.com/logs/log_configuration/pipelines.md) for advanced parsing. To automatically apply language-specific parsing rules, set it to your application language (`python`, `nodejs`, `go`, `java`, `csharp`, `ruby`, or `php`), or use your custom pipeline. Defaults to `containerapp`. | Sidecar container     |
| `DD_TAGS`                  | Add custom tags to your logs, metrics, and traces. Tags should be comma separated in key/value format (for example: `key1:value1,key2:value2`).                                                                                                                                                                                                          | Sidecar container     |

{% section displayed-if="Runtime is Java" %}
This section only applies to users who meet the following criteria: Runtime is Java

For Java, also set `JAVA_TOOL_OPTIONS` (**Required** for tracing) in the application container to the path to the Datadog Java agent. For example, `-javaagent:/path/to/dd-java-agent.jar`.
{% /section %}
{% /section %}

**Do not set** the following environment variables in your serverless environment. They should only be set in non-serverless environments.

- `DD_AGENT_HOST`
- `DD_TRACE_AGENT_URL`

## Troubleshooting{% #troubleshooting %}

This integration depends on your runtime having a full SSL implementation. If you are using a slim image, you may need to add the following command to your Dockerfile to include certificates:

```
RUN apt-get update && apt-get install -y ca-certificates
```

To have your services appear in the [Catalog](https://docs.datadoghq.com/internal_developer_portal/software_catalog.md), you must set the `DD_SERVICE`, `DD_VERSION`, and `DD_ENV` environment variables.

{% section displayed-if="Instrumentation method is Sidecar" %}
This section only applies to users who meet the following criteria: Instrumentation method is Sidecar

If you are missing logs or traces during container shutdown, specify a container start up order to make your main container depend on the sidecar container.
{% /section %}

## Further reading{% #further-reading %}

Additional helpful documentation, links, and articles:

- [Disable Serverless Monitoring](https://docs.datadoghq.com/serverless/guide/disable_serverless.md)
- [Collect traces, logs, and custom metrics from Container Apps services](https://www.datadoghq.com/blog/azure-container-apps/)
- [Build secure and scalable Azure serverless applications with the Well-Architected Framework](http://datadoghq.com/blog/azure-well-architected-serverless-applications-best-practices/)
- [Azure Integration](https://docs.datadoghq.com/integrations/azure.md)
- [Datadog MCP Server: serverless_onboarding tool](https://docs.datadoghq.com/mcp_server/tools.md#serverless_onboarding)

{% image
   source="https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format&fit=max&w=850 1x, https://docs.dd-static.net/images/serverless/azure_container_apps/aca-volume-mount.753e0b15953e49805769dcc4bd1ba06f.png?auto=format&fit=max&w=850&dpr=2 2x"
   alt="" /%}
