

# Enable Amazon GuardDuty conditionally by using AWS CloudFormation templates
Enable GuardDuty using CloudFormation templates

*Ram Kandaswamy, Amazon Web Services*

## Summary


[AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html), an infrastructure as code (IaC) tool, helps you to manage AWS resources through template-based deployments. CloudFormation is typically used to manage AWS resources. Using it to enable AWS services, such as [Amazon GuardDuty](https://docs.aws.amazon.com/guardduty/latest/ug/what-is-guardduty.html), can present unique challenges. GuardDuty is a threat detection service that continuously monitors your AWS accounts for malicious activity and unauthorized behavior. Unlike typical resources that can be created multiple times, GuardDuty is a service that needs to be enabled once per account and AWS Region. Traditional CloudFormation conditions support only static value comparisons, which makes it difficult to check the current state of services such as GuardDuty. If you attempt to enable GuardDuty through CloudFormation in an account where it's already active, the stack deployment fails. This can create operational challenges for DevOps teams that are managing multi-account environments.

This pattern introduces a solution to this challenge. It uses CloudFormation custom resources that are backed by [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) functions to perform dynamic state checks. The conditional logic enables GuardDuty only if it isn’t already enabled. It uses the stack outputs to record the GuardDuty status for future reference.

By following this pattern, you can automate GuardDuty deployments across your AWS infrastructure while maintaining clean, predictable CloudFormation stack operations. This approach is particularly valuable for organizations that are:
+ Managing multiple AWS accounts through IaC
+ Implementing security services at scale
+ Requiring idempotent infrastructure deployments
+ Automating security service deployments

## Prerequisites and limitations


**Prerequisites**
+ An active AWS account
+ An AWS Identity and Access Management (IAM) role that has permissions to create, update, and delete CloudFormation stacks
+ AWS Command Line Interface (AWS CLI), [installed](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions) and [configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)

**Limitations**

If GuardDuty has been manually disabled for an AWS account or AWS Region, this pattern does not enable GuardDuty for that target account or Region.

## Architecture


**Target technology stack**

The pattern uses CloudFormation for infrastructure as code (IaC). You use a CloudFormation custom resource backed by a Lambda function to achieve the dynamic service-enablement capability.

**Target architecture**

The following high-level architecture diagram shows the process of enabling GuardDuty by deploying a CloudFormation template:

![\[Using a CloudFormation stack to enable GuardDuty in an AWS account.\]](http://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/images/pattern-img/3abd7cb7-0937-41fe-8eaa-79aedb182732/images/71624052-eebc-474a-9aa3-8606d87fc51d.png)


1. You deploy a CloudFormation template to create a CloudFormation stack.

1. The stack creates an IAM role and a Lambda function.

1. The Lambda function assumes the IAM role.

1. If GuardDuty is not already enabled on the target AWS account, the Lambda function enables it.

**Automation and scale**

You can use the AWS CloudFormation StackSet feature to extend this solution to multiple AWS accounts and AWS Regions. For more information, see [Working with AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) in the CloudFormation documentation.

## Tools

+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) is an open-source tool that helps you interact with AWS services through commands in your command-line shell.
+ [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) helps you set up AWS resources, provision them quickly and consistently, and manage them throughout their lifecycle across AWS accounts and Regions.
+ [Amazon GuardDuty](https://docs.aws.amazon.com/guardduty/latest/ug/what-is-guardduty.html) is a continuous security monitoring service that analyzes and processes logs to identify unexpected and potentially unauthorized activity in your AWS environment.
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) helps you securely manage access to your AWS resources by controlling who is authenticated and authorized to use them.
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) is a compute service that helps you run code without needing to provision or manage servers. It runs your code only when needed and scales automatically, so you pay only for the compute time that you use.

## Epics


### Create the CloudFormation template and deploy the stack



| Task | Description | Skills required | 
| --- | --- | --- | 
| Store the code in Amazon S3. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/enable-amazon-guardduty-conditionally-by-using-aws-cloudformation-templates.html) | AWS DevOps | 
| Create the CloudFormation template. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/enable-amazon-guardduty-conditionally-by-using-aws-cloudformation-templates.html) | AWS DevOps | 
| Create the CloudFormation stack. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/enable-amazon-guardduty-conditionally-by-using-aws-cloudformation-templates.html) | AWS DevOps | 
| Validate that GuardDuty is enabled for the AWS account. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/enable-amazon-guardduty-conditionally-by-using-aws-cloudformation-templates.html) | Cloud administrator, AWS administrator | 
| Configure additional accounts or Regions. | As needed for your use case, use the CloudFormation StackSet feature to extend this solution to multiple AWS accounts and AWS Regions. For more information, see [Working with AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) in the CloudFormation documentation. | Cloud administrator, AWS administrator | 

## Related resources


**References**
+ [AWS CloudFormation documentation](https://docs.aws.amazon.com/cloudformation/index.html)
+ [AWS Lambda resource type reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_Lambda.html)
+ [CloudFormation resource type: AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)
+ [CloudFormation resource type: AWS::GuardDuty::Detector ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-guardduty-detector.html)
+ [Four ways to retrieve any AWS service property using AWS CloudFormation](https://aws.amazon.com/blogs/mt/four-ways-to-retrieve-any-aws-service-property-using-aws-cloudformation-part-1/) (blog post)

**Tutorials and videos**
+ [Simplify Your Infrastructure Management Using AWS CloudFormation](https://www.youtube.com/watch?v=1h-GPXQrLZw) (Tutorial)
+ [Use Amazon GuardDuty and AWS Security Hub CSPM to secure multiple accounts](https://www.youtube.com/watch?v=Rg2ZzAAi1nY) (AWS re:Invent 2020)
+ [Best practices for authoring AWS CloudFormation](https://www.youtube.com/watch?v=bJHHQM7GGro) (AWS re:Invent 2019)
+ [Threat Detection on AWS: An Introduction to Amazon GuardDuty](https://www.youtube.com/watch?v=czsuZXQvD8E) (AWS re:Inforce 2019)

## Additional information


**Python code**

```
import boto3
import os
import json
from botocore.exceptions import ClientError
import cfnresponse
guardduty=boto3.client('guardduty')
cfn=boto3.client('cloudformation')
def lambda_handler(event, context):
    print('Event: ', event)
    if 'RequestType' in event:    
      if event['RequestType'] in ["Create","Update"]:
          enabled=False
          try:  
            response=guardduty.list_detectors()
            if "DetectorIds" in response and len(response["DetectorIds"])>0:
              enabled="AlreadyEnabled"
            elif "DetectorIds" in response and len(response["DetectorIds"])==0:
              cfn_response=cfn.create_stack(
                StackName='guardduty-cfn-stack',
                TemplateBody='{ "AWSTemplateFormatVersion": "2010-09-09",    "Description": "Guard duty creation template",    "Resources": { "IRWorkshopGuardDutyDetector": {  "Type": "AWS::GuardDuty::Detector",    "Properties": {   "Enable": true  }   } } }'
                )
              enabled="True"
          except Exception as e:
              print("Exception: ",e)
          responseData = {}
          responseData['status'] = enabled
          cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID" )
      elif event['RequestType'] == "Delete":
          cfn_response=cfn.delete_stack(
                  StackName='guardduty-cfn-stack')
          cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
```

