November 13, 2019
3 min read

Configuring AWS GuardDuty with Lambda for Slack Notifications

Dennis Kelly

At Kong, we leverage many tools to protect our services and customers. Terraform from HashiCorp allows us to automate the process with Infrastructure as Code (IaC). Another important tool is Amazon Web Services (AWS) GuardDuty, a continuous monitoring service for security threat detection in your AWS accounts. It analyzes events from CloudTrail, VPC Flow Logs and DNS logs using machine learning, anomaly detection and known threats to provide security intelligence in the form of GuardDuty alerts or findings. Multiple member AWS accounts can be aggregated into a master account to centrally manage alerts across an entire organization. It provides an enterprise with comprehensive threat detection, stronger security through automation and centralized management at scale.

GuardDuty allows us to automatically send notifications to CloudWatch Events. We use this to notify the security team on Slack by configuring a CloudWatch Event Rule on GuardDuty findings that triggers a Lambda serverless function written in Go called GuardDuty2Slack. This post will walk you through the process and code used to join member accounts to an organization and send GuardDuty findings as Slack notifications. The complete example set of code is available here.

What is GuardDuty?

GuardDuty is a regional service, so member accounts need to be invited for every region they use. Some accounts may not use the same regions as others. While there are more sophisticated ways to manage this, for the simplicity of this post, the following directory structure will be used:

accounts/Terraform snippets for GuardDuty member accountsglobal/Terraform applied at a global level (IAM roles and policies)lambda/Terraform Lambda module and Go function for notificationsus-west-1/Terraform applied at a regional level (in this example us-west-1)

In the global directory, the file is used to create an IAM role, GuardDuty2Slack, that can be assumed by the Lambda service with basic Lambda execution permissions:

The Terraform in the global directory will need to be executed first - a bootstrapping process - so the IAM role will be available when setting up each region. In the Lambda module,, the IAM role is imported as a data source and associated with the function:

The event pattern for GuardDuty findings are associated with an event rule, which is used to trigger the Lambda function:

The event rule will also need permissions to invoke the function:

The configuration of the function is stored in main.yml. It defines the colors associated with GuardDuty severity levels, the default/fall-back webhook and per account settings:

To setup a region directory, first add the account to the accounts directory. Using the example of an AWS account named member1 with an ID of 111111111111, create accounts/

When applied via Terraform, an email invitation from AWS will be sent allowing an administrator to login, enable GuardDuty and accept the invitation for the master account to be the GuardDuty administrator of the member account.

We can use the same from the top-level directory for each region directory:

In the region directory, you will need the files backend.conf to configure the terraform state and with the region (i.e. us-west-1). In the region directory, you can link and accounts desired:

To deploy the member account invitations in and the Lambda function:

Iterate this process for each region (i.e. us-east-1, us-west-2, eu-north-1).

With notifications configured and sent, it is important to understand finding severity levels, types and remediation. For further information, please visit