Skip to content
Open
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
53 changes: 53 additions & 0 deletions Conformity/Integration/aws-cf-cloudwatch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# conformity-to-cloudwatch

Conformity-to-cloudwatch is an adittional feature to deploy all the required resoruces to send Cloud One Conformity new alerts to a cloudwatch log group, using the native integration that Conformity already has with SNS

# Deployment

To deploy this feature, just download the template found in the repository and deploy it to the AWS cloudformation service.

The template allows you to modify the following two parameters:

#### RetentionPeriod

By default, CloudWatch Logs will store your log data indefinitely. You can change the retention for each Log Group at any time, 90 days is a very common time within company compliance for data retention.

#### LogName

You can customize the log group name where the alerts will be stored

<img width="398" alt="image" src="https://github.com/alejogaci/conformity-to-cloudwatch/assets/37232597/9dcd094f-f2aa-420e-9248-753d671eee7c">

# Outputs LogGroupName

- `TopicArn` SNS Topic ARN to be used in Conformity
- `LogGroupName` Cloud Watch log group where the conformity notifications will be stored

**Note:** Save the TopicArn for later

# Conformity SNS integration

Once deployed, you just have to go to conformity, select the AWS account for which you want to integrate, enter `settings` and then `Update Communication settings`, you should see something like this

<img width="524" alt="image" src="https://github.com/alejogaci/conformity-to-cloudwatch/assets/37232597/b013c8d0-2b61-4bed-aa65-79bb25193ad1">

Go to `configure` under `Amazon SNS` an then click on `Create an Amazon SNS channel` and the following window will appear

<img width="458" alt="image" src="https://github.com/alejogaci/conformity-to-cloudwatch/assets/37232597/0ec8522e-6552-4074-b883-f6b874b3776a">

**Notes:** Enable at least `Automatic notifications` so that every time the bot runs, conformity sends new findings via SNS

Click on `Configure now...` , set the SNS Topic ARN and save changes

# Test the deployment

**Notes:** For this test you must enable `Manual notifications` in the conformity sns channel

Go to any finding in the conformity dashboard, you will see that in the upper right there is an option called `Send via SNS`, click on it to verify that the deployment is working correctly

![image](https://github.com/alejogaci/conformity-to-cloudwatch/assets/37232597/b02b3457-219f-4f73-a3a2-2f3db630a034)

If you check the log group in cloud watch you should see something like this

![image](https://github.com/alejogaci/conformity-to-cloudwatch/assets/37232597/beabbbe7-2f46-4d52-9845-b70a704b683c)

207 changes: 207 additions & 0 deletions Conformity/Integration/aws-cf-cloudwatch/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
AWSTemplateFormatVersion: 2010-09-09
Description: Conformity - Cloudwatch integration via SNS topic


Parameters:

RetentionPeriod:
Type: Number
Description: cloudwatch log retention period
Default: 90
LogName:
Type: String
Description: Log name
Default: notifications

Resources:

ConformityKMSKey:
Type: "AWS::KMS::Key"
Properties:
Description: "CloudConformityEncryptionKey"
KeyPolicy:
Version: "2012-10-17"
Id: "CloudConformityEncryptionKey"
Statement:
- Sid: "Enable Conformity Permissions"
Effect: "Allow"
Principal:
AWS: "arn:aws:iam::717210094962:root"
Action:
- "kms:Encrypt"
- "kms:Decrypt"
- "kms:ReEncrypt*"
- "kms:GenerateDataKey*"
- "kms:DescribeKey"
Resource: "arn:aws:kms:*:*:key/*"

- Sid: "Allow access for Key Administrators"
Effect: "Allow"
Principal:
AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root"
Action:
- "kms:Create*"
- "kms:Describe*"
- "kms:Enable*"
- "kms:List*"
- "kms:Put*"
- "kms:Update*"
- "kms:Revoke*"
- "kms:Disable*"
- "kms:Get*"
- "kms:Delete*"
- "kms:TagResource"
- "kms:UntagResource"
- "kms:ScheduleKeyDeletion"
- "kms:CancelKeyDeletion"
Resource: "arn:aws:kms:*:*:key/*"


ConformityKMSKeyAlias:
Type: "AWS::KMS::Alias"
Properties:
AliasName: !Join ["", ["alias/CloudConformity_",!Ref LogName]]
TargetKeyId: !Ref ConformityKMSKey



ConformitySNSTopic:
Type: "AWS::SNS::Topic"
Properties:
DisplayName: !Ref LogName
KmsMasterKeyId: !Ref ConformityKMSKey
TopicName: !Ref LogName

ConformitySNSTopicPolicy:
Type: "AWS::SNS::TopicPolicy"
Properties:
Topics:
- !Ref ConformitySNSTopic
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: "AllowPublishFromConformity"
Effect: "Allow"
Principal:
AWS: "arn:aws:iam::717210094962:root"
Action:
- "sns:Publish"
Resource: !Ref ConformitySNSTopic

AlertsLogGroup:
Type: "AWS::Logs::LogGroup"
Properties:
LogGroupName: !Join ["", ["/aws", "/lambda", "/conformity_alerts_",!Ref LogName]]
RetentionInDays: !Ref RetentionPeriod


ConformityAlertsLambdaRole:
Type: 'AWS::IAM::Role'
Properties:
RoleName: !Join ["-", [!Ref LogName, "lambda", "alerts","role"]]
Description: "IAM role for lambda setup"
Path: /
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: !Join ["-", [!Ref LogName, "lambda", "alerts","policy"]]
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !GetAtt AlertsLogGroup.Arn
- Effect: Allow
Action:
- sns:Subscribe
- sns:Receive
Resource:
- !Ref ConformitySNSTopic


ConformityAlertsLambda:
Type: "AWS::Lambda::Function"
Properties:
Description: "Lambda to send SNS messages to cloudwatch"
FunctionName: "conformity_alerts_lambda"
Handler: index.lambda_handler
MemorySize: 256
PackageType: "Zip"
Role: !GetAtt ConformityAlertsLambdaRole.Arn
Runtime: python3.9
Timeout: 180
Code:
ZipFile: |
import json
import boto3
import time
import os

def lambda_handler(event, context):
log_name = os.environ['LOG_NAME']
# Create a CloudWatch Logs client
cloudwatch_logs = boto3.client('logs')
# Define the Log Group and Log Stream names
log_group_name = '/aws/lambda/conformity_alerts_'+log_name
log_stream_name = 'alerts'
try:
response = cloudwatch_logs.create_log_stream(
logGroupName=log_group_name,
logStreamName=log_stream_name
)
print("Log stream created successfully.")
except cloudwatch_logs.exceptions.ResourceAlreadyExistsException:
print("Log stream already exists.")
except Exception as e:
print("Error creating log stream:", str(e))

# Put the log message to CloudWatch Logs
cloudwatch_logs.put_log_events(
logGroupName=log_group_name,
logStreamName=log_stream_name,
logEvents=[
{
'timestamp': int(round(time.time() * 1000)),
'message': str(json.loads(event['Records'][0]['Sns']['Message']))
}
]
)
Environment:
Variables:
LOG_NAME: !Ref LogName

ConformityLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref ConformityAlertsLambda
Action: lambda:InvokeFunction
Principal: sns.amazonaws.com
SourceArn: !Ref ConformitySNSTopic

ConformityLambdaSNSSubscription:
Type: AWS::SNS::Subscription
Properties:
TopicArn: !Ref ConformitySNSTopic
Protocol: lambda
Endpoint: !GetAtt ConformityAlertsLambda.Arn

Outputs:
TopicArn:
Value: !Ref ConformitySNSTopic
Description: SNS Topic ARN
LogGroupName:
Value: !Ref AlertsLogGroup
Description: Cloudwatch Log Group