AWS Inventory
Overview
AWS Inventory is a pull-based source that takes a periodic snapshot of an AWS account's assets and identities and sends one record per resource into a Praxis pipeline. These records are entity context: they describe what exists (servers, networks, users, roles), not what happened. A SIEM uses them to enrich events.
| Resource | AWS API | aws.inventory.resource → Google SecOps log type |
|---|---|---|
| EC2 instances: IDs, private/public IPs, DNS names, tags, state, security groups, network interfaces, instance profile | ec2:DescribeInstances (per region) | ec2_instance → AWS_EC2_INSTANCES |
| VPCs: CIDR blocks, state, default flag, DHCP options, tags | ec2:DescribeVpcs (per region) | ec2_vpc → AWS_EC2_VPCS |
| IAM users: groups, attached and inline policies, tags, permissions boundary, password last used | iam:GetAccountAuthorizationDetails + iam:ListUsers | iam_user → AWS_IAM |
| IAM roles: trust policy, policies, tags, role last used, description, max session duration | iam:GetAccountAuthorizationDetails + iam:ListRoles | iam_role → AWS_IAM |
| IAM groups: policies and member users | iam:GetAccountAuthorizationDetails | iam_group → AWS_IAM |
Like other sources, AWS Inventory does not set a Google SecOps log type. Every record carries the attribute aws.inventory.resource; set the log type from it with Google SecOps Standardization. See Sending to Google SecOps.
Supported types: Logs
Supported platforms: Linux, Windows, macOS
Minimum collector version: 0.5.59
Authentication
The credential is optional.
| Credential type | When to use |
|---|---|
AWS (aws), Assume Role | Recommended. The collector assumes a read-only IAM role in the target account, starting from its own host credentials (instance profile, environment, or a profile). Short-lived credentials, no stored keys. |
AWS (aws), Access Keys | Quick setup or testing. A read-only IAM user's access key ID and secret. |
AWS IMDS (awsimds) | The collector runs on an EC2 instance whose instance profile has the permissions below. |
| None | The collector uses the AWS SDK default chain on its host: environment variables, shared config, EKS IRSA / Pod Identity, ECS task role, then the EC2 instance profile. |
Required IAM permissions
All calls are read-only. The AWS managed policy SecurityAudit covers every one. The minimal policy is:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"ec2:DescribeRegions",
"ec2:DescribeInstances",
"ec2:DescribeVpcs",
"iam:GetAccountAuthorizationDetails",
"iam:ListUsers",
"iam:ListRoles"
],
"Resource": "*"
}]
}
ec2:DescribeRegionsis only needed with Collect From All Enabled Regions.- If
iam:ListUsersoriam:ListRolesis denied, users and roles are still collected, just withoutPasswordLastUsed(users) orDescription/MaxSessionDuration(roles). - The account ID comes from
sts:GetCallerIdentity, which needs no permission.
Basic configuration
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
region | string | Yes | us-east-1 | Home region. Used for STS and IAM calls (IAM is global), and the only region EC2 resources are read from when no other regions are set. |
resources | list | No | all five | Any of ec2_instances, ec2_vpcs, iam_users, iam_roles, iam_groups. |
all_regions | bool | No | false | Collect EC2 instances and VPCs from every region enabled for the account. Opt-in regions that are not enabled are skipped. |
regions | list | No | home region | Regions to collect EC2 instances and VPCs from, e.g. us-east-1, eu-west-1. Hidden when all_regions is on. |
mode | scheduled | manual | No | scheduled | scheduled: take a snapshot every interval. manual: take a snapshot only with Fetch Inventory Now. See Scheduled and manual fetching. |
interval | integer (seconds) | No | 21600 (6h) | Time between full snapshots in scheduled mode. Minimum 900 (15 minutes). Hidden in manual mode. |
sync_request | integer | No | 0 | Fetch Inventory Now: shown and used in manual mode only. |
format | secops | aws | No | secops | Record body shape. See Record format. |
Scheduled and manual fetching
Works the same way as Okta's user context fetching.
| Fetch Mode | When snapshots run |
|---|---|
| scheduled (default) | At start-up, then every Snapshot Interval. The time of the last snapshot is saved on the collector, so a restart or redeploy waits out the rest of the interval instead of fetching again. |
| manual | Only when you raise Fetch Inventory Now. Nothing runs on a timer. |
Fetching on demand
- Set Fetch Mode to
manual. - In Fetch Inventory Now, enter a number higher than the current one (for example
1→2). - Deploy. The collector takes one full snapshot.
The completed number is saved on the collector, so a restart or a later config change with the same number does not fetch again. If the snapshot fails, it stays pending and is retried. Raise the number again whenever you want a fresh snapshot.
Record format
Each resource becomes one log record whose body is that resource's JSON.
secops(default): matches what the Google SecOps native AWS feeds produce, which is what theAWS_EC2_INSTANCES,AWS_EC2_VPCSandAWS_IAMdefault parsers read. The AWS fields are kept, with Go-style initialisms and the EC2 XML set names:InstanceId→InstanceID,PrivateIpAddress→PrivateIPAddress,PublicIpAddress→IPAddress,Tags→TagSet,NetworkInterfaces→NetworkInterfaceSet, andReservation.Instances→InstancesSet. Instance records also carrycollection_time. IAM groups use theiam:GetGroupshape, with the group underGroupand its members underUsers.aws: the AWS API JSON unchanged. Use this for destinations other than Google SecOps.
In both formats, unset fields are left out and IAM policy documents (which AWS returns URL-encoded) are decoded to plain JSON.
| Field | OTel destination |
|---|---|
| (resource JSON) | LogRecord.Body (string) |
| (snapshot start time) | LogRecord.Timestamp: the record describes the resource as of that snapshot |
| (resource kind) | LogRecord.Attributes["aws.inventory.resource"]: ec2_instance, ec2_vpc, iam_user, iam_role, iam_group |
| Instance / VPC / user / role / group ID | LogRecord.Attributes["aws.resource.id"] |
| IAM ARN | LogRecord.Attributes["aws.resource.arn"] |
| (constant) | Resource.Attributes["cloud.provider"] = "aws" |
| Account ID | Resource.Attributes["cloud.account.id"] |
| Region (EC2 resources only) | Resource.Attributes["cloud.region"] |
Sending to Google SecOps
One AWS Inventory source produces records for three Google SecOps log types. Between the source and the Google SecOps destination, add one Google SecOps Standardization processor per log type, each with a condition:
| Log Type | Condition |
|---|---|
AWS_EC2_INSTANCES | log.attributes["aws.inventory.resource"] == "ec2_instance" |
AWS_EC2_VPCS | log.attributes["aws.inventory.resource"] == "ec2_vpc" |
AWS_IAM | IsMatch(log.attributes["aws.inventory.resource"], "^iam_") |
Each processor sets the log type only on the records its condition matches, so the three can run one after another. Keep Record Format on secops so the record bodies match the Google SecOps parsers.
Example configuration
{
"region": "us-east-1", // required: home region
"resources": ["ec2_instances", "ec2_vpcs", "iam_users", "iam_roles", "iam_groups"],
"all_regions": true, // default: false
"mode": "scheduled", // default: scheduled (or "manual")
"interval": 21600, // default: 21600 (6h), minimum 900; scheduled mode only
"sync_request": 0, // manual mode: raise and deploy to fetch now
"format": "secops" // default: secops
}
Operational notes
- Snapshots, not streaming. Every snapshot re-sends the whole inventory. Pick an interval that matches how fast your estate changes: shorter for autoscaling fleets, longer for static ones.
- Partial failures. If one region or resource fails (for example a region blocked by an SCP), the others are still sent and the error appears in the source's error metric. Only a snapshot where everything failed is retried, after 5 minutes and then with backoff up to 1 hour.
- Multiple accounts. One source reads one account. Add a source per account, each with its own Assume Role credential.
- Rate limits. Requests are paginated at the API maximum (1000 per page) as AWS recommends, and throttled calls are retried by the AWS SDK.
Metrics
| Metric Name | Description |
|---|---|
prx_src_records_received_total{signal="logs"} | Log records emitted, one per resource. |
prx_src_bytes_received_total | Bytes of the emitted record bodies. |
prx_src_pipeline_latency_seconds | Arrival → downstream handoff. |
prx_src_errors_total{reason} | AWS API or snapshot failures by reason: auth, permission_denied, timeout, io. |
prx_src_records_dropped_total{reason="backpressure"} | Records dropped because the downstream pipeline refused them. |