Skip to content

Commit

Permalink
TME-2307: add support for existing trail with x-account resources (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
sarjumulmi authored Aug 15, 2023
1 parent 47b5dc2 commit d3270e1
Show file tree
Hide file tree
Showing 19 changed files with 326 additions and 67 deletions.
13 changes: 13 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,17 @@ jobs:
- attach_workspace:
at: .
- terraform/fmt
- run:
# There is a bug in terraform that fails validation for module with configuration configuration_aliases
# https://github.com/hashicorp/terraform/issues/28490
# As a workaround, we create a temp provider file before running `terraform validate`
# https://github.com/hashicorp/terraform/issues/28490#issuecomment-1140007955
name: create temp provider file
command: |
cat > provider.tf \<<EOF
provider "aws" {
region = "us-east-1"
alias = "log_bucket"
}
EOF
- terraform/validate
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ Configures a CloudTrail stack (CloudTrail & S3 bucket) with a notification queue
```hcl
module "expel_aws_cloudtrail" {
source = "expel-io/cloudtrail/aws"
version = "1.3.0"
version = "2.0.0"
providers = {
aws.log_bucket = aws //setting the log_bucket alias to default aws provider for new cloudtrail
}
expel_customer_organization_guid = "Replace with your organization GUID from Expel Workbench"
region = "AWS region in which notification queue for CloudTrail will be created"
Expand All @@ -30,14 +34,13 @@ The permissions allocated by this module allow Expel Workbench to perform invest
1. Creating a new AWS CloudTrail for an AWS organization (default)
2. Creating a new AWS CloudTrail for a single AWS account (Set [enable_organization_trail](#input_enable_organization_trail) input to false)
3. Reusing an existing AWS Cloudtrail for a single AWS account or an AWS organization with all the existing resources deployed in the same account (Set [existing_cloudtrail_bucket_name](#input_existing_cloudtrail_bucket_name) input to the name of the existing log bucket)
4. Reusing an existing AWS Cloudtrail for an AWS organization with the existing resources deployed in the different accounts (Set [is_existing_cloudtrail_cross_account](#input_is_existing_cloudtrail_cross_account) to true, [existing_cloudtrail_bucket_name](#input_existing_cloudtrail_bucket_name) input to the name of the existing log bucket, [existing_cloudtrail_log_bucket_account_id](#input_existing_cloudtrail_log_bucket_account_id) to the aws account id where the cloudtrail log bucket resides and [aws_management_account_id](#input_aws_management_account_id) to the management account id of the aws organization)

## Limitations

- This module only supports integrating with Expel when all the necessary resources are deployed in the same account.
- This module **does not** support integrating with Expel when all the necessary resources are deployed across multiple aws accounts.
> Ex. ControlTower Environments are **not supported** via this module. To integrate an AWS ControlTower environment with Expel refer to this [guide](https://support.expel.io/hc/en-us/articles/12391858961171-AWS-CloudTrail-Existing-CloudTrail-with-Control-Tower-setup-for-Workbench) in order to do so.
- For existing cloudtrail with cross account resources deployment, this module only supports integrating with Expel when [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html) is enabled. Additionally, if the cloudtrail log bucket is encrypted by an existing Customer Managed Key (CMK) that **does not** reside in the log bucket account, a new key policy needs to be added to the CMK that allows the `expel IAM role` created by the module in the log bucket account to perform `kms:Decrypt` action. Refer to [this guide](https://support.expel.io/hc/en-us/articles/12391858961171-AWS-CloudTrail-Existing-CloudTrail-with-Control-Tower-setup-for-Workbench#UUID-7931c0e3-f157-d464-2f19-fc51aaad5702_bridgehead-idm4579629317097633431279663831) for reference.
Please contact your Engagement Manager if you have an existing CloudTrail with a different configuration.
- For existing cloudtrail with cross account resources deployment, if you have an existing SNS topic configured as a notifier to the cloudtrail log bucket & the topic **does not** reside in the log bucket account, a new topic policy must be added that allows the log bucket account to perform `sns:Subscribe` action on the topic. Refer to [this aws documentation](https://docs.aws.amazon.com/sns/latest/dg/sns-send-message-to-sqs-cross-account.html) for details.

<!-- begin-tf-docs -->
## Requirements
Expand All @@ -52,6 +55,7 @@ Please contact your Engagement Manager if you have an existing CloudTrail with a
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_expel_customer_organization_guid"></a> [expel\_customer\_organization\_guid](#input\_expel\_customer\_organization\_guid) | Expel customer's organization GUID assigned to you by Expel. You can find it in your browser URL after navigating to Settings > My Organization in Workbench. | `string` | n/a | yes |
| <a name="input_aws_management_account_id"></a> [aws\_management\_account\_id](#input\_aws\_management\_account\_id) | Account id of AWS management account. | `string` | `null` | no |
| <a name="input_enable_access_logging_bucket_encryption"></a> [enable\_access\_logging\_bucket\_encryption](#input\_enable\_access\_logging\_bucket\_encryption) | Enable to encrypt objects in the access logging bucket. | `bool` | `true` | no |
| <a name="input_enable_bucket_access_logging"></a> [enable\_bucket\_access\_logging](#input\_enable\_bucket\_access\_logging) | Access logging provides detailed records for the requests that are made to an Amazon S3 bucket. | `bool` | `true` | no |
| <a name="input_enable_bucket_encryption_key_rotation"></a> [enable\_bucket\_encryption\_key\_rotation](#input\_enable\_bucket\_encryption\_key\_rotation) | If `enable_s3_encryption` is set to true, enabling key rotation will rotate the KMS keys used for S3 bucket encryption. | `bool` | `true` | no |
Expand All @@ -61,14 +65,18 @@ Please contact your Engagement Manager if you have an existing CloudTrail with a
| <a name="input_enable_sqs_encryption"></a> [enable\_sqs\_encryption](#input\_enable\_sqs\_encryption) | Enable server-side encryption (SSE) of message content with SQS-owned encryption keys. | `bool` | `true` | no |
| <a name="input_existing_cloudtrail_bucket_name"></a> [existing\_cloudtrail\_bucket\_name](#input\_existing\_cloudtrail\_bucket\_name) | The name of the existing bucket connected to the existing CloudTrail | `string` | `null` | no |
| <a name="input_existing_cloudtrail_kms_key_arn"></a> [existing\_cloudtrail\_kms\_key\_arn](#input\_existing\_cloudtrail\_kms\_key\_arn) | The ARN of the KMS key used to encrypt existing CloudTrail bucket | `string` | `null` | no |
| <a name="input_existing_cloudtrail_log_bucket_account_id"></a> [existing\_cloudtrail\_log\_bucket\_account\_id](#input\_existing\_cloudtrail\_log\_bucket\_account\_id) | Account id of AWS account where the existing cloudtrail log bucket is created. This is where the new SQS queue will be created | `string` | `null` | no |
| <a name="input_existing_sns_topic_arn"></a> [existing\_sns\_topic\_arn](#input\_existing\_sns\_topic\_arn) | The ARN of the existing SNS Topic configured to be notified by the existing CloudTrail bucket. The S3 bucket notification configuration must have the s3:ObjectCreated:* event type checked. | `string` | `null` | no |
| <a name="input_expel_assume_role_name"></a> [expel\_assume\_role\_name](#input\_expel\_assume\_role\_name) | The role name Expel will assume when authenticating. | `string` | `"ExpelTrailAssumeRole"` | no |
| <a name="input_expel_assume_role_session_name"></a> [expel\_assume\_role\_session\_name](#input\_expel\_assume\_role\_session\_name) | The session name Expel will use when authenticating. | `string` | `"ExpelCloudTrailServiceSession"` | no |
| <a name="input_expel_aws_account_arn"></a> [expel\_aws\_account\_arn](#input\_expel\_aws\_account\_arn) | Expel's AWS Account ARN to allow assuming role to gain CloudTrail access. | `string` | `"arn:aws:iam::012205512454:user/ExpelCloudService"` | no |
| <a name="input_expel_aws_user_arn"></a> [expel\_aws\_user\_arn](#input\_expel\_aws\_user\_arn) | Expel's AWS User ARN to allow assuming role to gain CloudTrail access. | `string` | `"arn:aws:iam::012205512454:user/ExpelCloudService"` | no |
| <a name="input_expel_customer_aws_account_id"></a> [expel\_customer\_aws\_account\_id](#input\_expel\_customer\_aws\_account\_id) | Account id of customer's AWS account that will be monitored by Expel if it is different than the one terraform is using. This should be the management account id if organization trail is enabled. | `string` | `null` | no |
| <a name="input_is_existing_cloudtrail_cross_account"></a> [is\_existing\_cloudtrail\_cross\_account](#input\_is\_existing\_cloudtrail\_cross\_account) | For an existing cloudtrail, whether the cloudtrail & the log bucket (& optionally log bucket notifier topic if existing) are in different aws accounts | `bool` | `false` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | A prefix to group all Expel integration resources. | `string` | `"expel-aws-cloudtrail"` | no |
| <a name="input_queue_message_retention_days"></a> [queue\_message\_retention\_days](#input\_queue\_message\_retention\_days) | The visibility timeout for the queue. See: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html | `number` | `7` | no |
| <a name="input_stackset_fault_tolerance_count"></a> [stackset\_fault\_tolerance\_count](#input\_stackset\_fault\_tolerance\_count) | The number of accounts, per Region, for which stackset deployment operation can fail before AWS CloudFormation stops the operation in that Region. | `number` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A set of tags to group resources. | `map` | `{}` | no |
| <a name="input_stackset_max_concurrent_count"></a> [stackset\_max\_concurrent\_count](#input\_stackset\_max\_concurrent\_count) | The maximum number of accounts in which to perform this operation at one time. At most, this should be set to one more than `stackset_fault_tolerance_count` | `number` | `1` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A set of tags to group resources. | `map(string)` | `{}` | no |
## Outputs

| Name | Description |
Expand All @@ -85,8 +93,10 @@ Please contact your Engagement Manager if you have an existing CloudTrail with a
| [aws_cloudformation_stack_set_instance.permeate_account_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack_set_instance) | resource |
| [aws_cloudtrail.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudtrail) | resource |
| [aws_iam_policy.cloudtrail_manager_iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.expel_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_policy.log_bucket_iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.mgmt_expel_assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.cloudtrail_manager_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.log_bucket_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_kms_key.cloudtrail_bucket_encryption_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_kms_key.notification_encryption_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_s3_bucket.cloudtrail_access_log_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
Expand All @@ -109,10 +119,11 @@ Please contact your Engagement Manager if you have an existing CloudTrail with a
| [random_uuid.cloudtrail_bucket_name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/uuid) | resource |
| [random_uuid.cloudtrail_sns_topic_name](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/uuid) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.cloudtrail_bucket_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.cloudtrail_key_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.cloudtrail_manager_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.log_bucket_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.mgmt_assume_role_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.notification_key_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.sns_queue_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.sns_topic_iam_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
Expand Down
4 changes: 4 additions & 0 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ provider "aws" {
module "expel_aws_cloudtrail_integration" {
source = "../../"

providers = {
aws.log_bucket = aws //setting the log_bucket alias to default aws provider for new cloudtrail
}

expel_customer_organization_guid = var.expel_customer_organization_guid
expel_assume_role_session_name = "ExpelServiceAssumeRoleForCloudTrailAccess"
queue_message_retention_days = 10
Expand Down
File renamed without changes.
75 changes: 75 additions & 0 deletions examples/existing-cloudtrail/cross-account/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
variable "region" {
type = string
}

variable "expel_customer_organization_guid" {
description = "Use your organization GUID assigned to you by Expel. You can find it in your browser URL after navigating to Settings > My Organization in Workbench"
type = string
}

variable "existing_cloudtrail_bucket_name" {
description = "Use your AWS CloudTrail S3 Bucket name"
type = string
}

variable "aws_management_account_id" {
description = "Use your AWS management account id"
type = string
}

variable "existing_cloudtrail_log_bucket_account_id" {
description = "Use your AWS cloudtrail log bucket account id"
type = string
}

variable "existing_cloudtrail_kms_key_arn" {
description = "Use your AWS KMS Key ARN that is used for your CloudTrail infrastructure"
type = string
default = null
}

variable "existing_sns_topic_arn" {
description = "Use your AWS CloudTrail SNS Topic ARN"
type = string
default = null
}

provider "aws" {
region = "us-east-1"
profile = "default"
}

provider "aws" {
region = "us-east-1"
alias = "log_bucket"
assume_role {
role_arn = "Replace role arn here or create a provider for log bucket account by other means"
}
}

module "expel_aws_cloudtrail_integration_x_account" {
source = "../../../"

providers = {
aws.log_bucket = aws.log_bucket //setting the log_bucket alias to the log bucket aws provider for existing cloudtrail with resources in different accounts
}

is_existing_cloudtrail_cross_account = true
expel_customer_organization_guid = var.expel_customer_organization_guid
aws_management_account_id = var.aws_management_account_id
existing_cloudtrail_log_bucket_account_id = var.existing_cloudtrail_log_bucket_account_id
existing_cloudtrail_bucket_name = var.existing_cloudtrail_bucket_name
existing_cloudtrail_kms_key_arn = var.existing_cloudtrail_kms_key_arn
existing_sns_topic_arn = var.existing_sns_topic_arn

prefix = "expel-aws-cloudtrail"

tags = {
"is_external" = "true",
"x-account" = "true"
}
}

output "expel_aws_cloudtrail_integration_x_account" {
value = module.expel_aws_cloudtrail_integration_x_account
}
7 changes: 7 additions & 0 deletions examples/existing-cloudtrail/cross-account/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
region = "Replace with the AWS region in which you want the notification queue for CloudTrail to be set up"
expel_customer_organization_guid = "Replace with your organization GUID assigned to you by Expel. You can find it in your browser URL after navigating to Settings > My Organization in Workbench"
existing_cloudtrail_bucket_name = "Replace with your AWS S3 Bucket name"
aws_mgmt_account_id = "Replace with your AWS Management account id"
existing_cloudtrail_log_bucket_account_id = "Replace with your AWS Cloudtrail log bucket account id"
existing_cloudtrail_kms_key_arn = "Replace with the KMS Key ARN used for your CloudTrail S3 Bucket"
existing_sns_topic_arn = "Replace with your AWS SNS Topic ARN"
21 changes: 21 additions & 0 deletions examples/existing-cloudtrail/single-account/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Existing

This configuration creates AWS resources that are necessary to integrate Expel Workbench with an existing AWS CloudTrail instance.

## Usage

To run this example you need to execute:

```bash
terraform init
terraform apply -var-file="terraform.tfvars"
```

Note that this example may create resources which can cost money, run `terraform destroy` when you don't need these resources.

## Requirements

| Name | Version |
|------|---------|
| terraform | = 1.1.3 |
| aws | = 4.0 |
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ provider "aws" {
}

module "expel_aws_cloudtrail_integration" {
source = "../../"
source = "../../../"

providers = {
aws.log_bucket = aws //setting the log_bucket alias to default aws provider for existing cloudtrail with resources in single account
}

expel_customer_organization_guid = var.expel_customer_organization_guid
existing_cloudtrail_bucket_name = var.existing_cloudtrail_bucket_name
existing_cloudtrail_kms_key_arn = var.existing_cloudtrail_kms_key_arn
existing_sns_topic_arn = var.existing_sns_topic_arn

prefix = "expel-aws-cloudtrail"

tags = {
"is_external" = "true"
}
Expand Down
Loading

0 comments on commit d3270e1

Please sign in to comment.