runbooks 0.9.9__py3-none-any.whl → 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runbooks/__init__.py +1 -1
- runbooks/cfat/WEIGHT_CONFIG_README.md +368 -0
- runbooks/cfat/app.ts +27 -19
- runbooks/cfat/assessment/runner.py +6 -5
- runbooks/cfat/cloud_foundations_assessment.py +626 -0
- runbooks/cfat/tests/test_weight_configuration.ts +449 -0
- runbooks/cfat/weight_config.ts +574 -0
- runbooks/cloudops/cost_optimizer.py +95 -33
- runbooks/common/__init__.py +26 -9
- runbooks/common/aws_pricing.py +1353 -0
- runbooks/common/aws_pricing_api.py +205 -0
- runbooks/common/aws_utils.py +2 -2
- runbooks/common/comprehensive_cost_explorer_integration.py +979 -0
- runbooks/common/cross_account_manager.py +606 -0
- runbooks/common/date_utils.py +115 -0
- runbooks/common/enhanced_exception_handler.py +14 -7
- runbooks/common/env_utils.py +96 -0
- runbooks/common/mcp_cost_explorer_integration.py +5 -4
- runbooks/common/mcp_integration.py +49 -2
- runbooks/common/organizations_client.py +579 -0
- runbooks/common/profile_utils.py +127 -72
- runbooks/common/rich_utils.py +3 -3
- runbooks/finops/cost_optimizer.py +2 -1
- runbooks/finops/dashboard_runner.py +47 -28
- runbooks/finops/ebs_optimizer.py +56 -9
- runbooks/finops/elastic_ip_optimizer.py +13 -9
- runbooks/finops/embedded_mcp_validator.py +31 -0
- runbooks/finops/enhanced_trend_visualization.py +10 -4
- runbooks/finops/finops_dashboard.py +6 -5
- runbooks/finops/iam_guidance.py +6 -1
- runbooks/finops/markdown_exporter.py +217 -2
- runbooks/finops/nat_gateway_optimizer.py +76 -20
- runbooks/finops/tests/test_integration.py +3 -1
- runbooks/finops/vpc_cleanup_exporter.py +28 -26
- runbooks/finops/vpc_cleanup_optimizer.py +363 -16
- runbooks/inventory/__init__.py +10 -1
- runbooks/inventory/cloud_foundations_integration.py +409 -0
- runbooks/inventory/core/collector.py +1177 -94
- runbooks/inventory/discovery.md +339 -0
- runbooks/inventory/drift_detection_cli.py +327 -0
- runbooks/inventory/inventory_mcp_cli.py +171 -0
- runbooks/inventory/inventory_modules.py +6 -9
- runbooks/inventory/list_ec2_instances.py +3 -3
- runbooks/inventory/mcp_inventory_validator.py +2149 -0
- runbooks/inventory/mcp_vpc_validator.py +23 -6
- runbooks/inventory/organizations_discovery.py +104 -9
- runbooks/inventory/rich_inventory_display.py +129 -1
- runbooks/inventory/unified_validation_engine.py +1279 -0
- runbooks/inventory/verify_ec2_security_groups.py +3 -1
- runbooks/inventory/vpc_analyzer.py +825 -7
- runbooks/inventory/vpc_flow_analyzer.py +36 -42
- runbooks/main.py +708 -47
- runbooks/monitoring/performance_monitor.py +11 -7
- runbooks/operate/base.py +9 -6
- runbooks/operate/deployment_framework.py +5 -4
- runbooks/operate/deployment_validator.py +6 -5
- runbooks/operate/dynamodb_operations.py +6 -5
- runbooks/operate/ec2_operations.py +3 -2
- runbooks/operate/mcp_integration.py +6 -5
- runbooks/operate/networking_cost_heatmap.py +21 -16
- runbooks/operate/s3_operations.py +13 -12
- runbooks/operate/vpc_operations.py +100 -12
- runbooks/remediation/base.py +4 -2
- runbooks/remediation/commons.py +5 -5
- runbooks/remediation/commvault_ec2_analysis.py +68 -15
- runbooks/remediation/config/accounts_example.json +31 -0
- runbooks/remediation/ec2_unattached_ebs_volumes.py +6 -3
- runbooks/remediation/multi_account.py +120 -7
- runbooks/remediation/rds_snapshot_list.py +5 -3
- runbooks/remediation/remediation_cli.py +710 -0
- runbooks/remediation/universal_account_discovery.py +377 -0
- runbooks/security/compliance_automation_engine.py +99 -20
- runbooks/security/config/__init__.py +24 -0
- runbooks/security/config/compliance_config.py +255 -0
- runbooks/security/config/compliance_weights_example.json +22 -0
- runbooks/security/config_template_generator.py +500 -0
- runbooks/security/security_cli.py +377 -0
- runbooks/validation/__init__.py +21 -1
- runbooks/validation/cli.py +8 -7
- runbooks/validation/comprehensive_2way_validator.py +2007 -0
- runbooks/validation/mcp_validator.py +965 -101
- runbooks/validation/terraform_citations_validator.py +363 -0
- runbooks/validation/terraform_drift_detector.py +1098 -0
- runbooks/vpc/cleanup_wrapper.py +231 -10
- runbooks/vpc/config.py +346 -73
- runbooks/vpc/cross_account_session.py +312 -0
- runbooks/vpc/heatmap_engine.py +115 -41
- runbooks/vpc/manager_interface.py +9 -9
- runbooks/vpc/mcp_no_eni_validator.py +1630 -0
- runbooks/vpc/networking_wrapper.py +14 -8
- runbooks/vpc/runbooks_adapter.py +33 -12
- runbooks/vpc/tests/conftest.py +4 -2
- runbooks/vpc/tests/test_cost_engine.py +4 -2
- runbooks/vpc/unified_scenarios.py +73 -3
- runbooks/vpc/vpc_cleanup_integration.py +512 -78
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/METADATA +94 -52
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/RECORD +101 -81
- runbooks/finops/runbooks.inventory.organizations_discovery.log +0 -0
- runbooks/finops/runbooks.security.report_generator.log +0 -0
- runbooks/finops/runbooks.security.run_script.log +0 -0
- runbooks/finops/runbooks.security.security_export.log +0 -0
- runbooks/finops/tests/results_test_finops_dashboard.xml +0 -1
- runbooks/inventory/artifacts/scale-optimize-status.txt +0 -12
- runbooks/inventory/runbooks.inventory.organizations_discovery.log +0 -0
- runbooks/inventory/runbooks.security.report_generator.log +0 -0
- runbooks/inventory/runbooks.security.run_script.log +0 -0
- runbooks/inventory/runbooks.security.security_export.log +0 -0
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/WHEEL +0 -0
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/entry_points.txt +0 -0
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {runbooks-0.9.9.dist-info → runbooks-1.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,710 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Remediation CLI Commands - Dynamic Multi-Account Support
|
4
|
+
|
5
|
+
Enhanced remediation CLI with enterprise configuration patterns:
|
6
|
+
- Dynamic account discovery (environment variables, config files, Organizations API)
|
7
|
+
- Profile override support (--profile parameter)
|
8
|
+
- Multi-account operations with safety controls
|
9
|
+
- Configuration-driven approach eliminating hardcoded values
|
10
|
+
|
11
|
+
Author: DevOps Security Engineer (Claude Code Enterprise Team)
|
12
|
+
Version: 1.0 - Enterprise Dynamic Configuration Ready
|
13
|
+
"""
|
14
|
+
|
15
|
+
import os
|
16
|
+
from typing import List, Optional
|
17
|
+
|
18
|
+
import click
|
19
|
+
from rich.console import Console
|
20
|
+
from rich.panel import Panel
|
21
|
+
|
22
|
+
from runbooks.common.profile_utils import get_profile_for_operation, validate_profile_access
|
23
|
+
from runbooks.common.rich_utils import (
|
24
|
+
console,
|
25
|
+
create_panel,
|
26
|
+
print_error,
|
27
|
+
print_info,
|
28
|
+
print_success,
|
29
|
+
print_warning,
|
30
|
+
)
|
31
|
+
|
32
|
+
from .multi_account import (
|
33
|
+
MultiAccountRemediator,
|
34
|
+
discover_organization_accounts,
|
35
|
+
get_accounts_from_environment,
|
36
|
+
)
|
37
|
+
from .universal_account_discovery import UniversalAccountDiscovery
|
38
|
+
|
39
|
+
|
40
|
+
@click.group()
|
41
|
+
@click.option(
|
42
|
+
"--profile",
|
43
|
+
default=None,
|
44
|
+
help="AWS profile to use (overrides environment variables)"
|
45
|
+
)
|
46
|
+
@click.option(
|
47
|
+
"--output-dir",
|
48
|
+
default="./artifacts/remediation",
|
49
|
+
help="Output directory for remediation reports"
|
50
|
+
)
|
51
|
+
@click.pass_context
|
52
|
+
def remediation(ctx, profile: Optional[str], output_dir: str):
|
53
|
+
"""
|
54
|
+
Enterprise Security Remediation with Dynamic Account Discovery.
|
55
|
+
|
56
|
+
Supports configuration via:
|
57
|
+
- Environment variables (REMEDIATION_TARGET_ACCOUNTS)
|
58
|
+
- Configuration files (REMEDIATION_ACCOUNT_CONFIG)
|
59
|
+
- AWS Organizations API discovery
|
60
|
+
- Profile override patterns
|
61
|
+
"""
|
62
|
+
ctx.ensure_object(dict)
|
63
|
+
ctx.obj["profile"] = profile
|
64
|
+
ctx.obj["output_dir"] = output_dir
|
65
|
+
|
66
|
+
# Validate profile if specified
|
67
|
+
if profile:
|
68
|
+
resolved_profile = get_profile_for_operation("management", profile)
|
69
|
+
if not validate_profile_access(resolved_profile, "remediation operations"):
|
70
|
+
print_error(f"Profile validation failed: {resolved_profile}")
|
71
|
+
raise click.Abort()
|
72
|
+
|
73
|
+
|
74
|
+
@remediation.command("s3-security")
|
75
|
+
@click.option(
|
76
|
+
"--operations",
|
77
|
+
multiple=True,
|
78
|
+
type=click.Choice([
|
79
|
+
"block_public_access",
|
80
|
+
"enforce_ssl",
|
81
|
+
"enable_encryption"
|
82
|
+
]),
|
83
|
+
default=["block_public_access"],
|
84
|
+
help="S3 security operations to execute"
|
85
|
+
)
|
86
|
+
@click.option(
|
87
|
+
"--accounts",
|
88
|
+
help="Comma-separated account IDs (overrides discovery)"
|
89
|
+
)
|
90
|
+
@click.option(
|
91
|
+
"--all",
|
92
|
+
"all_accounts",
|
93
|
+
is_flag=True,
|
94
|
+
help="Execute on all discovered accounts via Organizations API"
|
95
|
+
)
|
96
|
+
@click.option(
|
97
|
+
"--dry-run",
|
98
|
+
is_flag=True,
|
99
|
+
default=True,
|
100
|
+
help="Perform dry run without making changes (default: true)"
|
101
|
+
)
|
102
|
+
@click.option(
|
103
|
+
"--parallel",
|
104
|
+
is_flag=True,
|
105
|
+
default=True,
|
106
|
+
help="Execute operations in parallel (default: true)"
|
107
|
+
)
|
108
|
+
@click.option(
|
109
|
+
"--max-workers",
|
110
|
+
type=int,
|
111
|
+
default=5,
|
112
|
+
help="Maximum parallel workers"
|
113
|
+
)
|
114
|
+
@click.pass_context
|
115
|
+
def s3_security(
|
116
|
+
ctx,
|
117
|
+
operations: List[str],
|
118
|
+
accounts: Optional[str],
|
119
|
+
all_accounts: bool,
|
120
|
+
dry_run: bool,
|
121
|
+
parallel: bool,
|
122
|
+
max_workers: int
|
123
|
+
):
|
124
|
+
"""
|
125
|
+
Execute S3 security remediation across multiple accounts.
|
126
|
+
|
127
|
+
Environment Variables Supported:
|
128
|
+
- REMEDIATION_TARGET_ACCOUNTS: Comma-separated account IDs
|
129
|
+
- REMEDIATION_ACCOUNT_CONFIG: Path to accounts configuration file
|
130
|
+
- ACCESS_PORTAL_URL: AWS SSO start URL for multi-account access
|
131
|
+
"""
|
132
|
+
profile = ctx.obj["profile"]
|
133
|
+
output_dir = ctx.obj["output_dir"]
|
134
|
+
|
135
|
+
try:
|
136
|
+
# Display operation header
|
137
|
+
operation_status = "DRY RUN" if dry_run else "LIVE EXECUTION"
|
138
|
+
console.print(
|
139
|
+
create_panel(
|
140
|
+
f"[bold cyan]S3 Security Remediation - {operation_status}[/bold cyan]\n\n"
|
141
|
+
f"[dim]Operations: {', '.join(operations)}[/dim]\n"
|
142
|
+
f"[dim]Profile: {profile or 'default'}[/dim]\n"
|
143
|
+
f"[dim]Parallel: {parallel} (workers: {max_workers})[/dim]",
|
144
|
+
title="🛡️ Starting S3 Remediation",
|
145
|
+
border_style="cyan" if dry_run else "red",
|
146
|
+
)
|
147
|
+
)
|
148
|
+
|
149
|
+
# Safety warning for live operations
|
150
|
+
if not dry_run:
|
151
|
+
console.print(
|
152
|
+
Panel(
|
153
|
+
"[bold red]⚠️ LIVE EXECUTION MODE ⚠️[/bold red]\n\n"
|
154
|
+
"This will make actual changes to AWS resources.\n"
|
155
|
+
"Ensure you have proper permissions and backups.",
|
156
|
+
border_style="red",
|
157
|
+
title="Security Warning"
|
158
|
+
)
|
159
|
+
)
|
160
|
+
|
161
|
+
if not click.confirm("Continue with live execution?"):
|
162
|
+
print_warning("Operation cancelled by user")
|
163
|
+
return
|
164
|
+
|
165
|
+
# Determine target accounts
|
166
|
+
target_accounts = []
|
167
|
+
|
168
|
+
if accounts:
|
169
|
+
# Use specified accounts
|
170
|
+
account_ids = [acc.strip() for acc in accounts.split(",")]
|
171
|
+
target_accounts = [
|
172
|
+
type('AWSAccount', (), {'account_id': acc_id, 'environment': f'specified-{i}'})()
|
173
|
+
for i, acc_id in enumerate(account_ids)
|
174
|
+
]
|
175
|
+
print_info(f"Using specified accounts: {len(target_accounts)} accounts")
|
176
|
+
|
177
|
+
elif all_accounts:
|
178
|
+
# Discover all accounts via Organizations API
|
179
|
+
print_info("Discovering accounts via Organizations API...")
|
180
|
+
target_accounts = discover_organization_accounts(profile=profile)
|
181
|
+
print_info(f"Discovered {len(target_accounts)} accounts")
|
182
|
+
|
183
|
+
else:
|
184
|
+
# Use environment configuration
|
185
|
+
env_accounts = get_accounts_from_environment()
|
186
|
+
if env_accounts:
|
187
|
+
target_accounts = env_accounts
|
188
|
+
print_info(f"Using accounts from environment: {len(target_accounts)} accounts")
|
189
|
+
else:
|
190
|
+
# Fallback to Organizations discovery
|
191
|
+
print_info("No environment configuration found, discovering via Organizations API...")
|
192
|
+
target_accounts = discover_organization_accounts(profile=profile)
|
193
|
+
print_info(f"Discovered {len(target_accounts)} accounts")
|
194
|
+
|
195
|
+
if not target_accounts:
|
196
|
+
print_error("No target accounts found for remediation")
|
197
|
+
raise click.Abort()
|
198
|
+
|
199
|
+
# Initialize multi-account remediator
|
200
|
+
sso_start_url = os.getenv("ACCESS_PORTAL_URL")
|
201
|
+
if not sso_start_url:
|
202
|
+
print_warning("ACCESS_PORTAL_URL not set - SSO functionality may be limited")
|
203
|
+
|
204
|
+
remediator = MultiAccountRemediator(
|
205
|
+
sso_start_url=sso_start_url,
|
206
|
+
parallel_execution=parallel,
|
207
|
+
max_workers=max_workers
|
208
|
+
)
|
209
|
+
|
210
|
+
# Execute bulk S3 security operations
|
211
|
+
print_info(f"Executing S3 security operations on {len(target_accounts)} accounts...")
|
212
|
+
|
213
|
+
results = remediator.bulk_s3_security(
|
214
|
+
accounts=target_accounts,
|
215
|
+
operations=list(operations),
|
216
|
+
dry_run=dry_run
|
217
|
+
)
|
218
|
+
|
219
|
+
# Display results summary
|
220
|
+
successful_results = [r for r in results if r.success]
|
221
|
+
failed_results = [r for r in results if r.failed]
|
222
|
+
|
223
|
+
print_success(
|
224
|
+
f"S3 security remediation completed: "
|
225
|
+
f"{len(successful_results)} successful, {len(failed_results)} failed"
|
226
|
+
)
|
227
|
+
|
228
|
+
if failed_results:
|
229
|
+
print_warning(f"Failed operations: {len(failed_results)}")
|
230
|
+
for result in failed_results[:5]: # Show first 5 failures
|
231
|
+
print_error(f" Account {result.context.account.account_id}: {result.error_message}")
|
232
|
+
|
233
|
+
# Generate compliance report
|
234
|
+
compliance_report = remediator.generate_compliance_report(results)
|
235
|
+
print_info(f"Compliance report generated: {compliance_report['total_operations']} operations across {compliance_report['total_accounts']} accounts")
|
236
|
+
|
237
|
+
# Display configuration sources used
|
238
|
+
_display_configuration_sources()
|
239
|
+
|
240
|
+
except Exception as e:
|
241
|
+
print_error(f"S3 security remediation failed: {str(e)}")
|
242
|
+
raise click.Abort()
|
243
|
+
|
244
|
+
|
245
|
+
@remediation.command("list-accounts")
|
246
|
+
@click.option(
|
247
|
+
"--show-environment",
|
248
|
+
is_flag=True,
|
249
|
+
help="Show environment classification for each account"
|
250
|
+
)
|
251
|
+
@click.pass_context
|
252
|
+
def list_accounts(ctx, show_environment: bool):
|
253
|
+
"""
|
254
|
+
List available accounts for remediation operations.
|
255
|
+
"""
|
256
|
+
profile = ctx.obj["profile"]
|
257
|
+
|
258
|
+
try:
|
259
|
+
console.print(
|
260
|
+
create_panel(
|
261
|
+
"[bold cyan]Account Discovery[/bold cyan]\n\n"
|
262
|
+
"[dim]Discovering accounts from all sources...[/dim]",
|
263
|
+
title="📋 Account Listing",
|
264
|
+
border_style="blue",
|
265
|
+
)
|
266
|
+
)
|
267
|
+
|
268
|
+
# Try environment configuration first
|
269
|
+
env_accounts = get_accounts_from_environment()
|
270
|
+
if env_accounts:
|
271
|
+
console.print("\n[bold]Accounts from Environment Configuration:[/bold]")
|
272
|
+
for account in env_accounts:
|
273
|
+
env_indicator = f" ({account.environment})" if show_environment else ""
|
274
|
+
console.print(f" ✅ {account.account_id}{env_indicator}")
|
275
|
+
|
276
|
+
# Discover from Organizations API
|
277
|
+
try:
|
278
|
+
org_accounts = discover_organization_accounts(profile=profile)
|
279
|
+
console.print(f"\n[bold]Accounts from Organizations API Discovery:[/bold]")
|
280
|
+
for account in org_accounts:
|
281
|
+
env_indicator = f" ({account.environment})" if show_environment else ""
|
282
|
+
name_part = f" - {account.name}" if hasattr(account, 'name') and account.name else ""
|
283
|
+
console.print(f" 🌐 {account.account_id}{env_indicator}{name_part}")
|
284
|
+
except Exception as e:
|
285
|
+
print_warning(f"Organizations API discovery failed: {str(e)}")
|
286
|
+
|
287
|
+
# Display configuration information
|
288
|
+
console.print("\n[bold]Configuration Sources:[/bold]")
|
289
|
+
|
290
|
+
if os.getenv("REMEDIATION_TARGET_ACCOUNTS"):
|
291
|
+
console.print(" ✅ REMEDIATION_TARGET_ACCOUNTS environment variable")
|
292
|
+
|
293
|
+
if os.getenv("REMEDIATION_ACCOUNT_CONFIG"):
|
294
|
+
config_path = os.getenv("REMEDIATION_ACCOUNT_CONFIG")
|
295
|
+
status = "✅" if os.path.exists(config_path) else "⚠️ "
|
296
|
+
console.print(f" {status} REMEDIATION_ACCOUNT_CONFIG: {config_path}")
|
297
|
+
|
298
|
+
if not env_accounts:
|
299
|
+
console.print(" ℹ️ No environment configuration - using Organizations API discovery")
|
300
|
+
|
301
|
+
except Exception as e:
|
302
|
+
print_error(f"Account listing failed: {str(e)}")
|
303
|
+
raise click.Abort()
|
304
|
+
|
305
|
+
|
306
|
+
@remediation.command("config-info")
|
307
|
+
@click.pass_context
|
308
|
+
def config_info(ctx):
|
309
|
+
"""
|
310
|
+
Display current remediation configuration and environment setup.
|
311
|
+
"""
|
312
|
+
console.print(
|
313
|
+
Panel.fit(
|
314
|
+
"[bold cyan]Remediation Configuration Information[/bold cyan]",
|
315
|
+
border_style="cyan"
|
316
|
+
)
|
317
|
+
)
|
318
|
+
|
319
|
+
# Display environment variables
|
320
|
+
print_info("Environment Configuration:")
|
321
|
+
|
322
|
+
env_vars = {
|
323
|
+
"Account Configuration": {
|
324
|
+
"REMEDIATION_TARGET_ACCOUNTS": os.getenv("REMEDIATION_TARGET_ACCOUNTS", "Not set"),
|
325
|
+
"REMEDIATION_ACCOUNT_CONFIG": os.getenv("REMEDIATION_ACCOUNT_CONFIG", "Not set"),
|
326
|
+
},
|
327
|
+
"SSO Configuration": {
|
328
|
+
"ACCESS_PORTAL_URL": os.getenv("ACCESS_PORTAL_URL", "Not set"),
|
329
|
+
},
|
330
|
+
"Profile Configuration": {
|
331
|
+
"MANAGEMENT_PROFILE": os.getenv("MANAGEMENT_PROFILE", "Not set"),
|
332
|
+
"CENTRALISED_OPS_PROFILE": os.getenv("CENTRALISED_OPS_PROFILE", "Not set"),
|
333
|
+
}
|
334
|
+
}
|
335
|
+
|
336
|
+
for category, variables in env_vars.items():
|
337
|
+
console.print(f"\n[bold]{category}:[/bold]")
|
338
|
+
for var_name, var_value in variables.items():
|
339
|
+
status = "✅" if var_value != "Not set" else "❌"
|
340
|
+
console.print(f" {status} {var_name}: {var_value}")
|
341
|
+
|
342
|
+
# Display example configuration files
|
343
|
+
console.print("\n[bold]Example Configuration Files:[/bold]")
|
344
|
+
config_examples = [
|
345
|
+
"src/runbooks/remediation/config/accounts_example.json"
|
346
|
+
]
|
347
|
+
|
348
|
+
for config_file in config_examples:
|
349
|
+
if os.path.exists(config_file):
|
350
|
+
console.print(f" ✅ {config_file}")
|
351
|
+
else:
|
352
|
+
console.print(f" 📝 {config_file} (example)")
|
353
|
+
|
354
|
+
# Usage examples
|
355
|
+
console.print("\n[bold]Usage Examples:[/bold]")
|
356
|
+
examples = [
|
357
|
+
"# Set target accounts via environment variable",
|
358
|
+
"export REMEDIATION_TARGET_ACCOUNTS=\"111122223333,444455556666\"",
|
359
|
+
"",
|
360
|
+
"# Use configuration file",
|
361
|
+
"export REMEDIATION_ACCOUNT_CONFIG=\"/path/to/accounts.json\"",
|
362
|
+
"",
|
363
|
+
"# Execute S3 security remediation",
|
364
|
+
"runbooks remediation s3-security --operations block_public_access --dry-run",
|
365
|
+
"",
|
366
|
+
"# Execute on all discovered accounts",
|
367
|
+
"runbooks remediation s3-security --all --operations block_public_access,enforce_ssl",
|
368
|
+
]
|
369
|
+
|
370
|
+
for example in examples:
|
371
|
+
if example.startswith("#") or example == "":
|
372
|
+
console.print(f"[dim]{example}[/dim]")
|
373
|
+
else:
|
374
|
+
console.print(f"[cyan]{example}[/cyan]")
|
375
|
+
|
376
|
+
|
377
|
+
def _display_configuration_sources():
|
378
|
+
"""Display information about configuration sources used."""
|
379
|
+
console.print("\n[bold]Configuration Sources:[/bold]")
|
380
|
+
|
381
|
+
# Check environment variables
|
382
|
+
if os.getenv("REMEDIATION_TARGET_ACCOUNTS"):
|
383
|
+
console.print(" ✅ Using REMEDIATION_TARGET_ACCOUNTS environment variable")
|
384
|
+
|
385
|
+
if os.getenv("REMEDIATION_ACCOUNT_CONFIG"):
|
386
|
+
config_path = os.getenv("REMEDIATION_ACCOUNT_CONFIG")
|
387
|
+
if os.path.exists(config_path):
|
388
|
+
console.print(f" ✅ Using accounts config file: {config_path}")
|
389
|
+
else:
|
390
|
+
console.print(f" ⚠️ Accounts config file not found: {config_path}")
|
391
|
+
|
392
|
+
if os.getenv("ACCESS_PORTAL_URL"):
|
393
|
+
console.print(" ✅ AWS SSO configured via ACCESS_PORTAL_URL")
|
394
|
+
else:
|
395
|
+
console.print(" ⚠️ ACCESS_PORTAL_URL not set - SSO functionality limited")
|
396
|
+
|
397
|
+
if not any([
|
398
|
+
os.getenv("REMEDIATION_TARGET_ACCOUNTS"),
|
399
|
+
os.getenv("REMEDIATION_ACCOUNT_CONFIG")
|
400
|
+
]):
|
401
|
+
console.print(" ℹ️ Using default configuration (Organizations API discovery)")
|
402
|
+
|
403
|
+
|
404
|
+
@remediation.command("generate-config")
|
405
|
+
@click.option(
|
406
|
+
"--output-dir",
|
407
|
+
default="./artifacts/remediation/config",
|
408
|
+
help="Output directory for configuration templates"
|
409
|
+
)
|
410
|
+
@click.pass_context
|
411
|
+
def generate_config_templates(ctx, output_dir: str):
|
412
|
+
"""
|
413
|
+
Generate universal configuration templates for remediation operations.
|
414
|
+
|
415
|
+
Creates templates for:
|
416
|
+
- Account discovery configuration
|
417
|
+
- Environment variable examples
|
418
|
+
- Complete setup documentation
|
419
|
+
|
420
|
+
All templates support universal AWS compatibility with no hardcoded values.
|
421
|
+
"""
|
422
|
+
print_info(f"Generating universal remediation configuration templates in {output_dir}...")
|
423
|
+
|
424
|
+
try:
|
425
|
+
# Create output directory
|
426
|
+
from pathlib import Path
|
427
|
+
output_path = Path(output_dir)
|
428
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
429
|
+
|
430
|
+
# Use the security config generator (it covers remediation too)
|
431
|
+
from runbooks.security.config_template_generator import SecurityConfigTemplateGenerator
|
432
|
+
generator = SecurityConfigTemplateGenerator(output_dir)
|
433
|
+
|
434
|
+
# Generate account discovery template
|
435
|
+
account_config = generator.generate_account_config_template()
|
436
|
+
account_path = output_path / "account_config.json"
|
437
|
+
import json
|
438
|
+
with open(account_path, 'w') as f:
|
439
|
+
json.dump(account_config, f, indent=2)
|
440
|
+
print_success(f"Generated account configuration: {account_path}")
|
441
|
+
|
442
|
+
# Generate environment variables for remediation
|
443
|
+
env_template = """# Universal Remediation Configuration
|
444
|
+
# ===================================
|
445
|
+
|
446
|
+
# Profile Configuration (Universal Profile Management)
|
447
|
+
export AWS_PROFILE="your-aws-profile-name"
|
448
|
+
|
449
|
+
# Account Discovery Configuration
|
450
|
+
export REMEDIATION_ACCOUNT_CONFIG="/path/to/account_config.json"
|
451
|
+
|
452
|
+
# Alternative: Simple comma-separated account list
|
453
|
+
export REMEDIATION_TARGET_ACCOUNTS="111122223333,444455556666,777788889999"
|
454
|
+
|
455
|
+
# Remediation Configuration
|
456
|
+
export REMEDIATION_OUTPUT_DIR="./artifacts/remediation"
|
457
|
+
export REMEDIATION_MAX_CONCURRENT="10"
|
458
|
+
export REMEDIATION_DRY_RUN="true"
|
459
|
+
export REMEDIATION_TIMEOUT_SECONDS="300"
|
460
|
+
|
461
|
+
# Multi-Account Configuration
|
462
|
+
export ORGANIZATIONS_MANAGEMENT_ROLE="OrganizationAccountAccessRole"
|
463
|
+
export CROSS_ACCOUNT_ROLE="SecurityRemediationRole"
|
464
|
+
|
465
|
+
# Example Usage Commands
|
466
|
+
# ======================
|
467
|
+
|
468
|
+
# S3 security remediation (dry run)
|
469
|
+
runbooks remediation s3-security --operations block_public_access --dry-run
|
470
|
+
|
471
|
+
# Multi-account remediation with all discovered accounts
|
472
|
+
runbooks remediation s3-security --all --operations block_public_access,enforce_ssl
|
473
|
+
|
474
|
+
# Specific account remediation
|
475
|
+
runbooks remediation s3-security --accounts 111122223333,444455556666 --operations enable_encryption
|
476
|
+
|
477
|
+
# EC2 security remediation
|
478
|
+
runbooks remediation ec2-security --operations terminate_unused_instances --dry-run
|
479
|
+
|
480
|
+
# Generate account discovery template
|
481
|
+
runbooks remediation generate-config --output-dir ./config
|
482
|
+
"""
|
483
|
+
|
484
|
+
env_path = output_path / "environment_variables.sh"
|
485
|
+
with open(env_path, 'w') as f:
|
486
|
+
f.write(env_template)
|
487
|
+
print_success(f"Generated environment variables template: {env_path}")
|
488
|
+
|
489
|
+
# Generate setup documentation specific to remediation
|
490
|
+
setup_docs = """# Universal Remediation Module Setup Guide
|
491
|
+
========================================
|
492
|
+
|
493
|
+
This guide helps you configure the remediation module for ANY AWS environment without hardcoded values.
|
494
|
+
|
495
|
+
## Quick Start
|
496
|
+
|
497
|
+
1. **Basic Setup (Single Account)**
|
498
|
+
```bash
|
499
|
+
export AWS_PROFILE="your-aws-profile"
|
500
|
+
runbooks remediation s3-security --operations block_public_access --dry-run
|
501
|
+
```
|
502
|
+
|
503
|
+
2. **Multi-Account Setup (Organizations)**
|
504
|
+
```bash
|
505
|
+
export AWS_PROFILE="your-management-account-profile"
|
506
|
+
runbooks remediation s3-security --all --operations block_public_access
|
507
|
+
```
|
508
|
+
|
509
|
+
3. **Custom Account Configuration**
|
510
|
+
```bash
|
511
|
+
export REMEDIATION_ACCOUNT_CONFIG="./account_config.json"
|
512
|
+
runbooks remediation s3-security --operations enforce_ssl,enable_encryption
|
513
|
+
```
|
514
|
+
|
515
|
+
## Account Discovery
|
516
|
+
|
517
|
+
The remediation module automatically discovers target accounts using:
|
518
|
+
|
519
|
+
1. **Environment Variables** (highest priority)
|
520
|
+
```bash
|
521
|
+
export REMEDIATION_TARGET_ACCOUNTS="111122223333,444455556666"
|
522
|
+
```
|
523
|
+
|
524
|
+
2. **Configuration File**
|
525
|
+
```bash
|
526
|
+
export REMEDIATION_ACCOUNT_CONFIG="./account_config.json"
|
527
|
+
```
|
528
|
+
|
529
|
+
3. **AWS Organizations API** (automatic discovery)
|
530
|
+
```bash
|
531
|
+
# No configuration needed - uses Organizations API
|
532
|
+
runbooks remediation s3-security --all
|
533
|
+
```
|
534
|
+
|
535
|
+
4. **Current Account** (single account fallback)
|
536
|
+
```bash
|
537
|
+
# Falls back to current account if no other configuration
|
538
|
+
runbooks remediation s3-security --operations block_public_access
|
539
|
+
```
|
540
|
+
|
541
|
+
## Available Remediation Operations
|
542
|
+
|
543
|
+
### S3 Security Operations
|
544
|
+
```bash
|
545
|
+
# Block public access (recommended)
|
546
|
+
runbooks remediation s3-security --operations block_public_access
|
547
|
+
|
548
|
+
# Enforce SSL/TLS
|
549
|
+
runbooks remediation s3-security --operations enforce_ssl
|
550
|
+
|
551
|
+
# Enable encryption at rest
|
552
|
+
runbooks remediation s3-security --operations enable_encryption
|
553
|
+
|
554
|
+
# Enable access logging
|
555
|
+
runbooks remediation s3-security --operations enable_logging
|
556
|
+
|
557
|
+
# All S3 security operations
|
558
|
+
runbooks remediation s3-security --operations block_public_access,enforce_ssl,enable_encryption
|
559
|
+
```
|
560
|
+
|
561
|
+
### EC2 Security Operations
|
562
|
+
```bash
|
563
|
+
# Security group optimization
|
564
|
+
runbooks remediation ec2-security --operations optimize_security_groups
|
565
|
+
|
566
|
+
# Unused instance cleanup
|
567
|
+
runbooks remediation ec2-security --operations terminate_unused_instances
|
568
|
+
|
569
|
+
# Enable detailed monitoring
|
570
|
+
runbooks remediation ec2-security --operations enable_monitoring
|
571
|
+
```
|
572
|
+
|
573
|
+
## Safety Features
|
574
|
+
|
575
|
+
### Dry Run Mode (Recommended)
|
576
|
+
```bash
|
577
|
+
# Always test first with dry run
|
578
|
+
runbooks remediation s3-security --operations block_public_access --dry-run
|
579
|
+
|
580
|
+
# Execute after reviewing dry run results
|
581
|
+
runbooks remediation s3-security --operations block_public_access
|
582
|
+
```
|
583
|
+
|
584
|
+
### Account Filtering
|
585
|
+
```bash
|
586
|
+
# Specific accounts only
|
587
|
+
runbooks remediation s3-security --accounts 111122223333,444455556666
|
588
|
+
|
589
|
+
# Exclude specific accounts
|
590
|
+
export REMEDIATION_EXCLUDE_ACCOUNTS="999888777666"
|
591
|
+
runbooks remediation s3-security --all
|
592
|
+
```
|
593
|
+
|
594
|
+
### Operation Scope Control
|
595
|
+
```bash
|
596
|
+
# Single operation
|
597
|
+
runbooks remediation s3-security --operations block_public_access
|
598
|
+
|
599
|
+
# Multiple operations
|
600
|
+
runbooks remediation s3-security --operations block_public_access,enforce_ssl
|
601
|
+
|
602
|
+
# All available operations for service
|
603
|
+
runbooks remediation s3-security --operations all
|
604
|
+
```
|
605
|
+
|
606
|
+
## Configuration Examples
|
607
|
+
|
608
|
+
### Account Configuration File
|
609
|
+
```json
|
610
|
+
{
|
611
|
+
"target_accounts": [
|
612
|
+
{
|
613
|
+
"account_id": "111122223333",
|
614
|
+
"account_name": "Production Environment",
|
615
|
+
"profile_name": "prod-profile",
|
616
|
+
"criticality": "high"
|
617
|
+
},
|
618
|
+
{
|
619
|
+
"account_id": "444455556666",
|
620
|
+
"account_name": "Staging Environment",
|
621
|
+
"profile_name": "staging-profile",
|
622
|
+
"criticality": "medium"
|
623
|
+
}
|
624
|
+
],
|
625
|
+
"discovery_settings": {
|
626
|
+
"max_concurrent_accounts": 10,
|
627
|
+
"validation_timeout_seconds": 30
|
628
|
+
}
|
629
|
+
}
|
630
|
+
```
|
631
|
+
|
632
|
+
### Environment Variables
|
633
|
+
```bash
|
634
|
+
# Simple account list
|
635
|
+
export REMEDIATION_TARGET_ACCOUNTS="111122223333,444455556666,777788889999"
|
636
|
+
|
637
|
+
# Performance tuning
|
638
|
+
export REMEDIATION_MAX_CONCURRENT="10"
|
639
|
+
export REMEDIATION_TIMEOUT_SECONDS="300"
|
640
|
+
|
641
|
+
# Output configuration
|
642
|
+
export REMEDIATION_OUTPUT_DIR="./artifacts/remediation"
|
643
|
+
export REMEDIATION_DRY_RUN="true"
|
644
|
+
```
|
645
|
+
|
646
|
+
## Troubleshooting
|
647
|
+
|
648
|
+
### Common Issues
|
649
|
+
|
650
|
+
1. **No Accounts Discovered**
|
651
|
+
```bash
|
652
|
+
# Check available accounts
|
653
|
+
runbooks remediation discover-accounts
|
654
|
+
|
655
|
+
# Set specific accounts
|
656
|
+
export REMEDIATION_TARGET_ACCOUNTS="111122223333"
|
657
|
+
```
|
658
|
+
|
659
|
+
2. **Access Denied**
|
660
|
+
```bash
|
661
|
+
# Verify profile access
|
662
|
+
aws sts get-caller-identity --profile your-profile
|
663
|
+
|
664
|
+
# Check Organizations permissions
|
665
|
+
aws organizations list-accounts --profile your-management-profile
|
666
|
+
```
|
667
|
+
|
668
|
+
3. **Operation Timeout**
|
669
|
+
```bash
|
670
|
+
# Increase timeout
|
671
|
+
export REMEDIATION_TIMEOUT_SECONDS="600"
|
672
|
+
|
673
|
+
# Reduce concurrent operations
|
674
|
+
export REMEDIATION_MAX_CONCURRENT="5"
|
675
|
+
```
|
676
|
+
|
677
|
+
### Validation Commands
|
678
|
+
```bash
|
679
|
+
# Test account discovery
|
680
|
+
runbooks remediation discover-accounts --profile your-profile
|
681
|
+
|
682
|
+
# Validate configuration
|
683
|
+
runbooks remediation config --profile your-profile
|
684
|
+
|
685
|
+
# Test specific operation (dry run)
|
686
|
+
runbooks remediation s3-security --operations block_public_access --dry-run --accounts 111122223333
|
687
|
+
```
|
688
|
+
|
689
|
+
This configuration system provides universal compatibility with any AWS environment while maintaining safety and control.
|
690
|
+
"""
|
691
|
+
|
692
|
+
docs_path = output_path / "REMEDIATION_SETUP_GUIDE.md"
|
693
|
+
with open(docs_path, 'w') as f:
|
694
|
+
f.write(setup_docs)
|
695
|
+
print_success(f"Generated setup documentation: {docs_path}")
|
696
|
+
|
697
|
+
print_success("Remediation configuration templates generated successfully!")
|
698
|
+
console.print("\n[bold yellow]Next steps:[/bold yellow]")
|
699
|
+
console.print("1. Review and customize the generated configuration files")
|
700
|
+
console.print("2. Set REMEDIATION_ACCOUNT_CONFIG or REMEDIATION_TARGET_ACCOUNTS")
|
701
|
+
console.print("3. Test with: runbooks remediation s3-security --operations block_public_access --dry-run")
|
702
|
+
console.print("4. Execute: runbooks remediation s3-security --operations block_public_access")
|
703
|
+
|
704
|
+
except Exception as e:
|
705
|
+
print_error(f"Failed to generate configuration templates: {e}")
|
706
|
+
raise click.Abort()
|
707
|
+
|
708
|
+
|
709
|
+
if __name__ == "__main__":
|
710
|
+
remediation()
|