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.
Files changed (221) hide show
  1. conftest.py +26 -0
  2. jupyter-agent/.env.template +2 -0
  3. jupyter-agent/.gitattributes +35 -0
  4. jupyter-agent/README.md +16 -0
  5. jupyter-agent/app.py +256 -0
  6. jupyter-agent/cloudops-agent.png +0 -0
  7. jupyter-agent/ds-system-prompt.txt +154 -0
  8. jupyter-agent/jupyter-agent.png +0 -0
  9. jupyter-agent/llama3_template.jinja +123 -0
  10. jupyter-agent/requirements.txt +9 -0
  11. jupyter-agent/utils.py +409 -0
  12. runbooks/__init__.py +71 -3
  13. runbooks/__main__.py +13 -0
  14. runbooks/aws/ec2_describe_instances.py +1 -1
  15. runbooks/aws/ec2_run_instances.py +8 -2
  16. runbooks/aws/ec2_start_stop_instances.py +17 -4
  17. runbooks/aws/ec2_unused_volumes.py +5 -1
  18. runbooks/aws/s3_create_bucket.py +4 -2
  19. runbooks/aws/s3_list_objects.py +6 -1
  20. runbooks/aws/tagging_lambda_handler.py +13 -2
  21. runbooks/aws/tags.json +12 -0
  22. runbooks/base.py +353 -0
  23. runbooks/cfat/README.md +49 -0
  24. runbooks/cfat/__init__.py +74 -0
  25. runbooks/cfat/app.ts +644 -0
  26. runbooks/cfat/assessment/__init__.py +40 -0
  27. runbooks/cfat/assessment/asana-import.csv +39 -0
  28. runbooks/cfat/assessment/cfat-checks.csv +31 -0
  29. runbooks/cfat/assessment/cfat.txt +520 -0
  30. runbooks/cfat/assessment/collectors.py +200 -0
  31. runbooks/cfat/assessment/jira-import.csv +39 -0
  32. runbooks/cfat/assessment/runner.py +387 -0
  33. runbooks/cfat/assessment/validators.py +290 -0
  34. runbooks/cfat/cli.py +103 -0
  35. runbooks/cfat/docs/asana-import.csv +24 -0
  36. runbooks/cfat/docs/cfat-checks.csv +31 -0
  37. runbooks/cfat/docs/cfat.txt +335 -0
  38. runbooks/cfat/docs/checks-output.png +0 -0
  39. runbooks/cfat/docs/cloudshell-console-run.png +0 -0
  40. runbooks/cfat/docs/cloudshell-download.png +0 -0
  41. runbooks/cfat/docs/cloudshell-output.png +0 -0
  42. runbooks/cfat/docs/downloadfile.png +0 -0
  43. runbooks/cfat/docs/jira-import.csv +24 -0
  44. runbooks/cfat/docs/open-cloudshell.png +0 -0
  45. runbooks/cfat/docs/report-header.png +0 -0
  46. runbooks/cfat/models.py +1026 -0
  47. runbooks/cfat/package-lock.json +5116 -0
  48. runbooks/cfat/package.json +38 -0
  49. runbooks/cfat/report.py +496 -0
  50. runbooks/cfat/reporting/__init__.py +46 -0
  51. runbooks/cfat/reporting/exporters.py +337 -0
  52. runbooks/cfat/reporting/formatters.py +496 -0
  53. runbooks/cfat/reporting/templates.py +135 -0
  54. runbooks/cfat/run-assessment.sh +23 -0
  55. runbooks/cfat/runner.py +69 -0
  56. runbooks/cfat/src/actions/check-cloudtrail-existence.ts +43 -0
  57. runbooks/cfat/src/actions/check-config-existence.ts +37 -0
  58. runbooks/cfat/src/actions/check-control-tower.ts +37 -0
  59. runbooks/cfat/src/actions/check-ec2-existence.ts +46 -0
  60. runbooks/cfat/src/actions/check-iam-users.ts +50 -0
  61. runbooks/cfat/src/actions/check-legacy-cur.ts +30 -0
  62. runbooks/cfat/src/actions/check-org-cloudformation.ts +30 -0
  63. runbooks/cfat/src/actions/check-vpc-existence.ts +43 -0
  64. runbooks/cfat/src/actions/create-asanaimport.ts +14 -0
  65. runbooks/cfat/src/actions/create-backlog.ts +372 -0
  66. runbooks/cfat/src/actions/create-jiraimport.ts +15 -0
  67. runbooks/cfat/src/actions/create-report.ts +616 -0
  68. runbooks/cfat/src/actions/define-account-type.ts +51 -0
  69. runbooks/cfat/src/actions/get-enabled-org-policy-types.ts +40 -0
  70. runbooks/cfat/src/actions/get-enabled-org-services.ts +26 -0
  71. runbooks/cfat/src/actions/get-idc-info.ts +34 -0
  72. runbooks/cfat/src/actions/get-org-da-accounts.ts +34 -0
  73. runbooks/cfat/src/actions/get-org-details.ts +35 -0
  74. runbooks/cfat/src/actions/get-org-member-accounts.ts +44 -0
  75. runbooks/cfat/src/actions/get-org-ous.ts +35 -0
  76. runbooks/cfat/src/actions/get-regions.ts +22 -0
  77. runbooks/cfat/src/actions/zip-assessment.ts +27 -0
  78. runbooks/cfat/src/types/index.d.ts +147 -0
  79. runbooks/cfat/tests/__init__.py +141 -0
  80. runbooks/cfat/tests/test_cli.py +340 -0
  81. runbooks/cfat/tests/test_integration.py +290 -0
  82. runbooks/cfat/tests/test_models.py +505 -0
  83. runbooks/cfat/tests/test_reporting.py +354 -0
  84. runbooks/cfat/tsconfig.json +16 -0
  85. runbooks/cfat/webpack.config.cjs +27 -0
  86. runbooks/config.py +260 -0
  87. runbooks/finops/__init__.py +88 -0
  88. runbooks/finops/aws_client.py +245 -0
  89. runbooks/finops/cli.py +151 -0
  90. runbooks/finops/cost_processor.py +410 -0
  91. runbooks/finops/dashboard_runner.py +448 -0
  92. runbooks/finops/helpers.py +355 -0
  93. runbooks/finops/main.py +14 -0
  94. runbooks/finops/profile_processor.py +174 -0
  95. runbooks/finops/types.py +66 -0
  96. runbooks/finops/visualisations.py +80 -0
  97. runbooks/inventory/.gitignore +354 -0
  98. runbooks/inventory/ArgumentsClass.py +261 -0
  99. runbooks/inventory/Inventory_Modules.py +6130 -0
  100. runbooks/inventory/LandingZone/delete_lz.py +1075 -0
  101. runbooks/inventory/README.md +1320 -0
  102. runbooks/inventory/__init__.py +62 -0
  103. runbooks/inventory/account_class.py +532 -0
  104. runbooks/inventory/all_my_instances_wrapper.py +123 -0
  105. runbooks/inventory/aws_decorators.py +201 -0
  106. runbooks/inventory/cfn_move_stack_instances.py +1526 -0
  107. runbooks/inventory/check_cloudtrail_compliance.py +614 -0
  108. runbooks/inventory/check_controltower_readiness.py +1107 -0
  109. runbooks/inventory/check_landingzone_readiness.py +711 -0
  110. runbooks/inventory/cloudtrail.md +727 -0
  111. runbooks/inventory/collectors/__init__.py +20 -0
  112. runbooks/inventory/collectors/aws_compute.py +518 -0
  113. runbooks/inventory/collectors/aws_networking.py +275 -0
  114. runbooks/inventory/collectors/base.py +222 -0
  115. runbooks/inventory/core/__init__.py +19 -0
  116. runbooks/inventory/core/collector.py +303 -0
  117. runbooks/inventory/core/formatter.py +296 -0
  118. runbooks/inventory/delete_s3_buckets_objects.py +169 -0
  119. runbooks/inventory/discovery.md +81 -0
  120. runbooks/inventory/draw_org_structure.py +748 -0
  121. runbooks/inventory/ec2_vpc_utils.py +341 -0
  122. runbooks/inventory/find_cfn_drift_detection.py +272 -0
  123. runbooks/inventory/find_cfn_orphaned_stacks.py +719 -0
  124. runbooks/inventory/find_cfn_stackset_drift.py +733 -0
  125. runbooks/inventory/find_ec2_security_groups.py +669 -0
  126. runbooks/inventory/find_landingzone_versions.py +201 -0
  127. runbooks/inventory/find_vpc_flow_logs.py +1221 -0
  128. runbooks/inventory/inventory.sh +659 -0
  129. runbooks/inventory/list_cfn_stacks.py +558 -0
  130. runbooks/inventory/list_cfn_stackset_operation_results.py +252 -0
  131. runbooks/inventory/list_cfn_stackset_operations.py +734 -0
  132. runbooks/inventory/list_cfn_stacksets.py +453 -0
  133. runbooks/inventory/list_config_recorders_delivery_channels.py +681 -0
  134. runbooks/inventory/list_ds_directories.py +354 -0
  135. runbooks/inventory/list_ec2_availability_zones.py +286 -0
  136. runbooks/inventory/list_ec2_ebs_volumes.py +244 -0
  137. runbooks/inventory/list_ec2_instances.py +425 -0
  138. runbooks/inventory/list_ecs_clusters_and_tasks.py +562 -0
  139. runbooks/inventory/list_elbs_load_balancers.py +411 -0
  140. runbooks/inventory/list_enis_network_interfaces.py +526 -0
  141. runbooks/inventory/list_guardduty_detectors.py +568 -0
  142. runbooks/inventory/list_iam_policies.py +404 -0
  143. runbooks/inventory/list_iam_roles.py +518 -0
  144. runbooks/inventory/list_iam_saml_providers.py +359 -0
  145. runbooks/inventory/list_lambda_functions.py +882 -0
  146. runbooks/inventory/list_org_accounts.py +446 -0
  147. runbooks/inventory/list_org_accounts_users.py +354 -0
  148. runbooks/inventory/list_rds_db_instances.py +406 -0
  149. runbooks/inventory/list_route53_hosted_zones.py +318 -0
  150. runbooks/inventory/list_servicecatalog_provisioned_products.py +575 -0
  151. runbooks/inventory/list_sns_topics.py +360 -0
  152. runbooks/inventory/list_ssm_parameters.py +402 -0
  153. runbooks/inventory/list_vpc_subnets.py +433 -0
  154. runbooks/inventory/list_vpcs.py +422 -0
  155. runbooks/inventory/lockdown_cfn_stackset_role.py +224 -0
  156. runbooks/inventory/models/__init__.py +24 -0
  157. runbooks/inventory/models/account.py +192 -0
  158. runbooks/inventory/models/inventory.py +309 -0
  159. runbooks/inventory/models/resource.py +247 -0
  160. runbooks/inventory/recover_cfn_stack_ids.py +205 -0
  161. runbooks/inventory/requirements.txt +12 -0
  162. runbooks/inventory/run_on_multi_accounts.py +211 -0
  163. runbooks/inventory/tests/common_test_data.py +3661 -0
  164. runbooks/inventory/tests/common_test_functions.py +204 -0
  165. runbooks/inventory/tests/script_test_data.py +0 -0
  166. runbooks/inventory/tests/setup.py +24 -0
  167. runbooks/inventory/tests/src.py +18 -0
  168. runbooks/inventory/tests/test_cfn_describe_stacks.py +208 -0
  169. runbooks/inventory/tests/test_ec2_describe_instances.py +162 -0
  170. runbooks/inventory/tests/test_inventory_modules.py +55 -0
  171. runbooks/inventory/tests/test_lambda_list_functions.py +86 -0
  172. runbooks/inventory/tests/test_moto_integration_example.py +273 -0
  173. runbooks/inventory/tests/test_org_list_accounts.py +49 -0
  174. runbooks/inventory/update_aws_actions.py +173 -0
  175. runbooks/inventory/update_cfn_stacksets.py +1215 -0
  176. runbooks/inventory/update_cloudwatch_logs_retention_policy.py +294 -0
  177. runbooks/inventory/update_iam_roles_cross_accounts.py +478 -0
  178. runbooks/inventory/update_s3_public_access_block.py +539 -0
  179. runbooks/inventory/utils/__init__.py +23 -0
  180. runbooks/inventory/utils/aws_helpers.py +510 -0
  181. runbooks/inventory/utils/threading_utils.py +493 -0
  182. runbooks/inventory/utils/validation.py +682 -0
  183. runbooks/inventory/verify_ec2_security_groups.py +1430 -0
  184. runbooks/main.py +785 -0
  185. runbooks/organizations/__init__.py +12 -0
  186. runbooks/organizations/manager.py +374 -0
  187. runbooks/security_baseline/README.md +324 -0
  188. runbooks/security_baseline/checklist/alternate_contacts.py +8 -1
  189. runbooks/security_baseline/checklist/bucket_public_access.py +4 -1
  190. runbooks/security_baseline/checklist/cloudwatch_alarm_configuration.py +9 -2
  191. runbooks/security_baseline/checklist/guardduty_enabled.py +9 -2
  192. runbooks/security_baseline/checklist/multi_region_instance_usage.py +5 -1
  193. runbooks/security_baseline/checklist/root_access_key.py +6 -1
  194. runbooks/security_baseline/config-origin.json +1 -1
  195. runbooks/security_baseline/config.json +1 -1
  196. runbooks/security_baseline/permission.json +1 -1
  197. runbooks/security_baseline/report_generator.py +10 -2
  198. runbooks/security_baseline/report_template_en.html +8 -8
  199. runbooks/security_baseline/report_template_jp.html +8 -8
  200. runbooks/security_baseline/report_template_kr.html +13 -13
  201. runbooks/security_baseline/report_template_vn.html +8 -8
  202. runbooks/security_baseline/requirements.txt +7 -0
  203. runbooks/security_baseline/run_script.py +8 -2
  204. runbooks/security_baseline/security_baseline_tester.py +10 -2
  205. runbooks/security_baseline/utils/common.py +5 -1
  206. runbooks/utils/__init__.py +204 -0
  207. runbooks-0.6.1.dist-info/METADATA +373 -0
  208. runbooks-0.6.1.dist-info/RECORD +237 -0
  209. {runbooks-0.2.3.dist-info → runbooks-0.6.1.dist-info}/WHEEL +1 -1
  210. runbooks-0.6.1.dist-info/entry_points.txt +7 -0
  211. runbooks-0.6.1.dist-info/licenses/LICENSE +201 -0
  212. runbooks-0.6.1.dist-info/top_level.txt +3 -0
  213. runbooks/python101/calculator.py +0 -34
  214. runbooks/python101/config.py +0 -1
  215. runbooks/python101/exceptions.py +0 -16
  216. runbooks/python101/file_manager.py +0 -218
  217. runbooks/python101/toolkit.py +0 -153
  218. runbooks-0.2.3.dist-info/METADATA +0 -435
  219. runbooks-0.2.3.dist-info/RECORD +0 -61
  220. runbooks-0.2.3.dist-info/entry_points.txt +0 -3
  221. 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()