1. Forwarding CloudWatch Logs to External SIEM Systems

    TypeScript

    Forwarding CloudWatch Logs to an external SIEM (Security Information and Event Management) system is a common practice for aggregating and analyzing logs for security insights. To achieve this, you'll create a CloudWatch Log Group and Log Stream in AWS. Then, you'll define a Log Destination that has the external SIEM system as its target. To wire everything together, you'll need to set an IAM role with the necessary permissions, and create a subscription filter on the CloudWatch Log Group to send logs to the Log Destination.

    Below, you'll see a Pulumi program written in TypeScript that sets up these resources. The program assumes you have the external SIEM system endpoint available, and that you have the necessary permissions to deploy resources in AWS.

    Here is a breakdown of how we will proceed:

    1. Log Group and Log Stream: These are the basic units of CloudWatch Logs. A Log Group contains Log Streams, which are sequences of log events.
    2. Log Destination: This represents the external SIEM system where you want to forward your logs.
    3. IAM Role and Policy: The IAM role and policy grant CloudWatch Logs the permission to forward logs to the SIEM system.
    4. Subscription Filter: This defines the pattern to use for filtering the logs and also specifies the Log Destination that will receive the logs.

    Let's implement this:

    import * as aws from "@pulumi/aws"; // Assume the external SIEM system's ARN is already available const externalSiemSystemArn = "arn:aws:siem:::endpoint"; // Please replace this with your actual external SIEM endpoint ARN // Create a new IAM role for CloudWatch Logs to access the SIEM system const cwLogRole = new aws.iam.Role("cwLogRole", { assumeRolePolicy: JSON.stringify({ Version: "2012-10-17", Statement: [{ Action: "sts:AssumeRole", Effect: "Allow", Principal: { Service: "logs.amazonaws.com", }, }], }), }); // Attach a policy to the IAM role created above const cwLogPolicy = new aws.iam.RolePolicy("cwLogPolicy", { role: cwLogRole.id, policy: JSON.stringify({ Version: "2012-10-17", Statement: [{ Action: [ "logs:CreateLogStream", "logs:PutLogEvents", "logs:PutDestination", ], Effect: "Allow", Resource: "*", // Scope down this resource to your needs }], }), }); // Create the CloudWatch Log Group const logGroup = new aws.cloudwatch.LogGroup("my-log-group"); // Create the CloudWatch Log Stream const logStream = new aws.cloudwatch.LogStream("my-log-stream", { logGroupName: logGroup.name, // Reference to the Log Group created above }); // Create the CloudWatch Log Destination const logDestination = new aws.cloudwatch.LogDestination("my-destination", { roleArn: cwLogRole.arn, // The IAM role ARN with permissions for CloudWatch Logs targetArn: externalSiemSystemArn, // The ARN of the external SIEM endpoint }); // Create a CloudWatch Logs Subscription Filter const logSubscriptionFilter = new aws.cloudwatch.LogSubscriptionFilter("my-subscription-filter", { logGroupName: logGroup.name, // Reference to the Log Group created above destinationArn: logDestination.arn, // Reference to the Log Destination created above filterPattern: "", // Supply a filter pattern as per your needs roleArn: cwLogRole.arn, // The IAM role ARN with permissions for CloudWatch Logs }); // Export the names of the resources export const logGroupName = logGroup.name; export const logGroupArn = logGroup.arn; export const logStreamName = logStream.name; export const logDestinationArn = logDestination.arn; export const logSubscriptionFilterName = logSubscriptionFilter.name;

    In this program:

    • We create an IAM role with the necessary permissions to push logs to the SIEM system and a policy that outlines those permissions.
    • We make a new CloudWatch Log Group and Stream, which is where our logs will be aggregated initially.
    • The Log Destination is then set up, specifying the ARN of the external SIEM system.
    • Finally, the Subscription Filter pipes logs from the Log Group to the Log Destination.

    Please ensure you replace externalSiemSystemArn with the actual ARN of your external SIEM endpoint and scope the resource permissions in the IAM policy according to your organizational security policies.

    To run this Pulumi program, you need to have the Pulumi CLI installed and configured with your AWS credentials. Save the above code to an index.ts file within a Pulumi project directory.

    Ensure to install the necessary dependency @pulumi/aws by running npm install @pulumi/aws in the same directory as your index.ts file. You can then run pulumi up to deploy these resources to your AWS account.