runbooks 0.2.3__py3-none-any.whl → 0.6.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.
- conftest.py +26 -0
- jupyter-agent/.env.template +2 -0
- jupyter-agent/.gitattributes +35 -0
- jupyter-agent/README.md +16 -0
- jupyter-agent/app.py +256 -0
- jupyter-agent/cloudops-agent.png +0 -0
- jupyter-agent/ds-system-prompt.txt +154 -0
- jupyter-agent/jupyter-agent.png +0 -0
- jupyter-agent/llama3_template.jinja +123 -0
- jupyter-agent/requirements.txt +9 -0
- jupyter-agent/utils.py +409 -0
- runbooks/__init__.py +71 -3
- runbooks/__main__.py +13 -0
- runbooks/aws/ec2_describe_instances.py +1 -1
- runbooks/aws/ec2_run_instances.py +8 -2
- runbooks/aws/ec2_start_stop_instances.py +17 -4
- runbooks/aws/ec2_unused_volumes.py +5 -1
- runbooks/aws/s3_create_bucket.py +4 -2
- runbooks/aws/s3_list_objects.py +6 -1
- runbooks/aws/tagging_lambda_handler.py +13 -2
- runbooks/aws/tags.json +12 -0
- runbooks/base.py +353 -0
- runbooks/cfat/README.md +49 -0
- runbooks/cfat/__init__.py +74 -0
- runbooks/cfat/app.ts +644 -0
- runbooks/cfat/assessment/__init__.py +40 -0
- runbooks/cfat/assessment/asana-import.csv +39 -0
- runbooks/cfat/assessment/cfat-checks.csv +31 -0
- runbooks/cfat/assessment/cfat.txt +520 -0
- runbooks/cfat/assessment/collectors.py +200 -0
- runbooks/cfat/assessment/jira-import.csv +39 -0
- runbooks/cfat/assessment/runner.py +387 -0
- runbooks/cfat/assessment/validators.py +290 -0
- runbooks/cfat/cli.py +103 -0
- runbooks/cfat/docs/asana-import.csv +24 -0
- runbooks/cfat/docs/cfat-checks.csv +31 -0
- runbooks/cfat/docs/cfat.txt +335 -0
- runbooks/cfat/docs/checks-output.png +0 -0
- runbooks/cfat/docs/cloudshell-console-run.png +0 -0
- runbooks/cfat/docs/cloudshell-download.png +0 -0
- runbooks/cfat/docs/cloudshell-output.png +0 -0
- runbooks/cfat/docs/downloadfile.png +0 -0
- runbooks/cfat/docs/jira-import.csv +24 -0
- runbooks/cfat/docs/open-cloudshell.png +0 -0
- runbooks/cfat/docs/report-header.png +0 -0
- runbooks/cfat/models.py +1026 -0
- runbooks/cfat/package-lock.json +5116 -0
- runbooks/cfat/package.json +38 -0
- runbooks/cfat/report.py +496 -0
- runbooks/cfat/reporting/__init__.py +46 -0
- runbooks/cfat/reporting/exporters.py +337 -0
- runbooks/cfat/reporting/formatters.py +496 -0
- runbooks/cfat/reporting/templates.py +135 -0
- runbooks/cfat/run-assessment.sh +23 -0
- runbooks/cfat/runner.py +69 -0
- runbooks/cfat/src/actions/check-cloudtrail-existence.ts +43 -0
- runbooks/cfat/src/actions/check-config-existence.ts +37 -0
- runbooks/cfat/src/actions/check-control-tower.ts +37 -0
- runbooks/cfat/src/actions/check-ec2-existence.ts +46 -0
- runbooks/cfat/src/actions/check-iam-users.ts +50 -0
- runbooks/cfat/src/actions/check-legacy-cur.ts +30 -0
- runbooks/cfat/src/actions/check-org-cloudformation.ts +30 -0
- runbooks/cfat/src/actions/check-vpc-existence.ts +43 -0
- runbooks/cfat/src/actions/create-asanaimport.ts +14 -0
- runbooks/cfat/src/actions/create-backlog.ts +372 -0
- runbooks/cfat/src/actions/create-jiraimport.ts +15 -0
- runbooks/cfat/src/actions/create-report.ts +616 -0
- runbooks/cfat/src/actions/define-account-type.ts +51 -0
- runbooks/cfat/src/actions/get-enabled-org-policy-types.ts +40 -0
- runbooks/cfat/src/actions/get-enabled-org-services.ts +26 -0
- runbooks/cfat/src/actions/get-idc-info.ts +34 -0
- runbooks/cfat/src/actions/get-org-da-accounts.ts +34 -0
- runbooks/cfat/src/actions/get-org-details.ts +35 -0
- runbooks/cfat/src/actions/get-org-member-accounts.ts +44 -0
- runbooks/cfat/src/actions/get-org-ous.ts +35 -0
- runbooks/cfat/src/actions/get-regions.ts +22 -0
- runbooks/cfat/src/actions/zip-assessment.ts +27 -0
- runbooks/cfat/src/types/index.d.ts +147 -0
- runbooks/cfat/tests/__init__.py +141 -0
- runbooks/cfat/tests/test_cli.py +340 -0
- runbooks/cfat/tests/test_integration.py +290 -0
- runbooks/cfat/tests/test_models.py +505 -0
- runbooks/cfat/tests/test_reporting.py +354 -0
- runbooks/cfat/tsconfig.json +16 -0
- runbooks/cfat/webpack.config.cjs +27 -0
- runbooks/config.py +260 -0
- runbooks/finops/__init__.py +88 -0
- runbooks/finops/aws_client.py +245 -0
- runbooks/finops/cli.py +151 -0
- runbooks/finops/cost_processor.py +410 -0
- runbooks/finops/dashboard_runner.py +448 -0
- runbooks/finops/helpers.py +355 -0
- runbooks/finops/main.py +14 -0
- runbooks/finops/profile_processor.py +174 -0
- runbooks/finops/types.py +66 -0
- runbooks/finops/visualisations.py +80 -0
- runbooks/inventory/.gitignore +354 -0
- runbooks/inventory/ArgumentsClass.py +261 -0
- runbooks/inventory/Inventory_Modules.py +6130 -0
- runbooks/inventory/LandingZone/delete_lz.py +1075 -0
- runbooks/inventory/README.md +1320 -0
- runbooks/inventory/__init__.py +62 -0
- runbooks/inventory/account_class.py +532 -0
- runbooks/inventory/all_my_instances_wrapper.py +123 -0
- runbooks/inventory/aws_decorators.py +201 -0
- runbooks/inventory/cfn_move_stack_instances.py +1526 -0
- runbooks/inventory/check_cloudtrail_compliance.py +614 -0
- runbooks/inventory/check_controltower_readiness.py +1107 -0
- runbooks/inventory/check_landingzone_readiness.py +711 -0
- runbooks/inventory/cloudtrail.md +727 -0
- runbooks/inventory/collectors/__init__.py +20 -0
- runbooks/inventory/collectors/aws_compute.py +518 -0
- runbooks/inventory/collectors/aws_networking.py +275 -0
- runbooks/inventory/collectors/base.py +222 -0
- runbooks/inventory/core/__init__.py +19 -0
- runbooks/inventory/core/collector.py +303 -0
- runbooks/inventory/core/formatter.py +296 -0
- runbooks/inventory/delete_s3_buckets_objects.py +169 -0
- runbooks/inventory/discovery.md +81 -0
- runbooks/inventory/draw_org_structure.py +748 -0
- runbooks/inventory/ec2_vpc_utils.py +341 -0
- runbooks/inventory/find_cfn_drift_detection.py +272 -0
- runbooks/inventory/find_cfn_orphaned_stacks.py +719 -0
- runbooks/inventory/find_cfn_stackset_drift.py +733 -0
- runbooks/inventory/find_ec2_security_groups.py +669 -0
- runbooks/inventory/find_landingzone_versions.py +201 -0
- runbooks/inventory/find_vpc_flow_logs.py +1221 -0
- runbooks/inventory/inventory.sh +659 -0
- runbooks/inventory/list_cfn_stacks.py +558 -0
- runbooks/inventory/list_cfn_stackset_operation_results.py +252 -0
- runbooks/inventory/list_cfn_stackset_operations.py +734 -0
- runbooks/inventory/list_cfn_stacksets.py +453 -0
- runbooks/inventory/list_config_recorders_delivery_channels.py +681 -0
- runbooks/inventory/list_ds_directories.py +354 -0
- runbooks/inventory/list_ec2_availability_zones.py +286 -0
- runbooks/inventory/list_ec2_ebs_volumes.py +244 -0
- runbooks/inventory/list_ec2_instances.py +425 -0
- runbooks/inventory/list_ecs_clusters_and_tasks.py +562 -0
- runbooks/inventory/list_elbs_load_balancers.py +411 -0
- runbooks/inventory/list_enis_network_interfaces.py +526 -0
- runbooks/inventory/list_guardduty_detectors.py +568 -0
- runbooks/inventory/list_iam_policies.py +404 -0
- runbooks/inventory/list_iam_roles.py +518 -0
- runbooks/inventory/list_iam_saml_providers.py +359 -0
- runbooks/inventory/list_lambda_functions.py +882 -0
- runbooks/inventory/list_org_accounts.py +446 -0
- runbooks/inventory/list_org_accounts_users.py +354 -0
- runbooks/inventory/list_rds_db_instances.py +406 -0
- runbooks/inventory/list_route53_hosted_zones.py +318 -0
- runbooks/inventory/list_servicecatalog_provisioned_products.py +575 -0
- runbooks/inventory/list_sns_topics.py +360 -0
- runbooks/inventory/list_ssm_parameters.py +402 -0
- runbooks/inventory/list_vpc_subnets.py +433 -0
- runbooks/inventory/list_vpcs.py +422 -0
- runbooks/inventory/lockdown_cfn_stackset_role.py +224 -0
- runbooks/inventory/models/__init__.py +24 -0
- runbooks/inventory/models/account.py +192 -0
- runbooks/inventory/models/inventory.py +309 -0
- runbooks/inventory/models/resource.py +247 -0
- runbooks/inventory/recover_cfn_stack_ids.py +205 -0
- runbooks/inventory/requirements.txt +12 -0
- runbooks/inventory/run_on_multi_accounts.py +211 -0
- runbooks/inventory/tests/common_test_data.py +3661 -0
- runbooks/inventory/tests/common_test_functions.py +204 -0
- runbooks/inventory/tests/script_test_data.py +0 -0
- runbooks/inventory/tests/setup.py +24 -0
- runbooks/inventory/tests/src.py +18 -0
- runbooks/inventory/tests/test_cfn_describe_stacks.py +208 -0
- runbooks/inventory/tests/test_ec2_describe_instances.py +162 -0
- runbooks/inventory/tests/test_inventory_modules.py +55 -0
- runbooks/inventory/tests/test_lambda_list_functions.py +86 -0
- runbooks/inventory/tests/test_moto_integration_example.py +273 -0
- runbooks/inventory/tests/test_org_list_accounts.py +49 -0
- runbooks/inventory/update_aws_actions.py +173 -0
- runbooks/inventory/update_cfn_stacksets.py +1215 -0
- runbooks/inventory/update_cloudwatch_logs_retention_policy.py +294 -0
- runbooks/inventory/update_iam_roles_cross_accounts.py +478 -0
- runbooks/inventory/update_s3_public_access_block.py +539 -0
- runbooks/inventory/utils/__init__.py +23 -0
- runbooks/inventory/utils/aws_helpers.py +510 -0
- runbooks/inventory/utils/threading_utils.py +493 -0
- runbooks/inventory/utils/validation.py +682 -0
- runbooks/inventory/verify_ec2_security_groups.py +1430 -0
- runbooks/main.py +785 -0
- runbooks/organizations/__init__.py +12 -0
- runbooks/organizations/manager.py +374 -0
- runbooks/security_baseline/README.md +324 -0
- runbooks/security_baseline/checklist/alternate_contacts.py +8 -1
- runbooks/security_baseline/checklist/bucket_public_access.py +4 -1
- runbooks/security_baseline/checklist/cloudwatch_alarm_configuration.py +9 -2
- runbooks/security_baseline/checklist/guardduty_enabled.py +9 -2
- runbooks/security_baseline/checklist/multi_region_instance_usage.py +5 -1
- runbooks/security_baseline/checklist/root_access_key.py +6 -1
- runbooks/security_baseline/config-origin.json +1 -1
- runbooks/security_baseline/config.json +1 -1
- runbooks/security_baseline/permission.json +1 -1
- runbooks/security_baseline/report_generator.py +10 -2
- runbooks/security_baseline/report_template_en.html +8 -8
- runbooks/security_baseline/report_template_jp.html +8 -8
- runbooks/security_baseline/report_template_kr.html +13 -13
- runbooks/security_baseline/report_template_vn.html +8 -8
- runbooks/security_baseline/requirements.txt +7 -0
- runbooks/security_baseline/run_script.py +8 -2
- runbooks/security_baseline/security_baseline_tester.py +10 -2
- runbooks/security_baseline/utils/common.py +5 -1
- runbooks/utils/__init__.py +204 -0
- runbooks-0.6.1.dist-info/METADATA +373 -0
- runbooks-0.6.1.dist-info/RECORD +237 -0
- {runbooks-0.2.3.dist-info → runbooks-0.6.1.dist-info}/WHEEL +1 -1
- runbooks-0.6.1.dist-info/entry_points.txt +7 -0
- runbooks-0.6.1.dist-info/licenses/LICENSE +201 -0
- runbooks-0.6.1.dist-info/top_level.txt +3 -0
- runbooks/python101/calculator.py +0 -34
- runbooks/python101/config.py +0 -1
- runbooks/python101/exceptions.py +0 -16
- runbooks/python101/file_manager.py +0 -218
- runbooks/python101/toolkit.py +0 -153
- runbooks-0.2.3.dist-info/METADATA +0 -435
- runbooks-0.2.3.dist-info/RECORD +0 -61
- runbooks-0.2.3.dist-info/entry_points.txt +0 -3
- runbooks-0.2.3.dist-info/top_level.txt +0 -1
@@ -0,0 +1,402 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
"""
|
4
|
+
AWS Systems Manager (SSM) Parameter Store Inventory and Management Script
|
5
|
+
|
6
|
+
This script provides comprehensive discovery, analysis, and optional cleanup capabilities
|
7
|
+
for AWS Systems Manager Parameter Store parameters across multiple accounts and regions.
|
8
|
+
It's designed for enterprise environments where parameter sprawl and legacy parameter
|
9
|
+
cleanup is critical for operational efficiency and cost optimization.
|
10
|
+
|
11
|
+
Key Features:
|
12
|
+
- Multi-account SSM Parameter Store discovery using assume role capabilities
|
13
|
+
- Multi-region scanning with configurable region targeting
|
14
|
+
- AWS Landing Zone (ALZ) parameter detection and cleanup validation
|
15
|
+
- Age-based parameter filtering with configurable retention periods
|
16
|
+
- Pattern-based parameter identification using regex matching
|
17
|
+
- Comprehensive parameter metadata extraction and analysis
|
18
|
+
- Enterprise reporting with CSV export and structured output
|
19
|
+
- Profile-based authentication with support for federated access
|
20
|
+
|
21
|
+
Enterprise Use Cases:
|
22
|
+
- Parameter Store auditing and compliance reporting
|
23
|
+
- Legacy AWS Landing Zone parameter cleanup and migration
|
24
|
+
- Parameter sprawl analysis and cost optimization
|
25
|
+
- Multi-account parameter standardization and governance
|
26
|
+
- Operational efficiency through automated parameter lifecycle management
|
27
|
+
- Security auditing of stored parameters and access patterns
|
28
|
+
|
29
|
+
ALZ-Specific Features:
|
30
|
+
- Automatic detection of AWS Landing Zone generated parameters
|
31
|
+
- Pattern matching for ALZ UUID-based parameter naming conventions
|
32
|
+
- Age-based filtering to identify stale ALZ parameters from failed deployments
|
33
|
+
- Bulk deletion capabilities for ALZ cleanup operations (when enabled)
|
34
|
+
- Rollback protection through configurable retention windows
|
35
|
+
|
36
|
+
Security Considerations:
|
37
|
+
- Uses IAM assume role capabilities for cross-account access
|
38
|
+
- Implements proper error handling for authorization failures
|
39
|
+
- Supports read-only operations with optional deletion capabilities
|
40
|
+
- Provides comprehensive audit trail through detailed logging
|
41
|
+
- Respects parameter access permissions and encryption settings
|
42
|
+
|
43
|
+
Parameter Patterns:
|
44
|
+
- ALZ Pattern: /UUID-based-path/numeric-suffix (e.g., /2ac07efd-153d-4069-b7ad-0d18cc398b11/105)
|
45
|
+
- Standard AWS parameter conventions and custom organizational patterns
|
46
|
+
- Configurable regex matching for flexible parameter identification
|
47
|
+
|
48
|
+
Dependencies:
|
49
|
+
- boto3/botocore for AWS SSM API interactions
|
50
|
+
- tqdm for progress tracking during large-scale operations
|
51
|
+
- Inventory_Modules for common utility functions
|
52
|
+
- ArgumentsClass for standardized CLI argument parsing
|
53
|
+
|
54
|
+
Author: AWS CloudOps Team
|
55
|
+
Version: 2024.05.07
|
56
|
+
"""
|
57
|
+
|
58
|
+
import logging
|
59
|
+
import re
|
60
|
+
import sys
|
61
|
+
from datetime import datetime, timedelta, timezone
|
62
|
+
from os.path import split
|
63
|
+
from time import time
|
64
|
+
|
65
|
+
from ArgumentsClass import CommonArguments
|
66
|
+
from botocore.exceptions import ClientError
|
67
|
+
from colorama import Fore, init
|
68
|
+
from Inventory_Modules import display_results, find_ssm_parameters2, get_all_credentials
|
69
|
+
from tqdm.auto import tqdm
|
70
|
+
|
71
|
+
init()
|
72
|
+
__version__ = "2024.05.07"
|
73
|
+
begin_time = time()
|
74
|
+
ERASE_LINE = "\x1b[2K"
|
75
|
+
|
76
|
+
|
77
|
+
##################
|
78
|
+
# Functions
|
79
|
+
##################
|
80
|
+
|
81
|
+
|
82
|
+
def parse_args(arguments):
|
83
|
+
"""
|
84
|
+
Parse command line arguments for SSM Parameter Store inventory and management operations.
|
85
|
+
|
86
|
+
Configures comprehensive argument parsing for multi-account, multi-region SSM Parameter
|
87
|
+
Store discovery with specialized support for AWS Landing Zone parameter cleanup and
|
88
|
+
age-based filtering. Supports enterprise deployment patterns with profile management,
|
89
|
+
region targeting, and operational safety controls.
|
90
|
+
|
91
|
+
Args:
|
92
|
+
arguments (list): Command line arguments from sys.argv[1:]
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
argparse.Namespace: Parsed arguments containing:
|
96
|
+
- Profiles: List of AWS profiles to process
|
97
|
+
- Regions: Target regions for parameter discovery
|
98
|
+
- SkipProfiles/SkipAccounts: Exclusion filters
|
99
|
+
- RootOnly: Limit to organization root accounts
|
100
|
+
- ALZParam: Enable AWS Landing Zone parameter detection
|
101
|
+
- DaysBack: Retention period for age-based filtering (default: 90 days)
|
102
|
+
- DeletionRun: Enable parameter deletion operations (currently disabled)
|
103
|
+
- Filename: Output file for CSV export
|
104
|
+
- Time: Enable performance timing metrics
|
105
|
+
- loglevel: Logging verbosity configuration
|
106
|
+
|
107
|
+
Configuration Options:
|
108
|
+
- Multi-region scanning with region filters
|
109
|
+
- Multi-profile support for federated access
|
110
|
+
- Extended arguments for advanced filtering
|
111
|
+
- Root-only mode for organization-level inventory
|
112
|
+
- ALZ-specific parameter pattern detection
|
113
|
+
- Configurable retention windows for cleanup operations
|
114
|
+
- File output for integration and reporting
|
115
|
+
- Timing metrics for performance optimization
|
116
|
+
- Verbose logging for debugging and audit
|
117
|
+
|
118
|
+
ALZ-Specific Arguments:
|
119
|
+
--ALZ: Enables detection of AWS Landing Zone generated parameters using UUID-based
|
120
|
+
pattern matching for identification of stale parameters from failed deployments
|
121
|
+
-b/--daysback: Configures retention window for parameter age filtering, defaults to
|
122
|
+
90 days to provide reasonable safety margin for cleanup operations
|
123
|
+
+delete: Reserved for future parameter deletion capabilities, currently disabled for
|
124
|
+
safety pending enhanced multi-account/region grouping implementation
|
125
|
+
|
126
|
+
Safety Features:
|
127
|
+
- Deletion operations are currently disabled to prevent accidental data loss
|
128
|
+
- Age-based filtering provides rollback protection for recent parameters
|
129
|
+
- Comprehensive logging ensures full audit trail for compliance
|
130
|
+
- Profile-based access controls respect organizational security boundaries
|
131
|
+
"""
|
132
|
+
script_path, script_name = split(sys.argv[0])
|
133
|
+
parser = CommonArguments()
|
134
|
+
parser.multiprofile()
|
135
|
+
parser.multiregion()
|
136
|
+
parser.extendedargs()
|
137
|
+
parser.rootOnly()
|
138
|
+
parser.timing()
|
139
|
+
parser.save_to_file()
|
140
|
+
parser.verbosity()
|
141
|
+
parser.version(__version__)
|
142
|
+
local = parser.my_parser.add_argument_group(script_name, "Parameters specific to this script")
|
143
|
+
local.add_argument(
|
144
|
+
"--ALZ",
|
145
|
+
help="Identify left-over parameters created by the ALZ solution",
|
146
|
+
action="store_const",
|
147
|
+
dest="ALZParam",
|
148
|
+
const=True,
|
149
|
+
default=False,
|
150
|
+
)
|
151
|
+
local.add_argument(
|
152
|
+
"-b", "--daysback", help="Only keep the last x days of Parameters (default 90)", dest="DaysBack", default=90
|
153
|
+
)
|
154
|
+
local.add_argument(
|
155
|
+
"+delete",
|
156
|
+
help="Deletion is not working currently (as of 6/22/23)",
|
157
|
+
# help="Delete left-over parameters created by the ALZ solution. DOES NOT DELETE ANY OTHER PARAMETERS!!",
|
158
|
+
action="store_const",
|
159
|
+
dest="DeletionRun",
|
160
|
+
const=True,
|
161
|
+
default=False,
|
162
|
+
)
|
163
|
+
return parser.my_parser.parse_args(arguments)
|
164
|
+
|
165
|
+
|
166
|
+
def find_ssm_parameters(f_credentialList):
|
167
|
+
"""
|
168
|
+
Discover and collect SSM Parameter Store parameters across multiple AWS accounts and regions.
|
169
|
+
|
170
|
+
Implements sequential processing across account/region combinations to gather comprehensive
|
171
|
+
parameter inventory while providing progress feedback through visual indicators. Handles
|
172
|
+
large parameter stores with thousands of parameters while maintaining operational stability
|
173
|
+
through proper error handling and logging.
|
174
|
+
|
175
|
+
Args:
|
176
|
+
f_credentialList (list): List of credential dictionaries containing:
|
177
|
+
- AccountId/AccountNumber: AWS account identifier
|
178
|
+
- Profile: AWS profile for authentication
|
179
|
+
- Region: Target AWS region for scanning
|
180
|
+
- Credentials: Temporary AWS credentials for API access
|
181
|
+
|
182
|
+
Returns:
|
183
|
+
list: Aggregated collection of parameter records with structure:
|
184
|
+
- AccountNumber: AWS account containing the parameter
|
185
|
+
- Region: AWS region where parameter is stored
|
186
|
+
- Name: Parameter name/path in SSM Parameter Store
|
187
|
+
- LastModifiedDate: Timestamp of last parameter modification
|
188
|
+
- credentials: AWS credentials for potential deletion operations
|
189
|
+
|
190
|
+
Processing Architecture:
|
191
|
+
- Sequential processing for stability with large parameter stores
|
192
|
+
- Progress tracking through tqdm for operational visibility
|
193
|
+
- Comprehensive error handling for authorization failures
|
194
|
+
- Extensible design for future multi-threading optimization
|
195
|
+
|
196
|
+
Performance Considerations:
|
197
|
+
- Parameter stores can contain 10,000+ parameters per account/region
|
198
|
+
- Sequential processing trades speed for reliability and simplicity
|
199
|
+
- Future enhancement opportunity for multi-threaded implementation
|
200
|
+
- Progress indicators provide operational feedback during long operations
|
201
|
+
|
202
|
+
Error Handling:
|
203
|
+
- ClientError: AWS API authorization and throttling issues
|
204
|
+
- Graceful handling of access denied scenarios
|
205
|
+
- Detailed logging for troubleshooting authentication problems
|
206
|
+
- Continues processing remaining accounts on individual failures
|
207
|
+
|
208
|
+
Enterprise Scale Considerations:
|
209
|
+
- Designed for large multi-account organizations
|
210
|
+
- Handles parameter stores with thousands of parameters
|
211
|
+
- Provides operational visibility through progress tracking
|
212
|
+
- Logs authorization issues for security team follow-up
|
213
|
+
"""
|
214
|
+
parameter_list = []
|
215
|
+
print(f"Gathering parameters from {len(f_credentialList)} accounts and regions")
|
216
|
+
for credential in tqdm(f_credentialList, desc="Gathering SSM Parameters", leave=True):
|
217
|
+
try:
|
218
|
+
# Call SSM API to discover all parameters in this account/region combination
|
219
|
+
# Note: Parameter stores can contain 10,000+ parameters - this operation may take time
|
220
|
+
# Future enhancement: Consider multi-threading for improved performance
|
221
|
+
parameter_list.extend(find_ssm_parameters2(credential))
|
222
|
+
# Optional verbose logging for parameter discovery progress (currently commented)
|
223
|
+
# if verbose < 50 or len(parameter_list) == 0:
|
224
|
+
# print(f"Found a running total of {len(parameter_list)} parameters in account {Fore.RED}{credential['AccountNumber']}{Fore.RESET} in region {Fore.RED}{credential['Region']}{Fore.RESET}")
|
225
|
+
except ClientError as my_Error:
|
226
|
+
# Handle AWS API authorization failures gracefully
|
227
|
+
if "AuthFailure" in str(my_Error):
|
228
|
+
logging.error(
|
229
|
+
f"Profile {credential['Profile']}: Authorization Failure for account {credential['AccountNumber']}"
|
230
|
+
)
|
231
|
+
return parameter_list
|
232
|
+
|
233
|
+
|
234
|
+
##################
|
235
|
+
# Main execution entry point for SSM Parameter Store enterprise inventory and management
|
236
|
+
##################
|
237
|
+
if __name__ == "__main__":
|
238
|
+
"""
|
239
|
+
Main orchestration for comprehensive SSM Parameter Store discovery and analysis.
|
240
|
+
|
241
|
+
Coordinates multi-account, multi-region parameter inventory operations with specialized
|
242
|
+
support for AWS Landing Zone cleanup and enterprise parameter governance workflows.
|
243
|
+
"""
|
244
|
+
# Parse enterprise command-line arguments with specialized SSM and ALZ options
|
245
|
+
args = parse_args(sys.argv[1:])
|
246
|
+
|
247
|
+
# Extract configuration parameters for multi-account parameter discovery
|
248
|
+
pProfiles = args.Profiles # AWS profile list for federated access management
|
249
|
+
pRegionList = args.Regions # Target regions for parameter store scanning
|
250
|
+
pSkipAccounts = args.SkipAccounts # Account exclusion list for organizational policy
|
251
|
+
pSkipProfiles = args.SkipProfiles # Profile exclusion for credential optimization
|
252
|
+
pAccounts = args.Accounts # Specific account targeting for focused operations
|
253
|
+
pRootOnly = args.RootOnly # Organization root account limitation flag
|
254
|
+
ALZParam = args.ALZParam # AWS Landing Zone parameter detection enablement
|
255
|
+
pTiming = args.Time # Performance timing for operational optimization
|
256
|
+
pFilename = args.Filename # CSV export file for enterprise reporting
|
257
|
+
DeletionRun = args.DeletionRun # Parameter deletion capability (currently disabled)
|
258
|
+
dtDaysBack = timedelta(days=int(args.DaysBack)) # Retention window for age-based filtering
|
259
|
+
verbose = args.loglevel # Logging verbosity for operational visibility
|
260
|
+
|
261
|
+
# Configure enterprise logging infrastructure for parameter store operations
|
262
|
+
logging.basicConfig(level=verbose, format="[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s")
|
263
|
+
|
264
|
+
# Suppress verbose AWS SDK logging for cleaner parameter inventory output
|
265
|
+
logging.getLogger("boto3").setLevel(logging.CRITICAL) # Suppress boto3 internal logging
|
266
|
+
logging.getLogger("botocore").setLevel(logging.CRITICAL) # Suppress botocore HTTP logging
|
267
|
+
logging.getLogger("s3transfer").setLevel(logging.CRITICAL) # Suppress S3 transfer logging
|
268
|
+
logging.getLogger("urllib3").setLevel(logging.CRITICAL) # Suppress HTTP connection logging
|
269
|
+
|
270
|
+
##########################
|
271
|
+
# Define AWS Landing Zone (ALZ) parameter pattern for UUID-based identification
|
272
|
+
# Pattern matches: /UUID/numeric-suffix (e.g., /2ac07efd-153d-4069-b7ad-0d18cc398b11/105)
|
273
|
+
ALZRegex = r"/\w{8,8}-\w{4,4}-\w{4,4}-\w{4,4}-\w{12,12}/\w{3,3}"
|
274
|
+
print()
|
275
|
+
|
276
|
+
# Execute enterprise credential discovery across organizational hierarchy
|
277
|
+
CredentialList = get_all_credentials(
|
278
|
+
pProfiles, pTiming, pSkipProfiles, pSkipAccounts, pRootOnly, pAccounts, pRegionList
|
279
|
+
)
|
280
|
+
|
281
|
+
# Extract unique lists for summary reporting and operational metrics
|
282
|
+
RegionList = list(set([x["Region"] for x in CredentialList])) # Distinct regions for coverage analysis
|
283
|
+
AccountList = list(set([x["AccountId"] for x in CredentialList])) # Distinct accounts for scope reporting
|
284
|
+
|
285
|
+
# Initialize deletion candidate list for ALZ parameter cleanup operations
|
286
|
+
ParamsToDelete = []
|
287
|
+
|
288
|
+
# Execute comprehensive SSM Parameter Store discovery across all accounts/regions
|
289
|
+
AllParameters = find_ssm_parameters(CredentialList)
|
290
|
+
|
291
|
+
# Configure enterprise SSM parameter inventory report display formatting
|
292
|
+
display_dict = {
|
293
|
+
"AccountNumber": {"DisplayOrder": 1, "Heading": "Acct Number"}, # Account identifier for organizational context
|
294
|
+
"Region": {"DisplayOrder": 2, "Heading": "Region"}, # AWS region for geographic parameter distribution
|
295
|
+
"Name": {"DisplayOrder": 3, "Heading": "Parameter Name"}, # SSM parameter path for identification
|
296
|
+
"LastModifiedDate": {
|
297
|
+
"DisplayOrder": 4,
|
298
|
+
"Heading": "Last Modified",
|
299
|
+
}, # Modification timestamp for lifecycle analysis
|
300
|
+
}
|
301
|
+
|
302
|
+
# Sort parameter inventory for structured enterprise reporting and operational analysis
|
303
|
+
sorted_Parameters = sorted(AllParameters, key=lambda x: (x["AccountNumber"], x["Region"], x["Name"]))
|
304
|
+
|
305
|
+
# Generate comprehensive SSM parameter inventory report with CSV export capability
|
306
|
+
display_results(sorted_Parameters, display_dict, "Default", pFilename)
|
307
|
+
|
308
|
+
# Execute AWS Landing Zone (ALZ) parameter pattern analysis and cleanup candidate identification
|
309
|
+
if ALZParam:
|
310
|
+
ALZParams = 0 # Counter for ALZ parameters matching cleanup criteria
|
311
|
+
today = datetime.now(tz=timezone.utc) # Current UTC timestamp for age calculation
|
312
|
+
|
313
|
+
# Iterate through all discovered parameters for ALZ pattern matching and age analysis
|
314
|
+
for y in range(len(AllParameters)):
|
315
|
+
# ALZ parameters follow UUID-based path pattern: /UUID/numeric-suffix
|
316
|
+
# Example: "/2ac07efd-153d-4069-b7ad-0d18cc398b11/105" from failed ALZ deployments
|
317
|
+
# Regex pattern: "/\w{8,8}-\w{4,4}-\w{4,4}-\w{4,4}-\w{12,12}/\w{3,3}"
|
318
|
+
ParameterDate = AllParameters[y]["LastModifiedDate"]
|
319
|
+
mydelta = today - ParameterDate # Calculate parameter age as timedelta object
|
320
|
+
# Compile ALZ regex pattern for efficient UUID-based parameter identification
|
321
|
+
p = re.compile(ALZRegex)
|
322
|
+
|
323
|
+
# Log parameter analysis for detailed operational visibility and debugging
|
324
|
+
logging.info(f"Parameter{y}: {AllParameters[y]['Name']} with date {AllParameters[y]['LastModifiedDate']}")
|
325
|
+
|
326
|
+
# Identify ALZ parameters that match UUID pattern and exceed retention window
|
327
|
+
if p.match(AllParameters[y]["Name"]) and mydelta > dtDaysBack:
|
328
|
+
logging.error(
|
329
|
+
f"Parameter {AllParameters[y]['Name']} with date of {AllParameters[y]['LastModifiedDate']} matched"
|
330
|
+
)
|
331
|
+
ALZParams += 1 # Increment counter for cleanup candidate identification
|
332
|
+
|
333
|
+
# Add parameter to deletion candidate list with credentials for future cleanup operations
|
334
|
+
ParamsToDelete.append(
|
335
|
+
{"Credentials": AllParameters[y]["credentials"], "Name": AllParameters[y]["Name"]}
|
336
|
+
)
|
337
|
+
|
338
|
+
# Handle parameter deletion operations (currently disabled for safety)
|
339
|
+
if DeletionRun:
|
340
|
+
print(
|
341
|
+
f"Currently the deletion function for errored ALZ parameters isn't working. Please contact the author if this functionality is still needed for you... "
|
342
|
+
)
|
343
|
+
|
344
|
+
"""
|
345
|
+
Technical Note: Parameter Deletion Architecture Challenge
|
346
|
+
|
347
|
+
The SSM parameter deletion functionality is currently disabled due to architectural limitations
|
348
|
+
with the current multi-account/multi-region discovery implementation:
|
349
|
+
|
350
|
+
- SSM delete_parameters API requires account/region-specific batching (max 10 parameters per call)
|
351
|
+
- Original single-account/single-region implementation supported efficient batched deletion
|
352
|
+
- Current multi-account/multi-region capability requires parameter grouping by account/region
|
353
|
+
- Implementation complexity vs. usage demand assessment resulted in temporary disabling
|
354
|
+
|
355
|
+
Future Enhancement Requirements:
|
356
|
+
- Group deletion candidates by account/region combination for proper API batching
|
357
|
+
- Implement account/region-specific credential context for deletion operations
|
358
|
+
- Add batch size optimization (10 parameters per delete_parameters API call)
|
359
|
+
- Include rollback protection and deletion confirmation workflows
|
360
|
+
- Add comprehensive deletion audit logging for compliance tracking
|
361
|
+
|
362
|
+
Contact maintainer if this functionality is required for your operational needs.
|
363
|
+
"""
|
364
|
+
|
365
|
+
print()
|
366
|
+
print(ERASE_LINE) # Clear any progress indicators for clean summary display
|
367
|
+
|
368
|
+
# Display comprehensive SSM parameter inventory summary for operational reporting
|
369
|
+
print(f"Found {len(AllParameters)} total parameters")
|
370
|
+
|
371
|
+
# Report ALZ cleanup analysis results when ALZ detection is enabled
|
372
|
+
print(
|
373
|
+
f"And {ALZParams} of them were from buggy ALZ runs more than {dtDaysBack.days} days back"
|
374
|
+
) if ALZParam else None
|
375
|
+
|
376
|
+
# Display performance timing metrics for operational optimization
|
377
|
+
if pTiming:
|
378
|
+
print(ERASE_LINE)
|
379
|
+
print(f"{Fore.GREEN}This script took {time() - begin_time:.2f} seconds{Fore.RESET}")
|
380
|
+
|
381
|
+
print()
|
382
|
+
|
383
|
+
# Display operational exclusion summary for transparency and audit trail
|
384
|
+
print(f"These accounts were skipped - as requested: {pSkipAccounts}") if pSkipAccounts is not None else None
|
385
|
+
print(f"These profiles were skipped - as requested: {pSkipProfiles}") if pSkipProfiles is not None else None
|
386
|
+
|
387
|
+
print()
|
388
|
+
|
389
|
+
# Display comprehensive operational summary for executive reporting
|
390
|
+
print(
|
391
|
+
f"Found {len(AllParameters)} SSM parameters across {len(AccountList)} account{'' if len(AccountList) == 1 else 's'} across {len(RegionList)} region{'' if len(RegionList) == 1 else 's'}"
|
392
|
+
)
|
393
|
+
|
394
|
+
print()
|
395
|
+
|
396
|
+
# Display completion message and output file information
|
397
|
+
print("Thank you for using this script")
|
398
|
+
print(
|
399
|
+
f"Your output was saved to {Fore.GREEN}'{pFilename}-{datetime.now().strftime('%y-%m-%d--%H:%M:%S')}'{Fore.RESET}"
|
400
|
+
) if pFilename is not None else None
|
401
|
+
|
402
|
+
print()
|