Skip to content

Commit b2f6c39

Browse files
Add Java and .NET Support (#10)
* add support for java and .net lambda functions * adds java example * adds .net example * formatting * update documentation for .net and java * minor updates to documentation * add comment with option for building dotnet example with arm64 architecture
1 parent 609f6a7 commit b2f6c39

File tree

20 files changed

+546
-11
lines changed

20 files changed

+546
-11
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ terraform.rc
3737
.terraform.lock.hcl
3838

3939
build
40+
target
41+
bin
42+
obj
43+
.DS_Store

README.md

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,58 @@ module "lambda-datadog" {
6464
}
6565
```
6666

67+
### .NET
68+
```
69+
module "lambda-datadog" {
70+
source = "DataDog/lambda-datadog/aws"
71+
version = "1.1.0"
72+
73+
filename = "example.zip"
74+
function_name = "example-function"
75+
role = aws_iam_role.lambda_role.arn
76+
handler = "Example::Example.Function::Handler"
77+
runtime = "dotnet8"
78+
memory_size = 256
79+
80+
environment_variables = {
81+
"DD_API_KEY_SECRET_ARN" : "arn:aws:secretsmanager:us-east-1:000000000000:secret:example-secret"
82+
"DD_ENV" : "dev"
83+
"DD_SERVICE" : "example-service"
84+
"DD_SITE": "datadoghq.com"
85+
"DD_VERSION" : "1.0.0"
86+
}
87+
88+
datadog_extension_layer_version = 58
89+
datadog_dotnet_layer_version = 15
90+
}
91+
```
92+
93+
### Java
94+
```
95+
module "lambda-datadog" {
96+
source = "DataDog/lambda-datadog/aws"
97+
version = "1.1.0"
98+
99+
filename = "example.jar"
100+
function_name = "example-function"
101+
role = aws_iam_role.lambda_role.arn
102+
handler = "com.example.Handler"
103+
runtime = "java21"
104+
memory_size = 1024
105+
106+
environment_variables = {
107+
"DD_API_KEY_SECRET_ARN" : "arn:aws:secretsmanager:us-east-1:000000000000:secret:example-secret"
108+
"DD_ENV" : "dev"
109+
"DD_SERVICE" : "example-service"
110+
"DD_SITE": "datadoghq.com"
111+
"DD_VERSION" : "1.0.0"
112+
}
113+
114+
datadog_extension_layer_version = 58
115+
datadog_java_layer_version = 14
116+
}
117+
```
118+
67119
## Configuration
68120

69121
### Lambda Function
@@ -84,6 +136,7 @@ resource "aws_lambda_function" "example_lambda_function" {
84136
variables = {
85137
"DD_API_KEY_SECRET_ARN" : "arn:aws:secretsmanager:us-east-1:000000000000:secret:example-secret"
86138
"DD_ENV" : "dev"
139+
"DD_SITE": "datadoghq.com"
87140
"DD_SERVICE" : "example-service"
88141
"DD_VERSION" : "1.0.0"
89142
}
@@ -94,15 +147,17 @@ resource "aws_lambda_function" "example_lambda_function" {
94147

95148
#### Datadog Terraform module for AWS Lambda
96149
```
97-
module "example_lambda_function" {
98-
source = "Datadog/lambda-datadog/aws"
150+
module "lambda-datadog" {
151+
source = "DataDog/lambda-datadog/aws"
152+
version = "1.1.0"
99153
100154
function_name = "example-function"
101155
...
102156
103157
environment_variables = {
104158
"DD_API_KEY_SECRET_ARN" : "arn:aws:secretsmanager:us-east-1:000000000000:secret:example-secret"
105159
"DD_ENV" : "dev"
160+
"DD_SITE": "datadoghq.com"
106161
"DD_SERVICE" : "example-service"
107162
"DD_VERSION" : "1.0.0"
108163
}
@@ -119,6 +174,8 @@ Use the following variables to select the versions of the Datadog Lambda layers
119174
| Variable | Description |
120175
| -------- | ----------- |
121176
| `datadog_extension_layer_version` | Version of the [Datadog Lambda Extension layer](https://github.com/DataDog/datadog-lambda-extension/releases) to install |
177+
| `datadog_dotnet_layer_version` | Version of the [Datadog .NET Lambda layer](https://github.com/DataDog/dd-trace-dotnet-aws-lambda-layer/releases) to install |
178+
| `datadog_java_layer_version` | Version of the [Datadog Java Lambda layer](https://github.com/DataDog/datadog-lambda-java/releases) to install |
122179
| `datadog_node_layer_version` | Version of the [Datadog Node Lambda layer](https://github.com/DataDog/datadog-lambda-js/releases) to install |
123180
| `datadog_python_layer_version` | Version of the [Datadog Python Lambda layer](https://github.com/DataDog/datadog-lambda-python/releases) to install |
124181

@@ -132,6 +189,8 @@ Use Environment variables to configure Datadog Serverless Monitoring. Refer to t
132189

133190
* [Serverless Agent Configuration](https://docs.datadoghq.com/serverless/guide/agent_configuration/)
134191
* Tracer Configuration
192+
- [.NET](https://docs.datadoghq.com/tracing/trace_collection/library_config/dotnet-framework/?tab=environmentvariables)
193+
- [Java](https://docs.datadoghq.com/tracing/trace_collection/library_config/java/)
135194
- [Node](https://github.com/DataDog/datadog-lambda-js?tab=readme-ov-file#configuration)
136195
- [Python](https://github.com/DataDog/datadog-lambda-python?tab=readme-ov-file#configuration)
137196

@@ -167,6 +226,8 @@ No modules.
167226
| <a name="input_architectures"></a> [architectures](#input\_architectures) | Instruction set architecture for your Lambda function. Valid values are ["x86\_64"] and ["arm64"]. | `list(string)` | <pre>["x86_64"]</pre> | no |
168227
| <a name="input_code_signing_config_arn"></a> [code\_signing\_config\_arn](#input\_code\_signing\_config\_arn) | To enable code signing for this function, specify the ARN of a code-signing configuration. A code-signing configuration includes a set of signing profiles, which define the trusted publishers for this function. | `string` | `null` | no |
169228
| <a name="input_datadog_extension_layer_version"></a> [datadog\_extension\_layer\_version](#input\_datadog\_extension\_layer\_version) | Version for the Datadog Extension Layer | `number` | `58` | no |
229+
| <a name="input_datadog_dotnet_layer_version"></a> [datadog\_dotnet\_layer\_version](#input\_datadog\_dotnet\_layer\_version) | Version for the Datadog .NET Layer | `number` | `15` | no |
230+
| <a name="input_datadog_java_layer_version"></a> [datadog\_java\_layer\_version](#input\_datadog\_java\_layer\_version) | Version for the Datadog Java Layer | `number` | `14` | no |
170231
| <a name="input_datadog_node_layer_version"></a> [datadog\_node\_layer\_version](#input\_datadog\_node\_layer\_version) | Version for the Datadog Node Layer | `number` | `112` | no |
171232
| <a name="input_datadog_python_layer_version"></a> [datadog\_python\_layer\_version](#input\_datadog\_python\_layer\_version) | Version for the Datadog Python Layer | `number` | `95` | no |
172233
| <a name="input_dead_letter_config_target_arn"></a> [dead\_letter\_config\_target\_arn](#input\_dead\_letter\_config\_target\_arn) | ARN of an SNS topic or SQS queue to notify when an invocation fails. | `string` | `null` | no |

examples/dotnet/README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# .NET Example
2+
3+
A simple .NET Lambda function with out of the box Datadog instrumentation.
4+
5+
## Usage
6+
7+
* Create a [Datadog API Key](https://app.datadoghq.com/organization-settings/api-keys)
8+
* Create a secret in [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) and add the Datadog API Key as the secret value in plaintext
9+
* Create a `terraform.tfvars` file
10+
- Set the `datadog_secret_arn` to the arn of the secret you just created
11+
- Set the `datadog_service_name` to the name of the service you want to use to filter for the resource in Datadog
12+
- Set the `datadog_site` to the [Datadog destination site](https://docs.datadoghq.com/getting_started/site/) for your metrics, traces, and logs
13+
* Run the following commands
14+
15+
```
16+
dotnet restore ./src/HelloWorld
17+
dotnet lambda package --configuration Debug --framework net8.0 --output-package src/HelloWorld/bin/release/net8.0/hello-dotnet.zip --project-location ./src/HelloWorld
18+
terraform init
19+
terraform plan
20+
terraform apply
21+
```
22+
23+
If using `arm64` architecture then build the lambda package with the `-farch arm64` argument.
24+
25+
<!-- BEGIN_TF_DOCS -->
26+
## Requirements
27+
28+
| Name | Version |
29+
|------|---------|
30+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3 |
31+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.32.0 |
32+
33+
## Providers
34+
35+
| Name | Version |
36+
|------|---------|
37+
| <a name="provider_archive"></a> [archive](#provider\_archive) | 2.4.2 |
38+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.32.0 |
39+
40+
## Modules
41+
42+
| Name | Source | Version |
43+
|------|--------|---------|
44+
| <a name="module_lambda-datadog"></a> [lambda-datadog](#module\_lambda-datadog) | ../../ | n/a |
45+
46+
## Resources
47+
48+
| Name | Type |
49+
|------|------|
50+
| [aws_iam_policy.secrets_manager_read_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
51+
| [aws_iam_role.lambda_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
52+
| [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
53+
| [aws_iam_role_policy_attachment.attach_secrets_manager_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
54+
| [archive_file.zip_code](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
55+
56+
## Inputs
57+
58+
| Name | Description | Type | Default | Required |
59+
|------|-------------|------|---------|:--------:|
60+
| <a name="input_datadog_secret_arn"></a> [datadog\_secret\_arn](#input\_datadog\_secret\_arn) | Secret for Datadog API Key | `string` | n/a | yes |
61+
| <a name="input_datadog_service_name"></a> [datadog\_service\_name](#input\_datadog\_service\_name) | Service used to filter for resources in Datadog | `string` | n/a | yes |
62+
| <a name="input_datadog_site"></a> [datadog\_site](#input\_datadog\_site) | Destination site for your metrics, traces, and logs | `string` | n/a | yes |
63+
64+
## Outputs
65+
66+
| Name | Description |
67+
|------|-------------|
68+
| <a name="output_arn"></a> [arn](#output\_arn) | Amazon Resource Name (ARN) identifying your Lambda Function. |
69+
| <a name="output_function_name"></a> [function\_name](#output\_function\_name) | Unique name for your Lambda Function |
70+
| <a name="output_invoke_arn"></a> [invoke\_arn](#output\_invoke\_arn) | ARN to be used for invoking Lambda Function from API Gateway. |
71+
<!-- END_TF_DOCS -->

examples/dotnet/main.tf

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
resource "aws_iam_role" "lambda_role" {
2+
name = "terraform-example-dotnet-${var.datadog_service_name}-role"
3+
assume_role_policy = jsonencode(
4+
{
5+
"Version" : "2012-10-17",
6+
"Statement" : [
7+
{
8+
"Sid" : "",
9+
"Effect" : "Allow",
10+
"Action" : "sts:AssumeRole",
11+
"Principal" : {
12+
"Service" : "lambda.amazonaws.com"
13+
}
14+
}
15+
]
16+
})
17+
}
18+
19+
resource "aws_iam_policy" "secrets_manager_read_policy" {
20+
name = "terraform-example-dotnet-${var.datadog_service_name}-secrets-manager-policy"
21+
description = "Policy to allow read access to Secrets Manager"
22+
policy = jsonencode({
23+
Version = "2012-10-17"
24+
Statement = [
25+
{
26+
Sid = "ReadSecret"
27+
Effect = "Allow"
28+
Action = "secretsmanager:GetSecretValue"
29+
Resource = var.datadog_secret_arn
30+
}
31+
]
32+
})
33+
}
34+
35+
resource "aws_iam_role_policy_attachment" "attach_iam_policy_to_iam_role" {
36+
role = aws_iam_role.lambda_role.name
37+
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
38+
}
39+
40+
resource "aws_iam_role_policy_attachment" "attach_secrets_manager_policy" {
41+
role = aws_iam_role.lambda_role.name
42+
policy_arn = aws_iam_policy.secrets_manager_read_policy.arn
43+
}
44+
45+
module "lambda-datadog" {
46+
source = "../../"
47+
48+
filename = "${path.module}/src/HelloWorld/bin/release/net8.0/hello-dotnet.zip"
49+
source_code_hash = filebase64sha256("${path.module}/src/HelloWorld/bin/release/net8.0/hello-dotnet.zip")
50+
function_name = "terraform-example-dotnet-${var.datadog_service_name}-function"
51+
role = aws_iam_role.lambda_role.arn
52+
handler = "HelloWorld::HelloWorld.Function::Handler"
53+
runtime = "dotnet8"
54+
memory_size = 256
55+
56+
environment_variables = {
57+
"DD_API_KEY_SECRET_ARN" : var.datadog_secret_arn
58+
"DD_ENV" : "dev"
59+
"DD_SERVICE" : var.datadog_service_name
60+
"DD_SITE" : var.datadog_site
61+
"DD_VERSION" : "1.0.0"
62+
}
63+
}

examples/dotnet/outputs.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "arn" {
2+
description = "Amazon Resource Name (ARN) identifying your Lambda Function."
3+
value = module.lambda-datadog.arn
4+
}
5+
6+
output "invoke_arn" {
7+
description = "ARN to be used for invoking Lambda Function from API Gateway."
8+
value = module.lambda-datadog.invoke_arn
9+
}
10+
11+
output "function_name" {
12+
description = "Unique name for your Lambda Function"
13+
value = module.lambda-datadog.function_name
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Amazon.Lambda.Core;
2+
3+
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
4+
5+
namespace HelloWorld
6+
{
7+
public class Function
8+
{
9+
public string Handler(object input, ILambdaContext context)
10+
{
11+
return "Hello!";
12+
}
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
5+
<AWSProjectType>Lambda</AWSProjectType>
6+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
7+
</PropertyGroup>
8+
<ItemGroup>
9+
<PackageReference Include="Amazon.Lambda.Core" Version="2.2.0" />
10+
<PackageReference Include="Amazon.Lambda.Serialization.Json" Version="2.2.1" />
11+
</ItemGroup>
12+
</Project>

examples/dotnet/variables.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
variable "datadog_secret_arn" {
2+
description = "Secret for Datadog API Key"
3+
type = string
4+
}
5+
6+
variable "datadog_service_name" {
7+
description = "Service used to filter for resources in Datadog"
8+
type = string
9+
}
10+
11+
variable "datadog_site" {
12+
description = "Destination site for your metrics, traces, and logs"
13+
type = string
14+
}

examples/dotnet/versions.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.3"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 5.32.0"
8+
}
9+
}
10+
}

examples/java/README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Java Example
2+
3+
A simple Java Lambda function with out of the box Datadog instrumentation.
4+
5+
## Usage
6+
7+
* Create a [Datadog API Key](https://app.datadoghq.com/organization-settings/api-keys)
8+
* Create a secret in [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) and add the Datadog API Key as the secret value in plaintext
9+
* Create a `terraform.tfvars` file
10+
- Set the `datadog_secret_arn` to the arn of the secret you just created
11+
- Set the `datadog_service_name` to the name of the service you want to use to filter for the resource in Datadog
12+
- Set the `datadog_site` to the [Datadog destination site](https://docs.datadoghq.com/getting_started/site/) for your metrics, traces, and logs
13+
* Run the following commands
14+
15+
```
16+
mvn clean package shade:shade
17+
terraform init
18+
terraform plan
19+
terraform apply
20+
```
21+
22+
<!-- BEGIN_TF_DOCS -->
23+
## Requirements
24+
25+
| Name | Version |
26+
|------|---------|
27+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3 |
28+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.32.0 |
29+
30+
## Providers
31+
32+
| Name | Version |
33+
|------|---------|
34+
| <a name="provider_archive"></a> [archive](#provider\_archive) | 2.4.2 |
35+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.32.0 |
36+
37+
## Modules
38+
39+
| Name | Source | Version |
40+
|------|--------|---------|
41+
| <a name="module_lambda-datadog"></a> [lambda-datadog](#module\_lambda-datadog) | ../../ | n/a |
42+
43+
## Resources
44+
45+
| Name | Type |
46+
|------|------|
47+
| [aws_iam_policy.secrets_manager_read_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
48+
| [aws_iam_role.lambda_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
49+
| [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
50+
| [aws_iam_role_policy_attachment.attach_secrets_manager_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
51+
| [archive_file.zip_code](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
52+
53+
## Inputs
54+
55+
| Name | Description | Type | Default | Required |
56+
|------|-------------|------|---------|:--------:|
57+
| <a name="input_datadog_secret_arn"></a> [datadog\_secret\_arn](#input\_datadog\_secret\_arn) | Secret for Datadog API Key | `string` | n/a | yes |
58+
| <a name="input_datadog_service_name"></a> [datadog\_service\_name](#input\_datadog\_service\_name) | Service used to filter for resources in Datadog | `string` | n/a | yes |
59+
| <a name="input_datadog_site"></a> [datadog\_site](#input\_datadog\_site) | Destination site for your metrics, traces, and logs | `string` | n/a | yes |
60+
61+
## Outputs
62+
63+
| Name | Description |
64+
|------|-------------|
65+
| <a name="output_arn"></a> [arn](#output\_arn) | Amazon Resource Name (ARN) identifying your Lambda Function. |
66+
| <a name="output_function_name"></a> [function\_name](#output\_function\_name) | Unique name for your Lambda Function |
67+
| <a name="output_invoke_arn"></a> [invoke\_arn](#output\_invoke\_arn) | ARN to be used for invoking Lambda Function from API Gateway. |
68+
<!-- END_TF_DOCS -->

0 commit comments

Comments
 (0)