Documentation Index
Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
AWS Inspector is an automated security assessment service that helps you improve the security and compliance of applications deployed on AWS. It automatically assesses applications for vulnerabilities, exposure, and deviations from best practices. Think of Inspector as a continuous vulnerability scanner that knows your infrastructure context. Unlike generic CVE scanners, Inspector combines vulnerability data with network reachability analysis — a critical CVE on an instance that has no internet-facing ports is lower priority than the same CVE on a publicly accessible web server. This context-aware scoring is what makes Inspector more actionable than raw CVE feeds.Core Concepts
Scan Types
Vulnerability Scoring
Enabling Inspector
For EC2 Instances
# Enable Inspector for EC2 in account
aws inspector2 enable \
--resource-types EC2 \
--account-ids 123456789012
# Check status
aws inspector2 batch-get-account-status \
--account-ids 123456789012
# Get findings for EC2
aws inspector2 list-findings \
--filter-criteria '{
"resourceType": [{"comparison": "EQUALS", "value": "AWS_EC2_INSTANCE"}],
"severity": [{"comparison": "EQUALS", "value": "CRITICAL"}]
}'
For ECR
# Enable Inspector scanning for ECR
aws inspector2 enable \
--resource-types ECR
# Enable enhanced scanning for specific repo
aws ecr put-image-scanning-configuration \
--repository-name my-app \
--image-scanning-configuration scanOnPush=true
# Get ECR findings
aws inspector2 list-findings \
--filter-criteria '{
"resourceType": [{"comparison": "EQUALS", "value": "AWS_ECR_CONTAINER_IMAGE"}],
"severity": [{"comparison": "EQUALS", "value": "HIGH"}]
}'
# Get SBOM
aws inspector2 list-coverage \
--filter-criteria '{
"resourceType": [{"comparison": "EQUALS", "value": "AWS_ECR_CONTAINER_IMAGE"}]
}'
For Lambda
# Enable Inspector for Lambda
aws inspector2 enable \
--resource-types LAMBDA \
--account-ids 123456789012
# Lambda scanning is automatic - no additional config needed
# Get Lambda findings
aws inspector2 list-findings \
--filter-criteria '{
"resourceType": [{"comparison": "EQUALS", "value": "AWS_LAMBDA_FUNCTION"}],
"severity": [{"comparison": "EQUALS", "value": "CRITICAL"}]
}'
Terraform Configuration
# Enable Inspector
resource "aws_inspector2_enabler" "main" {
account_ids = [data.aws_caller_identity.current.account_id]
resource_types = ["EC2", "ECR", "LAMBDA"]
}
# ECR repository with enhanced scanning
resource "aws_ecr_repository" "app" {
name = "my-application"
image_tag_mutability = "MUTABLE"
image_scanning_configuration {
scan_on_push = true
}
encryption_configuration {
encryption_type = "KMS"
kms_key = aws_kms_key.ecr.arn
}
tags = {
Environment = "production"
}
}
# Inspector delegated admin (for Organizations)
resource "aws_inspector2_delegated_admin_account" "main" {
account_id = "123456789012"
}
# Inspector member association
resource "aws_inspector2_member_association" "members" {
account_id = "111122223333"
}
# EventBridge rule for critical findings
resource "aws_cloudwatch_event_rule" "inspector_critical" {
name = "inspector-critical-findings"
description = "Capture critical Inspector findings"
event_pattern = jsonencode({
source = ["aws.inspector2"]
detail-type = ["Inspector2 Finding"]
detail = {
severity = ["CRITICAL"]
status = ["ACTIVE"]
}
})
}
resource "aws_cloudwatch_event_target" "notify" {
rule = aws_cloudwatch_event_rule.inspector_critical.name
target_id = "SendToSNS"
arn = aws_sns_topic.security_alerts.arn
}
# SNS topic for alerts
resource "aws_sns_topic" "security_alerts" {
name = "inspector-security-alerts"
}
resource "aws_sns_topic_subscription" "email" {
topic_arn = aws_sns_topic.security_alerts.arn
protocol = "email"
endpoint = "security-team@example.com"
}
Finding Management
Understanding Findings
{
"findingArn": "arn:aws:inspector2:us-east-1:123456789012:finding/...",
"awsAccountId": "123456789012",
"type": "PACKAGE_VULNERABILITY",
"description": "CVE-2024-12345 - Remote Code Execution in libssl1.1",
"severity": "CRITICAL",
"firstObservedAt": "2024-01-15T10:00:00.000Z",
"lastObservedAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:00:00.000Z",
"status": "ACTIVE",
"remediation": {
"recommendation": {
"text": "Update libssl1.1 to version 1.1.1w-0+deb11u1 or later",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-12345"
}
},
"packageVulnerabilityDetails": {
"vulnerabilityId": "CVE-2024-12345",
"vulnerablePackages": [
{
"name": "libssl1.1",
"version": "1.1.1n-0+deb11u3",
"architecture": "amd64",
"packageManager": "APT"
}
],
"source": "NVD",
"cvss": {
"version": "3.1",
"baseScore": 9.8,
"scoringVector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
},
"referenceUrls": [
"https://nvd.nist.gov/vuln/detail/CVE-2024-12345"
]
},
"resources": [
{
"type": "AWS_EC2_INSTANCE",
"id": "i-1234567890abcdef0",
"details": {
"awsEc2Instance": {
"type": "t3.medium",
"platform": "UBUNTU_20_04",
"ipV4Addresses": ["10.0.1.50"]
}
}
}
],
"networkReachabilityDetails": {
"networkPath": {
"steps": [
{
"componentType": "INTERNET_GATEWAY"
},
{
"componentType": "SECURITY_GROUP",
"componentId": "sg-0123456789abcdef0"
}
]
},
"openPortRange": {
"begin": 443,
"end": 443
},
"protocol": "TCP"
},
"exploitAvailable": "YES",
"fixAvailable": "YES"
}
Automated Remediation
import boto3
import json
inspector = boto3.client('inspector2')
ssm = boto3.client('ssm')
sns = boto3.client('sns')
def lambda_handler(event, context):
"""
Automated response to Inspector findings
"""
finding = event['detail']
severity = finding['severity']
resource_type = finding['resources'][0]['type']
if severity == 'CRITICAL' and finding['fixAvailable'] == 'YES':
if resource_type == 'AWS_EC2_INSTANCE':
remediate_ec2_vulnerability(finding)
elif resource_type == 'AWS_ECR_CONTAINER_IMAGE':
notify_container_vulnerability(finding)
elif resource_type == 'AWS_LAMBDA_FUNCTION':
remediate_lambda_vulnerability(finding)
def remediate_ec2_vulnerability(finding):
"""
Patch EC2 instance using Systems Manager.
This is the "golden path" for EC2 patching: Inspector detects the vuln,
EventBridge triggers this Lambda, and SSM Run Command applies the patch.
No SSH access needed, no bastion hosts, fully auditable.
Common mistake: patching without testing. In production, route the
SSM command to a staging instance first, verify the patch doesn't break
your application, THEN apply to production instances in a rolling fashion.
"""
instance_id = finding['resources'][0]['id']
vulnerability_id = finding['packageVulnerabilityDetails']['vulnerabilityId']
# Get affected package
vulnerable_pkg = finding['packageVulnerabilityDetails']['vulnerablePackages'][0]
package_name = vulnerable_pkg['name']
fixed_version = finding['remediation']['recommendation']['text']
# Run patch command via SSM
response = ssm.send_command(
InstanceIds=[instance_id],
DocumentName='AWS-RunPatchBaseline',
Parameters={
'Operation': ['Install']
},
Comment=f'Patching {vulnerability_id} - {package_name}'
)
command_id = response['Command']['CommandId']
# Notify team
notify_remediation(
finding,
f'Initiated patching on {instance_id}. SSM Command: {command_id}'
)
def notify_container_vulnerability(finding):
"""
Alert team about container vulnerability
"""
image_uri = finding['resources'][0]['id']
vulnerability_id = finding['packageVulnerabilityDetails']['vulnerabilityId']
cvss_score = finding['packageVulnerabilityDetails']['cvss']['baseScore']
message = {
'severity': finding['severity'],
'vulnerability': vulnerability_id,
'cvss_score': cvss_score,
'image': image_uri,
'action_required': 'Rebuild container image with updated base image',
'remediation': finding['remediation']['recommendation']['text']
}
sns.publish(
TopicArn='arn:aws:sns:us-east-1:123456789012:container-security',
Subject=f'CRITICAL: Container Vulnerability {vulnerability_id}',
Message=json.dumps(message, indent=2)
)
def remediate_lambda_vulnerability(finding):
"""
Update Lambda function dependencies
"""
function_arn = finding['resources'][0]['id']
function_name = function_arn.split(':')[-1]
vulnerability_id = finding['packageVulnerabilityDetails']['vulnerabilityId']
# Get Lambda function
lambda_client = boto3.client('lambda')
function = lambda_client.get_function(FunctionName=function_name)
message = {
'severity': finding['severity'],
'function': function_name,
'vulnerability': vulnerability_id,
'runtime': function['Configuration']['Runtime'],
'action_required': 'Update function dependencies and redeploy',
'remediation': finding['remediation']['recommendation']['text']
}
sns.publish(
TopicArn='arn:aws:sns:us-east-1:123456789012:lambda-security',
Subject=f'Lambda Vulnerability: {function_name}',
Message=json.dumps(message, indent=2)
)
def notify_remediation(finding, action_taken):
"""
Send notification about remediation action
"""
sns.publish(
TopicArn='arn:aws:sns:us-east-1:123456789012:security-remediation',
Subject=f"Inspector Remediation: {finding['packageVulnerabilityDetails']['vulnerabilityId']}",
Message=json.dumps({
'finding_arn': finding['findingArn'],
'severity': finding['severity'],
'vulnerability': finding['packageVulnerabilityDetails']['vulnerabilityId'],
'action_taken': action_taken
}, indent=2)
)
Suppression Rules
import boto3
inspector = boto3.client('inspector2')
def create_suppression_rule():
"""
Suppress findings for dev environment
"""
response = inspector.create_filter(
action='SUPPRESS',
description='Suppress low severity findings in development',
filterCriteria={
'severity': [
{
'comparison': 'EQUALS',
'value': 'LOW'
}
],
'resourceTags': [
{
'comparison': 'EQUALS',
'key': 'Environment',
'value': 'development'
}
]
},
name='suppress-dev-low-severity',
reason='Low severity acceptable in dev environment'
)
return response
def suppress_specific_cve():
"""
Suppress specific CVE across all resources
"""
response = inspector.create_filter(
action='SUPPRESS',
description='Suppress CVE-2024-12345 - false positive',
filterCriteria={
'vulnerabilityId': [
{
'comparison': 'EQUALS',
'value': 'CVE-2024-12345'
}
]
},
name='suppress-cve-2024-12345',
reason='False positive - not applicable to our use case'
)
return response
Multi-Account Setup
Organization Integration
# From management account
aws inspector2 enable-delegated-admin-account \
--delegated-admin-account-id 123456789012
# From delegated admin account
aws inspector2 update-organization-configuration \
--auto-enable '{
"ec2": true,
"ecr": true,
"lambda": true
}'
Best Practices
Security Checklist
Inspector Best Practices:
Setup:
☐ Enable Inspector in all regions
☐ Configure delegated administrator
☐ Enable auto-enable for new accounts
☐ Set up EventBridge rules
Monitoring:
☐ Daily review of critical findings
☐ Weekly review of high severity
☐ Track patching metrics
☐ Monitor SBOM generation
Remediation:
☐ Automate EC2 patching where possible
☐ Set up container rebuild pipelines
☐ Update Lambda dependencies regularly
☐ Document suppression reasons
Compliance:
☐ Generate regular vulnerability reports
☐ Export SBOM for compliance
☐ Track time-to-remediation
Cost Optimization
Pricing Model:
EC2 Scanning:
- $0.30 per instance per month
- Charged per active instance
# Cost tip: 100 EC2 instances = $30/month -- very reasonable
# compared to commercial vulnerability scanners at $5-15/instance
ECR Scanning:
- First scan per image: FREE
- Re-scan if pushed: FREE
- Continuous monitoring: $0.09 per image per month
# Cost tip: only enable continuous monitoring for production images.
# Dev/test images get scanned on push, which is usually sufficient.
Lambda Scanning:
- $0.60 per function per month
- Includes code and layers
# Cost tip: if you have 200 Lambda functions but only 30 are
# production-critical, use tags and Inspector filters to focus scanning.
Optimization Tips:
- Use tags to exclude dev resources from continuous scanning
- Create suppression rules for accepted risks (with documented justification)
- Disable scanning for deprecated resources pending decommission
- Export findings to S3 for long-term storage and trend analysis
- Track mean-time-to-remediation (MTTR) as a KPI -- aim for <7 days for critical