Skip to content

Commit

Permalink
Removed need for hosting integration files in more than one bucket
Browse files Browse the repository at this point in the history
* Introduced parameter groups in the CF tempÃlate

* Grouped parameters and made metric statistics ingester and metric ingester optional

* Fixed error in making metric ingesters optional

* Made it possible to decide whether to omit creating a cloudtrail and a s3 bucket in the main cf file - the other should now be redundant

* Deleted cloudformation-no-trail

* Made the bucket for the lambda files a parameter and deleted the cloudformation_test file

* Made it possible for users to choose their own s3 bucket to retrieve lambda files from

* Added resources to copy zip file content from one bucket

* Updated inline code for lambda zil copier and used new bucket location for ingester

* Updated s3bucket location for lambdas to find code

* Added depends on for the lambdas using zip copier and added log group retention setting for it

* Added condition for creating the copy zip resources

* Removed option to set custom s3 bucket location - will hopefully add later

* Removed override lambda files location parameter

* Simplified deploy script

* Bumped the version (manually) and updated deploy scripts

* Added S3 bucket location as a parameter.

* Used logger for print in lambda zip code

* Added some information regarding how the integration works in the readme.

* Updated changelog.

* Structued the changelog update

* Added the S3 key for the lambda code files as a parameter, updated the parameter descriptions, and removed the option for versions

* Updated the changelog

* Removed versioning deployment scripts and Makefile

* Added comment for CopyZipLambda

* Changed name from prefix to key

* Updated bucket name to logscale

* Added comment with where copy zip is from

* Updated name related to zip and bucket to be logscale

* Updated the README to use LogScale

* Replaced Humio with LogScale in CF file

* Updated relevant names from Humio to LogScale in helper.py

* Updated names in logs_backfiller to logscale

* Updated relevant names to LogScale in logs_ingester.py

* Updated relevant names to LogScale in logs_subscriber.py

* Updated relevant names to LogScale in metric .py files

* Updated CopyZipLambda file with function descriptions

* Updated name

* Added name update in ChangeLog

* Fixed error in CopyZipLambda and updated deploy scripts with logscale bucket

* Re-added versioning to package name, so that update is possible

* Cleaned up permissions

* Updated changelog

* Updated the readme with section regarding adding a new region

* Fixed minor mistake in changelog

* Updated date for last changelog entry

* Fixed errors in changelog

* Fixed comment in copyziplambda

* Small changes to the readme

* Changed to lowercase lambda and removed outcommented deploy commands

* Small update in wording

* Added most important change in the changelog overview

Co-authored-by: Zanna <suzanna.volkov@crowdstrike.com>
  • Loading branch information
Suzanna-Volkov and Zanna authored Jan 6, 2023
1 parent bcbd866 commit 9c3b9d4
Show file tree
Hide file tree
Showing 16 changed files with 496 additions and 1,412 deletions.
9 changes: 3 additions & 6 deletions .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.2.2
current_version = 2.0.0
commit = True
tag = True
message = Bump version: {current_version} → {new_version}
Expand All @@ -12,14 +12,11 @@ replace = v{new_version}
search = v{current_version}
replace = v{new_version}

[bumpversion:file:cloudformation.json]
[bumpversion:file:deploy-using-profile.sh]
search = v{current_version}
replace = v{new_version}

[bumpversion:file:cloudformation-no-trail.json]
[bumpversion:file:cloudformation.json]
search = v{current_version}
replace = v{new_version}

[bumpversion:file:cloudformation-test.json]
search = v{current_version}
replace = v{new_version}
32 changes: 30 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
# Changelog

## 2.0.0 (2023-01-06)
Updated naming where possible to LogScale.
Added functionality to only support hosting the integration files in one bucket in one region.
Added functionality to choose which S3 bucket and S3 key should be used for retrieving the code files for the AWS Lambda functions.
Removed the option to choose older versions of the integration.
Removed unnecessary permissions for the CloudFormation resources.

### Added
- Introduced parameter groups in the CF template.
- Added parameter for setting the S3 bucket containing the lambda code files.
- Added parameter for setting the S3 key in the S3 bucket containing the lambda code files.
- Created resources for copying the lambda code files from the specified S3 bucket, so that it is no longer required to create a new bucket in each region supported. The default S3 bucket hosted by LogScale is named _logscale-public-us-east-1_.
- Added a parameter for determining whether the CloudTrail and S3 bucket for autosubscription should be created, which also made it possible to delete the additional CF template.
- Made it possible for users to set which S3 bucket and S3 key they want to retrieve the lambda code files from, which also made it possible to delete the CF template for testing.

### Changed
- Made metric ingester and metric statistics ingester creation optional.
- Updated the README of the project to contain a section for how the integration works, how versioning works, and how to support new regions.
- Updated the deployment scripts.
- Replaced 'Humio' with 'LogScale' where possible.
- Merged permissions regarding the subscriber into one.

### Removed
- Removed the CF template with no trail.
- Removed the CF template for testing.
- Removed the parameter related to versions, so that there is only the newest version of the code uploaded.
- Removed unnecessary permissions for some of the AWS Lambdas.

## 1.2.2 (2022-08-30)
Added additional login at ingest error
Added additional login at ingest error.

### Added
- Logging for when ingest into Humio fails
- Logging for when ingest into Humio fails.

## 1.2.1 (2021-01-12)
Performance regression fix.
Expand Down
92 changes: 92 additions & 0 deletions CopyZipLambda.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# This file contains the inline code for the lambda named "LogScaleCloudWatchCopyZipLambda".
# This code is copied directly into the CF resource, and thus this file is only to have an overview.
# This code is based on the inline code from the following GitHub library https://github.com/aws-quickstart/quickstart-examples/blob/main/patterns/LambdaZips/example.yaml.

import json
import logging
import os
import threading
import boto3
import cfnresponse

level = os.getenv("log_level", "INFO")
logging.basicConfig(level=level)
logger = logging.getLogger()
logger.setLevel(level)


def copy_objects(source_bucket, dest_bucket, key):
"""
Copy key from source bucket to destination bucket.
:param source_bucket: S3 bucket containing zip file with code.
:param dest_bucket: S3 bucket where zip file with code should be copied to.
:param key: File name to be copied.
:return: None
"""
s3 = boto3.client('s3')
copy_source = {
'Bucket': source_bucket,
'Key': key
}
logger.debug(('copy_source: %s' % copy_source))
logger.debug(('dest_bucket = %s' % dest_bucket))
logger.debug(('key = %s' % key))
s3.copy_object(CopySource=copy_source, Bucket=dest_bucket, Key=key)


def delete_objects(bucket, key):
"""
Delete a bucket and its objects.
:param bucket: S3 bucket to be deleted.
:param key: S3 key to object that should be deleted.
:return:
"""
s3 = boto3.client('s3')
objects = {'Objects': [{'Key': key}]}
s3.delete_objects(Bucket=bucket, Delete=objects)


def timeout(event, context):
"""
Send a response to the custom resource if it times out.
:param event: Event data from the lambda.
:param context: Lambda context object.
:return: None
"""
logging.error('Execution is about to time out, sending failure response to CloudFormation')
cfnresponse.send(event, context, cfnresponse.FAILED, {}, None)


def handler(event, context):
"""
Lambda handler that will copy the zip file from the source bucket to the
destination bucket.
It will send a failure to CloudFormation if the function is going to timeout.
:param event: Event data from caller.
:param context: Lambda context object.
:return: None
"""
timer = threading.Timer((context.get_remaining_time_in_millis()
/ 1000.00) - 0.5, timeout, args=[event, context])
timer.start()
logger.debug(('Received event: %s' % json.dumps(event)))
status = cfnresponse.SUCCESS
try:
source_bucket = event['ResourceProperties']['SourceBucket']
dest_bucket = event['ResourceProperties']['DestBucket']
key = event['ResourceProperties']['Key']
if event['RequestType'] == 'Delete':
delete_objects(dest_bucket, key)
else:
copy_objects(source_bucket, dest_bucket, key)
except Exception as e:
logging.error('Exception: %s' % e, exc_info=True)
status = cfnresponse.FAILED
finally:
timer.cancel()
cfnresponse.send(event, context, status, {}, None)
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
build: clean target copy dependencies target/cloudwatch2humio.zip
build: clean target copy dependencies target/cloudwatch2logscale.zip

clean:
rm -rf target/*
Expand All @@ -12,8 +12,8 @@ copy:
dependencies:
pip3 install -r requirements.txt -t target

target/cloudwatch2humio.zip:
(cd target/ && zip -r ../target/v1.2.2_cloudwatch2humio.zip * )
target/cloudwatch2logscale.zip:
(cd target/ && zip -r ../target/v2.0.0_cloudwatch2logscale.zip * )

clean:
rm -rf target
Expand Down
69 changes: 49 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# CloudWatch2Humio
This repository contains a set of lambdas for shipping Cloudwatch Logs and Metrics to Humio.
# CloudWatch2LogScale
This repository contains a CloudFormation template as well as Python code files for setting up an integration
which is used for shipping Cloudwatch Logs and Metrics to LogScale.

The full documentation regarding installing and using this integration can be found in the official [humio library](https://library.humio.com/reference/log-formats/amazon-cloudwatch/).
The full documentation regarding installing and using this integration can be found in the official
[humio library](https://library.humio.com/reference/log-formats/amazon-cloudwatch/).

## Vision
The vision for the CloudWatch to Humio integration, is to create a bridge between Humio and AWS, which enables users to ingest logs and metrics from the AWS CloudWatch service, so that Humio can be used to manage this data.
The vision for the CloudWatch to LogScale integration, is to create a bridge between LogScale and AWS,
which enables users to ingest logs and metrics from the AWS CloudWatch service,
so that LogScale can be used to manage this data.

## Governance
This project is maintained by employees at Humio ApS.
As a general rule, only employees at Humio can become maintainers and have commit privileges to this repository.
This project is maintained by employees at CrowdStrike.
As a general rule, only employees at CrowdStrike can become maintainers and have commit privileges to this repository.
Therefore, if you want to contribute to the project, which we very much encourage, you must first fork the repository.
Maintainers will have the final say on accepting or rejecting pull requests.
As a rule of thumb, pull requests will be accepted if:
Expand All @@ -18,25 +22,50 @@ As a rule of thumb, pull requests will be accepted if:
* The contribution is of a quality comparable to the rest of the project

The maintainers will attempt to react to issues and pull requests quickly, but their ability to do so can vary.
If you haven't heard back from a maintainer within 7 days of creating an issue or making a pull request, please feel free to ping them on the relevant post.
If you haven't heard back from a maintainer within 7 days of creating an issue or making a pull request ,
please feel free to ping them on the relevant post.

Maintainers will also be in charge of both versioning and publishing future releases of the project. This includes adding versioning tags and adding to the changelog file.
Maintainers will also be in charge of both versioning and publishing future releases of the project.
This includes adding versioning tags and adding to the changelog file.

The active maintainers involved with this project include:

* [Suzanna Volkov](https://github.com/Suzanna-Volkov)

## CloudFormation Files
There are two versions of the CloudFormation file; one which creates a CloudTrail with a S3 bucket for log storage,
and one which does not create these resources.
The reason for this is that every AWS account only allows for one free CloudTrail,
and adding another will therefore be an additional cost for setting up this integration if one is already present.
By introducing two versions of the CloudFormation file,
it is possible for the user to choose whether they want to create a CloudTrail specifically to be used with this integration,
or to use a one which already exists.
## How this integration works
The integration consists of a CloudFormation template and some Python code files used for lambda functions.
The lambda code files are zipped and uploaded to a public S3 bucket hosted by LogScale.
When creating a CloudStack using this CloudFormation template,
some additional helper resources are created to help copy the lambda code files from the S3 bucket hosting the
files to a newly created S3 bucket in the user's AWS environment.
This is so that we do not have to create buckets in each supported region as the CloudFormation has a
restriction that it can only retrieve lambda code files from a bucket located in the same region as the stack.

***It is thus required when creating a stack using the "no-trail" CloudFormation file that an existing CloudTrail with "management events" enabled already to be present for the account!***
When all the resources are created, the lambda functions will start sending logs to the LogScale host,
which was determined during setup.
Chosen log groups are subscribed to, and whenever new logs arrive, these will be forwarded to LogScale.
This means that existing logs will not be forwarded to LogScale using this integration.
To get existing logs into LogScale another approach is required, which will probably include manually downloading
the existing logs and then sending them to LogScale using some sort of shipper.

The CloudTrail is used by the integration for discovering new log groups in CloudWatch,
which makes it possible for the integration to automatically subscribe to these when they appear.
This is only done if the parameter `EnableCloudWatchLogsAutoSubscription` is set to **true**.
## Versioning
Versioning is used for the ZIP package containing the deployment files.
Versioning of the deployment package is required to make it possible to update an already installed
integration's code files.
A CloudStack will only update its files if the name changes, so you cannot use a file with the
same name as is already used to update with as it won't be recognized as a change.
So to force CloudStack to run an update, the deployment package name needs to be changed.
This means that only one file version is necessary to maintain in the public S3 bucket,
but the name needs to be updated every time there are new changes to the code files.

A flow can be setup where older versions are deleted when a new one is uploaded, this does not yet exist.

It is thus not necessary to make a new release of the integration unless the Python files are changed,
however, changes to the CloudFormation file will still be included in the CHANGELOG. Therefore,
version updates has happened whenever there are changes pushed to the GitHub repository to keep these
two numbers aligned.

## Adding new regions
The most common request from users is that a new region be supported. Since the move to one bucket in one region,
it is no longer necessary to add new buckets, and thus this code does not need any updates. To support a new region
there simply needs to be added a link in the documentation.
Loading

0 comments on commit 9c3b9d4

Please sign in to comment.