Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support providing a cloudtrail from a different account #136

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Terraform module for configuring an integration with Lacework and AWS for CloudT
| <a name="input_cloudtrail_name"></a> [cloudtrail\_name](#input\_cloudtrail\_name) | The name of the CloudTrail. Required when setting use\_existing\_cloudtrail to true | `string` | `"lacework-cloudtrail"` | no |
| <a name="input_consolidated_trail"></a> [consolidated\_trail](#input\_consolidated\_trail) | Set this to true to configure a consolidated cloudtrail | `bool` | `false` | no |
| <a name="input_create_lacework_integration"></a> [create\_lacework\_integration](#input\_create\_lacework\_integration) | Set this to `false` if you don't want the module to automatically create a corresponding Lacework integration. | `bool` | `true` | no |
| <a name="input_cross_account_cloudtrail_arn"></a> [cross\_account\_cloudtrail\_arn](#input\_cross\_account\_cloudtrail\_arn) | If using an existing CloudTrail in another account, provide the ARN here | `string` | `null` | no |
| <a name="input_cross_account_policy_name"></a> [cross\_account\_policy\_name](#input\_cross\_account\_policy\_name) | n/a | `string` | `""` | no |
| <a name="input_enable_cloudtrail_s3_management_events"></a> [enable\_cloudtrail\_s3\_management\_events](#input\_enable\_cloudtrail\_s3\_management\_events) | Enable CloudTrail Object-level logging | `bool` | `false` | no |
| <a name="input_enable_log_file_validation"></a> [enable\_log\_file\_validation](#input\_enable\_log\_file\_validation) | Specifies whether cloudtrail log file integrity validation is enabled | `bool` | `true` | no |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Consolidated Existing CloudTrail in Another Account + Co-Existing with Datadog

This example handles a bit of a specific case.

1. You're following the AWS best practice to consolidate all CloudTrail logs into a single "security" account.
* The CloudTrail config itself exists on the org's management account
* The Bucket / KMS key exist on the security account

2. You're setting up LW when either transitioning from Datadog cloudtrail integration, or you're using both LW and Datadog.
* The coveat here is that DD's integration expects to attach a lambda hook to the CloudTrail bucket, only one such hook can be defined on the bucket, and the DD interation can be a bit aggressive about re-claiming this hook.
* This necessitates that the LW integration is done via the SNS topic the LW module sets up instead.

# Important bits of code

## Org Management Account

```hcl
resource "aws_cloudtrail" "org-trail" {
...

# Hook the lw cloudtrail sns topic
sns_topic_name = "arn:aws:sns:us-west-2:200000000000:lw-cloudtrail"
}
```

## Security Account

```hcl
module "aws_cloudtrail" {
source = "lacework/cloudtrail/aws"
version = "~> 2.8"

consolidated_trail = true

# Use an existing CloudTrail
use_existing_cloudtrail = true

# this is arn to the existung bucket in the security account
bucket_arn = "arn:aws:s3:::org-ct-bucket"

# this is the arn to the trail in the org management account
cross_account_cloudtrail_arn = "arn:aws:cloudtrail:us-west-2:100000000000:trail/org-trail"

bucket_encryption_enabled = true
bucket_sse_algorithm = "aws:kms"

# this is the arn to the kms key in the security account
bucket_sse_key_arn = "arn:aws:kms:us-west-2:200000000000:key/6e2010aa-27e4-49c6-8887-956abc1caeb9"

# Create new SNS Topic and SQS Queue
# the SNS topic is referenced in the org management account
sns_topic_name = "lw-cloudtrail"
sqs_queue_name = "lw-cloudtrail"

# Name the integration inside LW UI
lacework_integration_name = "AWS Consolidated CloudTrail"
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# in org management account - ID: 100000000000

resource "aws_cloudtrail" "org-trail" {
name = "org-trail"
s3_bucket_name = "org-ct-bucket"
kms_key_id = "arn:aws:kms:us-west-2:200000000000:key/6e2010aa-27e4-49c6-8887-956abc1caeb9"
is_multi_region_trail = true
is_organization_trail = true
enable_log_file_validation = true

# Hook the lw cloudtrail sns topic
sns_topic_name = "arn:aws:sns:us-west-2:200000000000:lw-cloudtrail"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# in a "security" account - ID: 200000000000

provider "lacework" {}

provider "aws" {
region = "us-west-2"
}

# the CT logs live in this account
# Note: in order to make this co-exist with Datadog (useful for the transitional period)
# datadog has to be allowed to maintain the lambda hook on the bucket, so we can't have
# LW hook that (it'd be the easiest option)
resource "aws_s3_bucket" "ct_bucket" {
bucket = "org-ct-bucket"
}

# and so does their KMS Key
# let's assume its ARN is: arn:aws:kms:us-west-2:200000000000:key/6e2010aa-27e4-49c6-8887-956abc1caeb9
resource "aws_kms_key" "ct_key" {
}

module "aws_cloudtrail" {
source = "../../"

consolidated_trail = true

# Use an existing CloudTrail
use_existing_cloudtrail = true
bucket_arn = "arn:aws:s3:::org-ct-bucket"
cross_account_cloudtrail_arn = "arn:aws:cloudtrail:us-west-2:100000000000:trail/org-trail"

bucket_encryption_enabled = true
bucket_sse_algorithm = "aws:kms"
bucket_sse_key_arn = "arn:aws:kms:us-west-2:200000000000:key/6e2010aa-27e4-49c6-8887-956abc1caeb9"

# Create new SNS Topic and SQS Queue
sns_topic_name = "lw-cloudtrail"
sqs_queue_name = "lw-cloudtrail"

# Name the integration inside LW UI
lacework_integration_name = "AWS Consolidated CloudTrail"
}
7 changes: 4 additions & 3 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ locals {
version_file = "${abspath(path.module)}/VERSION"
module_name = "terraform-aws-cloudtrail"
module_version = fileexists(local.version_file) ? file(local.version_file) : ""
cloudtrail_arn = var.consolidated_trail && var.use_existing_cloudtrail && var.cross_account_cloudtrail_arn != null ? var.cross_account_cloudtrail_arn : "arn:aws:cloudtrail:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:trail/${var.cloudtrail_name}"
}

resource "random_id" "uniq" {
Expand Down Expand Up @@ -475,11 +476,11 @@ data "aws_iam_policy_document" "sns_topic_policy" {
effect = "Allow"

dynamic "condition" {
for_each = !var.consolidated_trail ? [1] : []
for_each = (!var.consolidated_trail || var.cross_account_cloudtrail_arn != null) ? [1] : []
content {
test = "StringEquals"
variable = "AWS:SourceArn"
values = ["arn:aws:cloudtrail:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:trail/${var.cloudtrail_name}"]
values = [local.cloudtrail_arn]
}
}

Expand Down Expand Up @@ -699,4 +700,4 @@ resource "lacework_integration_aws_ct" "default" {
data "lacework_metric_module" "lwmetrics" {
name = local.module_name
version = local.module_version
}
}
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,9 @@ variable "enable_cloudtrail_s3_management_events" {
default = false
description = "Enable CloudTrail Object-level logging"
}

variable "cross_account_cloudtrail_arn" {
type = string
default = null
description = "If using an existing CloudTrail in another account, provide the ARN here"
}