Problem 3: AWS Resource Inspector

Requirements

Use only the following packages:

  • boto3 (AWS SDK for Python)
  • Python standard library modules (json, sys, datetime, argparse, os)

Do not use other AWS libraries, CLI wrappers, or third-party AWS tools beyond boto3.

Create a Python script that lists and inspects AWS resources across your account, providing insight into IAM users, EC2 instances, S3 buckets, and security groups.

Part A: Authentication Setup

Your script must support AWS credential authentication through:

  1. AWS CLI credentials (primary method):

    aws configure
    # OR
    aws configure set aws_access_key_id YOUR_KEY
    aws configure set aws_secret_access_key YOUR_SECRET  
    aws configure set region us-east-1
  2. Environment variables (fallback):

    export AWS_ACCESS_KEY_ID=your_key
    export AWS_SECRET_ACCESS_KEY=your_secret
    export AWS_DEFAULT_REGION=us-east-1

Your script must verify authentication at startup using sts:GetCallerIdentity.

Part B: Required AWS Permissions

Your script needs these permissions (minimum required):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:GetCallerIdentity",
                "iam:ListUsers",
                "iam:GetUser",
                "iam:ListAttachedUserPolicies",
                "ec2:DescribeInstances",
                "ec2:DescribeImages",
                "ec2:DescribeSecurityGroups",
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation",
                "s3:ListBucket"
            ],
            "Resource": "*"
        }
    ]
}

Part C: Script Implementation

Create aws_inspector.py with the following command line interface:

python aws_inspector.py [--region REGION] [--output OUTPUT_FILE] [--format json|table]

Arguments:

  • --region: AWS region to inspect (default: from credentials/config)
  • --output: Output file path (default: print to stdout)
  • --format: Output format - ‘json’ or ‘table’ (default: json)

Part D: Resource Collection

Your script must collect information for these resource types:

1. IAM Users

For each user, collect:

{
    "username": "user-name",
    "user_id": "AIDACKEXAMPLE",
    "arn": "arn:aws:iam::123456789012:user/user-name",
    "create_date": "2025-01-15T10:30:00Z",
    "last_activity": "2025-09-10T14:20:00Z",  # PasswordLastUsed if available
    "attached_policies": [
        {
            "policy_name": "PowerUserAccess",
            "policy_arn": "arn:aws:iam::aws:policy/PowerUserAccess"
        }
    ]
}

2. EC2 Instances

For each instance, collect:

{
    "instance_id": "i-1234567890abcdef0",
    "instance_type": "t3.micro",
    "state": "running",
    "public_ip": "54.123.45.67",
    "private_ip": "10.0.1.100", 
    "availability_zone": "us-east-1a",
    "launch_time": "2025-09-15T08:00:00Z",
    "ami_id": "ami-0abcdef1234567890",
    "ami_name": "Amazon Linux 2023 AMI",
    "security_groups": ["sg-12345678", "sg-87654321"],
    "tags": {
        "Name": "my-instance",
        "Environment": "development"
    }
}

3. S3 Buckets

For each bucket, collect:

{
    "bucket_name": "my-example-bucket",
    "creation_date": "2025-08-20T12:00:00Z",
    "region": "us-east-1",
    "object_count": 47,  # Approximate from ListObjects
    "size_bytes": 1024000  # Approximate total size
}

4. Security Groups

For each security group, collect:

{
    "group_id": "sg-12345678",
    "group_name": "default",
    "description": "Default security group",
    "vpc_id": "vpc-12345678",
    "inbound_rules": [
        {
            "protocol": "tcp",
            "port_range": "22-22",
            "source": "0.0.0.0/0"
        }
    ],
    "outbound_rules": [
        {
            "protocol": "all",
            "port_range": "all",
            "destination": "0.0.0.0/0"
        }
    ]
}

Part E: Output Formats

JSON Format (Default)

{
    "account_info": {
        "account_id": "123456789012",
        "user_arn": "arn:aws:iam::123456789012:user/student",
        "region": "us-east-1",
        "scan_timestamp": "2025-09-16T14:30:00Z"
    },
    "resources": {
        "iam_users": [...],
        "ec2_instances": [...],
        "s3_buckets": [...],
        "security_groups": [...]
    },
    "summary": {
        "total_users": 3,
        "running_instances": 2,
        "total_buckets": 5,
        "security_groups": 8
    }
}

Table Format

AWS Account: 123456789012 (us-east-1)
Scan Time: 2025-09-16 14:30:00 UTC

IAM USERS (3 total)
Username            Create Date          Last Activity        Policies
student-user        2025-01-15           2025-09-10           2
admin-user          2025-02-01           2025-09-15           1

EC2 INSTANCES (2 running, 1 stopped)  
Instance ID          Type        State      Public IP        Launch Time
i-1234567890abcdef0  t3.micro    running    54.123.45.67     2025-09-15 08:00
i-0987654321fedcba0  t3.small    stopped    -                2025-09-10 12:30

S3 BUCKETS (5 total)
Bucket Name              Region      Created       Objects    Size (MB)
my-example-bucket        us-east-1   2025-08-20    47         ~1.0
data-backup-bucket       us-west-2   2025-07-15    234        ~15.2

SECURITY GROUPS (8 total)
Group ID         Name           VPC ID          Inbound Rules
sg-12345678      default        vpc-12345678    1
sg-87654321      web-servers    vpc-12345678    2

Part F: Error Handling

Your script must handle these error conditions gracefully:

  1. Authentication failures: Print clear error message and exit
  2. Permission denied: Skip resource type, log warning, continue
  3. Network timeouts: Retry once, then skip resource
  4. Invalid regions: Validate region exists before proceeding
  5. Empty resources: Handle accounts with no resources of a type

Example error output:

[WARNING] Access denied for IAM operations - skipping user enumeration
[WARNING] No EC2 instances found in us-east-1
[ERROR] Failed to access S3 bucket 'private-bucket': Access Denied

Part G: Testing Script

Create test.sh:

#!/bin/bash

echo "Testing AWS Inspector Script"
echo "============================"

# Test 1: Verify authentication
echo "Test 1: Authentication check"
python aws_inspector.py --region us-east-1 --format json > /dev/null
if [ $? -eq 0 ]; then
    echo "[PASS] Authentication successful"
else
    echo "[FAIL] Authentication failed"
    exit 1
fi

# Test 2: JSON output format
echo "Test 2: JSON output format"
python aws_inspector.py --region us-east-1 --format json --output test_output.json
if [ -f "test_output.json" ]; then
    python -m json.tool test_output.json > /dev/null
    if [ $? -eq 0 ]; then
        echo "[PASS] Valid JSON output generated"
    else
        echo "[FAIL] Invalid JSON output"
    fi
    rm test_output.json
else
    echo "[FAIL] Output file not created"
fi

# Test 3: Table output format
echo "Test 3: Table output format"
python aws_inspector.py --region us-east-1 --format table | head -10
echo "[PASS] Table format displayed"

# Test 4: Invalid region handling
echo "Test 4: Invalid region handling"
python aws_inspector.py --region invalid-region 2>/dev/null
if [ $? -ne 0 ]; then
    echo "[PASS] Invalid region properly rejected"
else
    echo "[FAIL] Invalid region accepted"
fi

echo ""
echo "Testing complete. Review output above for any failures."

Deliverables

Your problem3/ directory must contain:

problem3/
├── aws_inspector.py
├── requirements.txt
└── test.sh

Create requirements.txt:

boto3>=1.26.0

Validation

We will test your implementation by:

  1. Running with valid AWS credentials in multiple regions
  2. Testing both JSON and table output formats
  3. Verifying all resource types are collected with correct fields
  4. Testing error handling with restricted permissions
  5. Checking output file generation and format validity
  6. Testing with accounts containing no resources
  7. Validating authentication error handling

Your script must complete scanning within 60 seconds for accounts with moderate resource counts (< 50 resources total) and handle rate limiting gracefully.