DETECT/IR – automating aws guard-duty with terraform

It’s been a long weekend and I haven’t left this cushy gaming chair in 12 hours, 20 if you don’t count leaving for sleep… So let’s cut to the chase so I can go ride my bike and enjoy a beer …

Here’s a quick weekend project which automates almost all of the AWS GuardDuty set up and SNS notifications of Guard Duty findings. I was feeling a bit bored and wanted to reverse engineer some more advanced terraform features such as count, for each and dynamic code blocks. Decided to use this project as a chance to get some practices… Shout out to the the @CloudPosse who wrote the original source code which I modified and refactored.

It now only takes you four commands to get some detection coverage in aws… There’s really no excuse, to not have some basic level of Threat Detection in your AWS environment …

Okay, yes you have to script out the Terraform iteration over all the AWS regions, because some of these settings are regional…

Refactored and tested under Terraform v1.1.5

git clone
terraform init
terraform plan
terraform apply 

Guard Duty and VPC flow logs, s3 and kms

The following repo is a set of terraform scripts intended to enable Guard Duty for a specific region in which Terraform is executed within. The code assumes you have already provisioned a VPC but have yet to enable flow logs on it. The code then proceeds with the following

The code behaves as follows

  • 1.) Creates and AWS KMS for the s3 bucket that will store the vpc flow logs
  • 2.) Creates TLS only and non-public S3 bucket bucket encrypted with the new KMS key
  • 3.) Configures the flow logs to send to the new s3 bucket
  • 4.) Creates an SNS topic for Guard Duty events to be sent to
  • 5.) Creates a CloudWatch/EventBridge rule to parse Guard Duty findings and forward them to SNS
  • 6.) Enables GuardDuty in the region in which you execute the Terraform script

About the refactor

The code is a refactored version of the upstream cloud posse source code under Apache 2.0 license. However, the code was refactored and modified as follows

  • Most importantly the previous code did not work correctly on Terraform v1.1.5
  • Due to the use of count and for each dynamic code blocks, the old code concatenated ARN strings with name.*.id pattern
  • In recent versions the use of .id is no longer needed in replace of ARN attribute
  • Additionally, the [0] index is passed with every name[0] in replace of name.*.id
  • The root main S3 bucket policies have been removed and pushed to modules s3 to cleanup root
  • Some of the default bucket ACL policies have been removed, only enforced TLS and Public block is enabled
  • SNS ACL access rules updated to accept eventbridge as a principle service writing into topic
  • The KMS key alias is not s user supplied input, previously a validation error was being thrown because of the use of name.*.id concatenation
  • Enable SNS and Cloud Event is now user supplied input excepting bool: true:false
  • VPCid is now a user supplied input expecting the vpc-foobaripsum format
  • All reference to external registries have been removed to prevent supply chain attack
  • All source = /registry keys removed to support local paths and version references removed to support local path files

important terraform concepts

If you want to just point and shoot without understanding any of the code-base, then due so at your own risk… I read it all, so you wouldn’t have to (-;

However, I would encourage y’all to read the following articles or at the very least keep them handy as you’re doing source code review …


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s