Skip to content

Prerequisites

  • projectx-prod-vpc has been created with subnets configured.
  • projectx-prod-jumpbox EC2 instance exists and is accessible.
  • AWS CLI configured with appropriate credentials.
  • Your AWS username for the bucket naming convention.
  • project-x-sec-box configured with Wazuh.
  • S3 security datalake bucket has been created and is receiving logs from CloudTrail and VPC Flow Logs.

Note

This guide is written for Wazuh version 4.9.2. UI elements and navigation paths may differ in other versions.

Network Topology

Base Layout
(Click to zoom)

Overview

What is Index State Management (ISM)?

Index State Management (ISM) is a feature in Wazuh (backed by OpenSearch) that allows you to automate routine index management tasks. ISM policies can automatically transition indices through different states based on age, size, or other conditions.

👉 For this guide, we'll create an ISM policy that automatically deletes indices older than 14 days to manage storage limitations on our VM.

Create S3 IAM User for Wazuh

Before configuring Wazuh to ingest logs from your S3 datalake, we need to create an IAM user with appropriate permissions to read from the S3 bucket. This user will be used by Wazuh to access and retrieve log files.

Open the IAM service in the AWS Console.

In the left navigation pane, select Users.

Click Create user.

Configure User Details

User Name

  • User name: projectx-wazuh-s3-user

👉 Use a descriptive name that indicates this user is for Wazuh S3 access.

Set Permissions

Select Attach policies directly.

Click Create policy.

Create Policy
(Click to zoom)

Configure Policy

In the policy editor, select the JSON tab.

Paste the following policy, replacing [AWS-BUCKET-NAME] with your actual S3 bucket name (e.g., projectx-prod-datalake-[username]):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "WazuhS3Access",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::[AWS-BUCKET-NAME]/*",
                "arn:aws:s3:::[AWS-BUCKET-NAME]"
            ]
        }
    ]
}

👉 Replace [AWS-BUCKET-NAME] with your S3 bucket name. For example, if your bucket is projectx-prod-datalake-johnsmith, the ARN would be arn:aws:s3:::projectx-prod-datalake-johnsmith.

👉 Security Note: This policy grants read-only access (GetObject and ListBucket) to the S3 bucket. This is sufficient for Wazuh to read log files but prevents modification or deletion.

Click Next.

Name the Policy

  • Policy name: projectx-wazuh-s3-read-policy

  • Description: Allows Wazuh to read log files from S3 datalake bucket

Click Create policy.

Policy Created
(Click to zoom)

Attach Policy to User

Navigate back to the user creation page.

In the Set permissions section, click the refresh icon or search for projectx-wazuh-s3-read-policy.

Select the policy you just created.

Attach Policy
(Click to zoom)

Click Next.

Review and Create User

Review the user configuration:

  • User name: projectx-wazuh-s3-user
  • Permissions: projectx-wazuh-s3-read-policy

Click Create user.

User Created
(Click to zoom)

Create Access Keys

After the user is created, you'll need to create access keys for programmatic access.

Click on the user name projectx-wazuh-s3-user.

Navigate to the Security credentials tab.

Scroll down to Access keys.

Click Create access key.

Select Application running outside AWS as the use case.

👉 This use case is appropriate for Wazuh running on an EC2 instance or on-premises server.

Click Next.

Click Create access key.

Save Credentials

👉 Important: Copy both the Access key ID and Secret access key immediately. The secret access key will only be shown once and cannot be retrieved later.

👉 Security Best Practice: Store these credentials securely. You'll need them when configuring Wazuh to connect to S3. Consider using AWS Secrets Manager or a secure password manager.

Click Done.

Verify User Configuration

Navigate back to IAMUsers.

Select projectx-wazuh-s3-user.

Verify that:

  • The user has the projectx-wazuh-s3-read-policy attached
  • Access keys have been created (you'll see "2" under Access keys if you created one)

You now have an IAM user with S3 read permissions that Wazuh can use to access your security datalake bucket.

Install and Configure AWS CLI

To enable Wazuh to access your S3 bucket, we need to install the AWS CLI on the [project-x-sec-box] VM and configure it with the IAM user's access keys.

Connect to project-x-sec-box

Install AWS CLI

Update the package list:

sudo apt update

Install the AWS CLI:

sudo apt install awscli -y

👉 The -y flag automatically answers "yes" to prompts during installation.

Verify the installation:

aws --version

You should see output showing the AWS CLI version (e.g., aws-cli/2.x.x).

AWS CLI Version
(Click to zoom)

Configure AWS Credentials

Configure the AWS CLI with the access keys from the IAM user you created earlier.

root permissions are required for Wazuh <wodle> integrations to work.

Change to the root user first.

sudo su

Run the AWS configure command:

aws configure

You will be prompted for the following information:

AWS Access Key ID

Enter the Access key ID you saved when creating the IAM user:

AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE

👉 Paste the Access key ID you copied from the IAM user creation step.

AWS Secret Access Key

Enter the Secret access key:

AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

👉 Paste the Secret access key you saved. The characters will not be displayed as you type for security reasons.

Default Region Name

Enter your AWS region (e.g., us-east-2):

Default region name [None]: us-east-2

👉 Use the same region where your S3 bucket is located.

Default Output Format

Press Enter to accept the default JSON format, or specify json:

Default output format [None]: json

Configure AWS Profile for Wazuh

Wazuh uses the AWS profile named default by default. The credentials you just configured are stored in the default profile.

Verify the credentials are stored correctly:

cat ~/.aws/credentials

You should see:

[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

👉 The credentials file is located at ~/.aws/credentials for the current user. If Wazuh runs as a different user, you may need to configure credentials for that user as well.

Check the AWS config file:

cat ~/.aws/config

You should see:

[default]
region = us-east-2
output = json

Access Wazuh Dashboard

Connect to [project-x-sec-box]

Log in with your Wazuh credentials.

👉 If you don't remember your credentials, you can retrieve them from the wazuh-passwords.txt file on the Wazuh server.

Create Index State Management Policy

ISM policies automate index lifecycle management. We'll create a policy that automatically deletes indices starting from the default wazuh-alerts-* index after they reach 14 days of age. This is to preserve space on our VM.

In the Wazuh Dashboard, click the hamburger menu (☰) in the top left corner.

Select Indexer ManagementIndex Management.

ISM Policies
(Click to zoom)

Click Create policy.

Configure Policy Details

Basic Information

  • Policy ID: 14day-policy

👉 Policy IDs must be unique and cannot contain spaces or special characters.

  • Description: Automatically delete log indices after 14 days.

Click Create.

Policy Details
(Click to zoom)

ISM Template

Under ISM Templates, select Add Template.

Add wazuh-alerts-* as the Index pattern to match on.

Policy Details
(Click to zoom)

Configure Policy States

Configure States

ISM policies start with a default state or initial state. We will start with a initial state of default which will do nothing until we reach 14 days. Then we'll configure a state called delete to transition to a delete state after 14 days.

In the States section, select Add state.

Create Default State

  • State name: default

  • Actions: Leave empty.

  • Transitions: Minimum index age is 14d

Policy Details
(Click to zoom)

Click Save.

Create Delete State

Select Add state again.

  • State name: delete

  • Order: Add after default

  • Actions: Delete

  • Transitions: Leave empty.

Click Save.

Policy Details
(Click to zoom)

Navigate back to the default state.

Edit the Transition to go to the delete stage.

Policy Details
(Click to zoom)

You should now have two states.

Policy Details
(Click to zoom)

Click Create to create the ISM policy.

Navigating back to State management policies, you will see the 14day-policy ISM. This will apply to all indices in the wazuh-alerts-* index pattern, which is where all of our logs are being sent to.

Policy Details
(Click to zoom)

Alternative: View JSON Editor

This is what your ISM policy should be in JSON format, if you would like to double check or configured with "View JSON".

{
    "id": "14day-policy",
    "seqNo": 232,
    "primaryTerm": 1,
    "policy": {
        "policy_id": "14day-policy",
        "description": "Automatically delete log indices after 14 days.",
        "last_updated_time": 1764539879054,
        "schema_version": 21,
        "error_notification": null,
        "default_state": "default",
        "states": [
            {
                "name": "default",
                "actions": [],
                "transitions": [
                    {
                        "state_name": "delete",
                        "conditions": {
                            "min_index_age": "14d"
                        }
                    }
                ]
            },
            {
                "name": "delete",
                "actions": [
                    {
                        "retry": {
                            "count": 3,
                            "backoff": "exponential",
                            "delay": "1m"
                        },
                        "delete": {}
                    }
                ],
                "transitions": []
            }
        ],
        "ism_template": [
            {
                "index_patterns": [
                    "wazuh-alerts-*"
                ],
                "priority": 0,
                "last_updated_time": [timestamp]
            }
        ]
    }
}

👉 Timestamp is a sequence of numbers.

Success!

These configurations will help you organize and manage all of our logs as they're ingested. Now when we add more data sources from the S3 datalake into Wazuh, they will automatically be rotated to deletion through the ISM policy to maintain storage.