Skip to content

Commit 12dc58b

Browse files
authored
Merge pull request #127 from dxw/datadog
Datadog AWS integration
2 parents c0df3d6 + 26b8e86 commit 12dc58b

10 files changed

+264
-0
lines changed

README.md

+14
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ for dxw's Dalmatian hosting platform.
1515
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5.3 |
1616
| <a name="requirement_archive"></a> [archive](#requirement\_archive) | >= 2.4.0 |
1717
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.11.0 |
18+
| <a name="requirement_datadog"></a> [datadog](#requirement\_datadog) | >= 3.46.0 |
1819

1920
## Providers
2021

@@ -23,6 +24,7 @@ for dxw's Dalmatian hosting platform.
2324
| <a name="provider_archive"></a> [archive](#provider\_archive) | 2.6.0 |
2425
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.70.0 |
2526
| <a name="provider_aws.useast1"></a> [aws.useast1](#provider\_aws.useast1) | 5.70.0 |
27+
| <a name="provider_datadog"></a> [datadog](#provider\_datadog) | >= 3.46.0 |
2628

2729
## Modules
2830

@@ -46,17 +48,23 @@ for dxw's Dalmatian hosting platform.
4648
| [aws_iam_policy.cloudtrail_cloudwatch_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
4749
| [aws_iam_policy.cloudwatch_slack_alerts_logs_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
4850
| [aws_iam_policy.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
51+
| [aws_iam_policy.datadog_aws_integration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
52+
| [aws_iam_policy.datadog_aws_integration_resource_collection](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
4953
| [aws_iam_policy.delete_default_resources_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
5054
| [aws_iam_policy.delete_default_resources_vpc_delete_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
5155
| [aws_iam_policy.ssm_dhmc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
5256
| [aws_iam_role.cloudtrail_cloudwatch_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
5357
| [aws_iam_role.cloudwatch_slack_alerts_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
5458
| [aws_iam_role.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
59+
| [aws_iam_role.datadog_aws_integration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
5560
| [aws_iam_role.delete_default_resources_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
5661
| [aws_iam_role.ssm_dhmc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
5762
| [aws_iam_role_policy_attachment.cloudtrail_cloudwatch_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
5863
| [aws_iam_role_policy_attachment.cloudwatch_slack_alerts_logs_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
5964
| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
65+
| [aws_iam_role_policy_attachment.datadog_aws_integration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
66+
| [aws_iam_role_policy_attachment.datadog_aws_integration_resource_collection](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
67+
| [aws_iam_role_policy_attachment.datadog_aws_integration_security_audit](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
6068
| [aws_iam_role_policy_attachment.delete_default_resources_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
6169
| [aws_iam_role_policy_attachment.delete_default_resources_vpc_delete_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
6270
| [aws_iam_role_policy_attachment.ssm_dhmc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
@@ -106,9 +114,11 @@ for dxw's Dalmatian hosting platform.
106114
| [aws_sns_topic_subscription.cloudwatch_opsgenie_alerts_subscription_us_east_1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
107115
| [aws_sns_topic_subscription.cloudwatch_slack_alerts_lambda_subscription](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
108116
| [aws_ssm_service_setting.ssm_dhmc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_service_setting) | resource |
117+
| [datadog_integration_aws.aws](https://registry.terraform.io/providers/DataDog/datadog/latest/docs/resources/integration_aws) | resource |
109118
| [archive_file.cloudwatch_slack_alerts_lambda](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
110119
| [archive_file.delete_default_resources_lambda](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
111120
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
121+
| [aws_regions.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/regions) | data source |
112122

113123
## Inputs
114124

@@ -130,11 +140,15 @@ for dxw's Dalmatian hosting platform.
130140
| <a name="input_cloudwatch_slack_alerts_log_retention"></a> [cloudwatch\_slack\_alerts\_log\_retention](#input\_cloudwatch\_slack\_alerts\_log\_retention) | Cloudwatch Slack Alerts log retention. Set to 0 to keep all logs | `number` | n/a | yes |
131141
| <a name="input_codestar_connections"></a> [codestar\_connections](#input\_codestar\_connections) | CodeStar connections to create | <pre>map(<br/> object({<br/> provider_type = string,<br/> })<br/> )</pre> | n/a | yes |
132142
| <a name="input_custom_iam_roles"></a> [custom\_iam\_roles](#input\_custom\_iam\_roles) | Configure custom IAM roles/policies | <pre>map(object({<br/> description = string<br/> policies = map(object({<br/> description = string<br/> Version = string<br/> Statement = list(object({<br/> Action = list(string)<br/> Effect = string<br/> Resource = string<br/> }))<br/> }))<br/> assume_role_policy = object({<br/> Version = string<br/> Statement = list(object({<br/> Action = list(string)<br/> Effect = string<br/> Principal = map(string)<br/> }))<br/> })<br/> }))</pre> | n/a | yes |
143+
| <a name="input_datadog_api_key"></a> [datadog\_api\_key](#input\_datadog\_api\_key) | Datadog API key | `string` | n/a | yes |
144+
| <a name="input_datadog_app_key"></a> [datadog\_app\_key](#input\_datadog\_app\_key) | Datadog App key | `string` | n/a | yes |
145+
| <a name="input_datadog_region"></a> [datadog\_region](#input\_datadog\_region) | Datadog region | `string` | n/a | yes |
133146
| <a name="input_delete_default_resources_lambda_kms_encryption"></a> [delete\_default\_resources\_lambda\_kms\_encryption](#input\_delete\_default\_resources\_lambda\_kms\_encryption) | Conditionally encrypt the Delete Default Resources Lambda logs with KMS | `bool` | n/a | yes |
134147
| <a name="input_delete_default_resources_log_retention"></a> [delete\_default\_resources\_log\_retention](#input\_delete\_default\_resources\_log\_retention) | Log retention for the Delete Default Resources Lambda | `number` | n/a | yes |
135148
| <a name="input_enable_cloudtrail"></a> [enable\_cloudtrail](#input\_enable\_cloudtrail) | Enable Cloudtrail | `bool` | n/a | yes |
136149
| <a name="input_enable_cloudwatch_opsgenie_alerts"></a> [enable\_cloudwatch\_opsgenie\_alerts](#input\_enable\_cloudwatch\_opsgenie\_alerts) | Enable CloudWatch Opsgenie alerts. This creates an SNS topic to which alerts and pipelines can send messages, which are then sent to the Opsgenie SNS endpoint. | `bool` | n/a | yes |
137150
| <a name="input_enable_cloudwatch_slack_alerts"></a> [enable\_cloudwatch\_slack\_alerts](#input\_enable\_cloudwatch\_slack\_alerts) | Enable CloudWatch Slack alerts. This creates an SNS topic to which alerts and pipelines can send messages, which are then picked up by a Lambda function that forwards them to a Slack webhook. | `bool` | n/a | yes |
151+
| <a name="input_enable_datadog_aws_integration"></a> [enable\_datadog\_aws\_integration](#input\_enable\_datadog\_aws\_integration) | Conditionally create the datadog AWS integration role (https://docs.datadoghq.com/integrations/guide/aws-terraform-setup/) and configure the datadog integration | `bool` | n/a | yes |
138152
| <a name="input_enable_delete_default_resources"></a> [enable\_delete\_default\_resources](#input\_enable\_delete\_default\_resources) | Creates a Lambda function which deletes all default VPCs and resources within them. This only needs to be ran once, either through the AWS console or via the AWS CLI | `bool` | n/a | yes |
139153
| <a name="input_enable_route53_root_hosted_zone"></a> [enable\_route53\_root\_hosted\_zone](#input\_enable\_route53\_root\_hosted\_zone) | Conditionally create Route53 hosted zone, which will contain the DNS records for resources launched within the account. | `bool` | n/a | yes |
140154
| <a name="input_enable_s3_tfvars"></a> [enable\_s3\_tfvars](#input\_enable\_s3\_tfvars) | enable\_s3\_tfvars | `bool` | n/a | yes |

data.tf

+4
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
data "aws_caller_identity" "current" {}
2+
3+
data "aws_regions" "current" {
4+
all_regions = true
5+
}

datadog-aws-integration.tf

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
resource "aws_iam_role" "datadog_aws_integration" {
2+
count = local.enable_datadog_aws_integration ? 1 : 0
3+
4+
name = "${local.project_name_hash}-datadog-aws-integration"
5+
description = "${local.project_name}-datadog-aws-integration"
6+
assume_role_policy = templatefile(
7+
"${path.root}/policies/assume-roles/external-id.json.tpl", {
8+
iam_arns = jsonencode(["arn:aws:iam::464622532012:root"]),
9+
external_id = datadog_integration_aws.aws[0].external_id
10+
}
11+
)
12+
}
13+
14+
resource "aws_iam_policy" "datadog_aws_integration" {
15+
count = local.enable_datadog_aws_integration ? 1 : 0
16+
17+
name = "${local.project_name}-datadog-aws-integration"
18+
policy = templatefile(
19+
"${path.root}/policies/datadog-integration.json.tpl", {}
20+
)
21+
}
22+
23+
resource "aws_iam_role_policy_attachment" "datadog_aws_integration" {
24+
count = local.enable_datadog_aws_integration ? 1 : 0
25+
26+
role = aws_iam_role.datadog_aws_integration[0].name
27+
policy_arn = aws_iam_policy.datadog_aws_integration[0].arn
28+
}
29+
30+
resource "aws_iam_policy" "datadog_aws_integration_resource_collection" {
31+
count = local.enable_datadog_aws_integration ? 1 : 0
32+
33+
name = "${local.project_name}-datadog-aws-integration-resource-collection"
34+
policy = templatefile(
35+
"${path.root}/policies/datadog-integration-resource-collection.json.tpl", {}
36+
)
37+
}
38+
39+
resource "aws_iam_role_policy_attachment" "datadog_aws_integration_resource_collection" {
40+
count = local.enable_datadog_aws_integration ? 1 : 0
41+
42+
role = aws_iam_role.datadog_aws_integration[0].name
43+
policy_arn = aws_iam_policy.datadog_aws_integration_resource_collection[0].arn
44+
}
45+
46+
resource "aws_iam_role_policy_attachment" "datadog_aws_integration_security_audit" {
47+
count = local.enable_datadog_aws_integration ? 1 : 0
48+
49+
role = aws_iam_role.datadog_aws_integration[0].name
50+
policy_arn = "arn:aws:iam::aws:policy/SecurityAudit"
51+
}
52+
53+
resource "datadog_integration_aws" "aws" {
54+
count = local.enable_datadog_aws_integration ? 1 : 0
55+
56+
account_id = local.aws_account_id
57+
role_name = "${local.project_name_hash}-datadog-aws-integration"
58+
excluded_regions = local.datadog_resource_collection_excluded_regions
59+
}

locals.tf

+14
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ locals {
6262
cloudwatch_opsgenie_alerts_sns_kms_encryption = var.cloudwatch_opsgenie_alerts_sns_kms_encryption && local.enable_cloudwatch_opsgenie_alerts
6363
cloudwatch_opsgenie_alerts_sns_endpoint = var.cloudwatch_opsgenie_alerts_sns_endpoint
6464

65+
datadog_api_key = var.datadog_api_key
66+
datadog_app_key = var.datadog_app_key
67+
datadog_region = var.datadog_region
68+
datadog_api_url = local.datadog_region != "" ? {
69+
"US1" = "https://api.datadoghq.com/",
70+
"US3" = "https://api.us3.datadoghq.com/",
71+
"US5" = "https://api.us5.datadoghq.com/",
72+
"EU1" = "https://api.datadoghq.eu/",
73+
"US1-FED" = "https://api.ddog-gov.com/",
74+
"AP1" = "https://api.ap1.datadoghq.com/"
75+
}[local.datadog_region] : "https://api.datadoghq.com/"
76+
enable_datadog_aws_integration = var.enable_datadog_aws_integration
77+
datadog_resource_collection_excluded_regions = setsubtract(data.aws_regions.current.names, [local.aws_region, "us-east-1"])
78+
6579
codestar_connections = var.codestar_connections
6680

6781
enable_ssm_dhmc = var.enable_ssm_dhmc
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Sid": "",
6+
"Effect": "Allow",
7+
"Principal": {
8+
"AWS": ${iam_arns}
9+
},
10+
"Condition": {
11+
"StringEquals": {
12+
"sts:ExternalId": "${external_id}"
13+
}
14+
},
15+
"Action": "sts:AssumeRole"
16+
}
17+
]
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Action": [
6+
"backup:ListRecoveryPointsByBackupVault",
7+
"bcm-data-exports:GetExport",
8+
"bcm-data-exports:ListExports",
9+
"cassandra:Select",
10+
"cur:DescribeReportDefinitions",
11+
"ec2:GetSnapshotBlockPublicAccessState",
12+
"glacier:GetVaultNotifications",
13+
"glue:ListRegistries",
14+
"lightsail:GetInstancePortStates",
15+
"savingsplans:DescribeSavingsPlanRates",
16+
"savingsplans:DescribeSavingsPlans",
17+
"timestream:DescribeEndpoints",
18+
"waf-regional:ListRuleGroups",
19+
"waf-regional:ListRules",
20+
"waf:ListRuleGroups",
21+
"waf:ListRules",
22+
"wafv2:GetIPSet",
23+
"wafv2:GetRegexPatternSet",
24+
"wafv2:GetRuleGroup"
25+
],
26+
"Effect": "Allow",
27+
"Resource": "*"
28+
}
29+
]
30+
}

policies/datadog-integration.json.tpl

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Action": [
6+
"apigateway:GET",
7+
"autoscaling:Describe*",
8+
"backup:List*",
9+
"budgets:ViewBudget",
10+
"cloudfront:GetDistributionConfig",
11+
"cloudfront:ListDistributions",
12+
"cloudtrail:DescribeTrails",
13+
"cloudtrail:GetTrailStatus",
14+
"cloudtrail:LookupEvents",
15+
"cloudwatch:Describe*",
16+
"cloudwatch:Get*",
17+
"cloudwatch:List*",
18+
"codedeploy:List*",
19+
"codedeploy:BatchGet*",
20+
"directconnect:Describe*",
21+
"dynamodb:List*",
22+
"dynamodb:Describe*",
23+
"ec2:Describe*",
24+
"ec2:GetTransitGatewayPrefixListReferences",
25+
"ec2:SearchTransitGatewayRoutes",
26+
"ecs:Describe*",
27+
"ecs:List*",
28+
"elasticache:Describe*",
29+
"elasticache:List*",
30+
"elasticfilesystem:DescribeFileSystems",
31+
"elasticfilesystem:DescribeTags",
32+
"elasticfilesystem:DescribeAccessPoints",
33+
"elasticloadbalancing:Describe*",
34+
"elasticmapreduce:List*",
35+
"elasticmapreduce:Describe*",
36+
"es:ListTags",
37+
"es:ListDomainNames",
38+
"es:DescribeElasticsearchDomains",
39+
"events:CreateEventBus",
40+
"fsx:DescribeFileSystems",
41+
"fsx:ListTagsForResource",
42+
"health:DescribeEvents",
43+
"health:DescribeEventDetails",
44+
"health:DescribeAffectedEntities",
45+
"kinesis:List*",
46+
"kinesis:Describe*",
47+
"lambda:GetPolicy",
48+
"lambda:List*",
49+
"logs:DeleteSubscriptionFilter",
50+
"logs:DescribeLogGroups",
51+
"logs:DescribeLogStreams",
52+
"logs:DescribeSubscriptionFilters",
53+
"logs:FilterLogEvents",
54+
"logs:PutSubscriptionFilter",
55+
"logs:TestMetricFilter",
56+
"oam:ListSinks",
57+
"oam:ListAttachedLinks",
58+
"organizations:Describe*",
59+
"organizations:List*",
60+
"rds:Describe*",
61+
"rds:List*",
62+
"redshift:DescribeClusters",
63+
"redshift:DescribeLoggingStatus",
64+
"route53:List*",
65+
"s3:GetBucketLogging",
66+
"s3:GetBucketLocation",
67+
"s3:GetBucketNotification",
68+
"s3:GetBucketTagging",
69+
"s3:ListAllMyBuckets",
70+
"s3:PutBucketNotification",
71+
"ses:Get*",
72+
"sns:List*",
73+
"sns:Publish",
74+
"sns:GetSubscriptionAttributes",
75+
"sqs:ListQueues",
76+
"states:ListStateMachines",
77+
"states:DescribeStateMachine",
78+
"support:DescribeTrustedAdvisor*",
79+
"support:RefreshTrustedAdvisorCheck",
80+
"tag:GetResources",
81+
"tag:GetTagKeys",
82+
"tag:GetTagValues",
83+
"wafv2:ListLoggingConfigurations",
84+
"wafv2:GetLoggingConfiguration",
85+
"xray:BatchGetTraces",
86+
"xray:GetTraceSummaries"
87+
],
88+
"Effect": "Allow",
89+
"Resource": "*"
90+
}
91+
]
92+
}

providers.tf

+7
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,10 @@ provider "aws" {
1414
tags = local.default_tags
1515
}
1616
}
17+
18+
provider "datadog" {
19+
api_key = local.datadog_api_key
20+
app_key = local.datadog_app_key
21+
validate = local.datadog_api_key != "" && local.datadog_app_key != ""
22+
api_url = local.datadog_api_url
23+
}

variables.tf

+22
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,28 @@ variable "logging_bucket_retention" {
167167
type = number
168168
}
169169

170+
variable "datadog_api_key" {
171+
description = "Datadog API key"
172+
type = string
173+
sensitive = true
174+
}
175+
176+
variable "datadog_app_key" {
177+
description = "Datadog App key"
178+
type = string
179+
sensitive = true
180+
}
181+
182+
variable "datadog_region" {
183+
description = "Datadog region"
184+
type = string
185+
}
186+
187+
variable "enable_datadog_aws_integration" {
188+
description = "Conditionally create the datadog AWS integration role (https://docs.datadoghq.com/integrations/guide/aws-terraform-setup/) and configure the datadog integration"
189+
type = bool
190+
}
191+
170192
variable "custom_iam_roles" {
171193
type = map(object({
172194
description = string

versions.tf

+4
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,9 @@ terraform {
99
source = "hashicorp/archive"
1010
version = ">= 2.4.0"
1111
}
12+
datadog = {
13+
source = "DataDog/datadog"
14+
version = ">= 3.46.0"
15+
}
1216
}
1317
}

0 commit comments

Comments
 (0)