runbooks 0.2.5__py3-none-any.whl → 0.7.0__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 (249) hide show
  1. conftest.py +26 -0
  2. jupyter-agent/.env +2 -0
  3. jupyter-agent/.env.template +2 -0
  4. jupyter-agent/.gitattributes +35 -0
  5. jupyter-agent/.gradio/certificate.pem +31 -0
  6. jupyter-agent/README.md +16 -0
  7. jupyter-agent/__main__.log +8 -0
  8. jupyter-agent/app.py +256 -0
  9. jupyter-agent/cloudops-agent.png +0 -0
  10. jupyter-agent/ds-system-prompt.txt +154 -0
  11. jupyter-agent/jupyter-agent.png +0 -0
  12. jupyter-agent/llama3_template.jinja +123 -0
  13. jupyter-agent/requirements.txt +9 -0
  14. jupyter-agent/tmp/4ojbs8a02ir/jupyter-agent.ipynb +68 -0
  15. jupyter-agent/tmp/cm5iasgpm3p/jupyter-agent.ipynb +91 -0
  16. jupyter-agent/tmp/crqbsseag5/jupyter-agent.ipynb +91 -0
  17. jupyter-agent/tmp/hohanq1u097/jupyter-agent.ipynb +57 -0
  18. jupyter-agent/tmp/jns1sam29wm/jupyter-agent.ipynb +53 -0
  19. jupyter-agent/tmp/jupyter-agent.ipynb +27 -0
  20. jupyter-agent/utils.py +409 -0
  21. runbooks/__init__.py +71 -3
  22. runbooks/__main__.py +13 -0
  23. runbooks/aws/ec2_describe_instances.py +1 -1
  24. runbooks/aws/ec2_run_instances.py +8 -2
  25. runbooks/aws/ec2_start_stop_instances.py +17 -4
  26. runbooks/aws/ec2_unused_volumes.py +5 -1
  27. runbooks/aws/s3_create_bucket.py +4 -2
  28. runbooks/aws/s3_list_objects.py +6 -1
  29. runbooks/aws/tagging_lambda_handler.py +13 -2
  30. runbooks/aws/tags.json +12 -0
  31. runbooks/base.py +353 -0
  32. runbooks/cfat/README.md +49 -0
  33. runbooks/cfat/__init__.py +74 -0
  34. runbooks/cfat/app.ts +644 -0
  35. runbooks/cfat/assessment/__init__.py +40 -0
  36. runbooks/cfat/assessment/asana-import.csv +39 -0
  37. runbooks/cfat/assessment/cfat-checks.csv +31 -0
  38. runbooks/cfat/assessment/cfat.txt +520 -0
  39. runbooks/cfat/assessment/collectors.py +200 -0
  40. runbooks/cfat/assessment/jira-import.csv +39 -0
  41. runbooks/cfat/assessment/runner.py +387 -0
  42. runbooks/cfat/assessment/validators.py +290 -0
  43. runbooks/cfat/cli.py +103 -0
  44. runbooks/cfat/docs/asana-import.csv +24 -0
  45. runbooks/cfat/docs/cfat-checks.csv +31 -0
  46. runbooks/cfat/docs/cfat.txt +335 -0
  47. runbooks/cfat/docs/checks-output.png +0 -0
  48. runbooks/cfat/docs/cloudshell-console-run.png +0 -0
  49. runbooks/cfat/docs/cloudshell-download.png +0 -0
  50. runbooks/cfat/docs/cloudshell-output.png +0 -0
  51. runbooks/cfat/docs/downloadfile.png +0 -0
  52. runbooks/cfat/docs/jira-import.csv +24 -0
  53. runbooks/cfat/docs/open-cloudshell.png +0 -0
  54. runbooks/cfat/docs/report-header.png +0 -0
  55. runbooks/cfat/models.py +1026 -0
  56. runbooks/cfat/package-lock.json +5116 -0
  57. runbooks/cfat/package.json +38 -0
  58. runbooks/cfat/report.py +496 -0
  59. runbooks/cfat/reporting/__init__.py +46 -0
  60. runbooks/cfat/reporting/exporters.py +337 -0
  61. runbooks/cfat/reporting/formatters.py +496 -0
  62. runbooks/cfat/reporting/templates.py +135 -0
  63. runbooks/cfat/run-assessment.sh +23 -0
  64. runbooks/cfat/runner.py +69 -0
  65. runbooks/cfat/src/actions/check-cloudtrail-existence.ts +43 -0
  66. runbooks/cfat/src/actions/check-config-existence.ts +37 -0
  67. runbooks/cfat/src/actions/check-control-tower.ts +37 -0
  68. runbooks/cfat/src/actions/check-ec2-existence.ts +46 -0
  69. runbooks/cfat/src/actions/check-iam-users.ts +50 -0
  70. runbooks/cfat/src/actions/check-legacy-cur.ts +30 -0
  71. runbooks/cfat/src/actions/check-org-cloudformation.ts +30 -0
  72. runbooks/cfat/src/actions/check-vpc-existence.ts +43 -0
  73. runbooks/cfat/src/actions/create-asanaimport.ts +14 -0
  74. runbooks/cfat/src/actions/create-backlog.ts +372 -0
  75. runbooks/cfat/src/actions/create-jiraimport.ts +15 -0
  76. runbooks/cfat/src/actions/create-report.ts +616 -0
  77. runbooks/cfat/src/actions/define-account-type.ts +51 -0
  78. runbooks/cfat/src/actions/get-enabled-org-policy-types.ts +40 -0
  79. runbooks/cfat/src/actions/get-enabled-org-services.ts +26 -0
  80. runbooks/cfat/src/actions/get-idc-info.ts +34 -0
  81. runbooks/cfat/src/actions/get-org-da-accounts.ts +34 -0
  82. runbooks/cfat/src/actions/get-org-details.ts +35 -0
  83. runbooks/cfat/src/actions/get-org-member-accounts.ts +44 -0
  84. runbooks/cfat/src/actions/get-org-ous.ts +35 -0
  85. runbooks/cfat/src/actions/get-regions.ts +22 -0
  86. runbooks/cfat/src/actions/zip-assessment.ts +27 -0
  87. runbooks/cfat/src/types/index.d.ts +147 -0
  88. runbooks/cfat/tests/__init__.py +141 -0
  89. runbooks/cfat/tests/test_cli.py +340 -0
  90. runbooks/cfat/tests/test_integration.py +290 -0
  91. runbooks/cfat/tests/test_models.py +505 -0
  92. runbooks/cfat/tests/test_reporting.py +354 -0
  93. runbooks/cfat/tsconfig.json +16 -0
  94. runbooks/cfat/webpack.config.cjs +27 -0
  95. runbooks/config.py +260 -0
  96. runbooks/finops/README.md +337 -0
  97. runbooks/finops/__init__.py +86 -0
  98. runbooks/finops/aws_client.py +245 -0
  99. runbooks/finops/cli.py +151 -0
  100. runbooks/finops/cost_processor.py +410 -0
  101. runbooks/finops/dashboard_runner.py +448 -0
  102. runbooks/finops/helpers.py +355 -0
  103. runbooks/finops/main.py +14 -0
  104. runbooks/finops/profile_processor.py +174 -0
  105. runbooks/finops/types.py +66 -0
  106. runbooks/finops/visualisations.py +80 -0
  107. runbooks/inventory/.gitignore +354 -0
  108. runbooks/inventory/ArgumentsClass.py +261 -0
  109. runbooks/inventory/FAILED_SCRIPTS_TROUBLESHOOTING.md +619 -0
  110. runbooks/inventory/Inventory_Modules.py +6130 -0
  111. runbooks/inventory/LandingZone/delete_lz.py +1075 -0
  112. runbooks/inventory/PASSED_SCRIPTS_GUIDE.md +738 -0
  113. runbooks/inventory/README.md +1320 -0
  114. runbooks/inventory/__init__.py +62 -0
  115. runbooks/inventory/account_class.py +532 -0
  116. runbooks/inventory/all_my_instances_wrapper.py +123 -0
  117. runbooks/inventory/aws_decorators.py +201 -0
  118. runbooks/inventory/aws_organization.png +0 -0
  119. runbooks/inventory/cfn_move_stack_instances.py +1526 -0
  120. runbooks/inventory/check_cloudtrail_compliance.py +614 -0
  121. runbooks/inventory/check_controltower_readiness.py +1107 -0
  122. runbooks/inventory/check_landingzone_readiness.py +711 -0
  123. runbooks/inventory/cloudtrail.md +727 -0
  124. runbooks/inventory/collectors/__init__.py +20 -0
  125. runbooks/inventory/collectors/aws_compute.py +518 -0
  126. runbooks/inventory/collectors/aws_networking.py +275 -0
  127. runbooks/inventory/collectors/base.py +222 -0
  128. runbooks/inventory/core/__init__.py +19 -0
  129. runbooks/inventory/core/collector.py +303 -0
  130. runbooks/inventory/core/formatter.py +296 -0
  131. runbooks/inventory/delete_s3_buckets_objects.py +169 -0
  132. runbooks/inventory/discovery.md +81 -0
  133. runbooks/inventory/draw_org_structure.py +748 -0
  134. runbooks/inventory/ec2_vpc_utils.py +341 -0
  135. runbooks/inventory/find_cfn_drift_detection.py +272 -0
  136. runbooks/inventory/find_cfn_orphaned_stacks.py +719 -0
  137. runbooks/inventory/find_cfn_stackset_drift.py +733 -0
  138. runbooks/inventory/find_ec2_security_groups.py +669 -0
  139. runbooks/inventory/find_landingzone_versions.py +201 -0
  140. runbooks/inventory/find_vpc_flow_logs.py +1221 -0
  141. runbooks/inventory/inventory.sh +659 -0
  142. runbooks/inventory/list_cfn_stacks.py +558 -0
  143. runbooks/inventory/list_cfn_stackset_operation_results.py +252 -0
  144. runbooks/inventory/list_cfn_stackset_operations.py +734 -0
  145. runbooks/inventory/list_cfn_stacksets.py +453 -0
  146. runbooks/inventory/list_config_recorders_delivery_channels.py +681 -0
  147. runbooks/inventory/list_ds_directories.py +354 -0
  148. runbooks/inventory/list_ec2_availability_zones.py +286 -0
  149. runbooks/inventory/list_ec2_ebs_volumes.py +244 -0
  150. runbooks/inventory/list_ec2_instances.py +425 -0
  151. runbooks/inventory/list_ecs_clusters_and_tasks.py +562 -0
  152. runbooks/inventory/list_elbs_load_balancers.py +411 -0
  153. runbooks/inventory/list_enis_network_interfaces.py +526 -0
  154. runbooks/inventory/list_guardduty_detectors.py +568 -0
  155. runbooks/inventory/list_iam_policies.py +404 -0
  156. runbooks/inventory/list_iam_roles.py +518 -0
  157. runbooks/inventory/list_iam_saml_providers.py +359 -0
  158. runbooks/inventory/list_lambda_functions.py +882 -0
  159. runbooks/inventory/list_org_accounts.py +446 -0
  160. runbooks/inventory/list_org_accounts_users.py +354 -0
  161. runbooks/inventory/list_rds_db_instances.py +406 -0
  162. runbooks/inventory/list_route53_hosted_zones.py +318 -0
  163. runbooks/inventory/list_servicecatalog_provisioned_products.py +575 -0
  164. runbooks/inventory/list_sns_topics.py +360 -0
  165. runbooks/inventory/list_ssm_parameters.py +402 -0
  166. runbooks/inventory/list_vpc_subnets.py +433 -0
  167. runbooks/inventory/list_vpcs.py +422 -0
  168. runbooks/inventory/lockdown_cfn_stackset_role.py +224 -0
  169. runbooks/inventory/models/__init__.py +24 -0
  170. runbooks/inventory/models/account.py +192 -0
  171. runbooks/inventory/models/inventory.py +309 -0
  172. runbooks/inventory/models/resource.py +247 -0
  173. runbooks/inventory/recover_cfn_stack_ids.py +205 -0
  174. runbooks/inventory/requirements.txt +12 -0
  175. runbooks/inventory/run_on_multi_accounts.py +211 -0
  176. runbooks/inventory/tests/common_test_data.py +3661 -0
  177. runbooks/inventory/tests/common_test_functions.py +204 -0
  178. runbooks/inventory/tests/setup.py +24 -0
  179. runbooks/inventory/tests/src.py +18 -0
  180. runbooks/inventory/tests/test_cfn_describe_stacks.py +208 -0
  181. runbooks/inventory/tests/test_ec2_describe_instances.py +162 -0
  182. runbooks/inventory/tests/test_inventory_modules.py +55 -0
  183. runbooks/inventory/tests/test_lambda_list_functions.py +86 -0
  184. runbooks/inventory/tests/test_moto_integration_example.py +273 -0
  185. runbooks/inventory/tests/test_org_list_accounts.py +49 -0
  186. runbooks/inventory/update_aws_actions.py +173 -0
  187. runbooks/inventory/update_cfn_stacksets.py +1215 -0
  188. runbooks/inventory/update_cloudwatch_logs_retention_policy.py +294 -0
  189. runbooks/inventory/update_iam_roles_cross_accounts.py +478 -0
  190. runbooks/inventory/update_s3_public_access_block.py +539 -0
  191. runbooks/inventory/utils/__init__.py +23 -0
  192. runbooks/inventory/utils/aws_helpers.py +510 -0
  193. runbooks/inventory/utils/threading_utils.py +493 -0
  194. runbooks/inventory/utils/validation.py +682 -0
  195. runbooks/inventory/verify_ec2_security_groups.py +1430 -0
  196. runbooks/main.py +1004 -0
  197. runbooks/organizations/__init__.py +12 -0
  198. runbooks/organizations/manager.py +374 -0
  199. runbooks/security/README.md +447 -0
  200. runbooks/security/__init__.py +71 -0
  201. runbooks/{security_baseline → security}/checklist/alternate_contacts.py +8 -1
  202. runbooks/{security_baseline → security}/checklist/bucket_public_access.py +4 -1
  203. runbooks/{security_baseline → security}/checklist/cloudwatch_alarm_configuration.py +9 -2
  204. runbooks/{security_baseline → security}/checklist/guardduty_enabled.py +9 -2
  205. runbooks/{security_baseline → security}/checklist/multi_region_instance_usage.py +5 -1
  206. runbooks/{security_baseline → security}/checklist/root_access_key.py +6 -1
  207. runbooks/{security_baseline → security}/config-origin.json +1 -1
  208. runbooks/{security_baseline → security}/config.json +1 -1
  209. runbooks/{security_baseline → security}/permission.json +1 -1
  210. runbooks/{security_baseline → security}/report_generator.py +10 -2
  211. runbooks/{security_baseline → security}/report_template_en.html +7 -7
  212. runbooks/{security_baseline → security}/report_template_jp.html +7 -7
  213. runbooks/{security_baseline → security}/report_template_kr.html +12 -12
  214. runbooks/{security_baseline → security}/report_template_vn.html +7 -7
  215. runbooks/{security_baseline → security}/run_script.py +8 -2
  216. runbooks/{security_baseline → security}/security_baseline_tester.py +12 -4
  217. runbooks/{security_baseline → security}/utils/common.py +5 -1
  218. runbooks/utils/__init__.py +204 -0
  219. runbooks-0.7.0.dist-info/METADATA +375 -0
  220. runbooks-0.7.0.dist-info/RECORD +249 -0
  221. {runbooks-0.2.5.dist-info → runbooks-0.7.0.dist-info}/WHEEL +1 -1
  222. runbooks-0.7.0.dist-info/entry_points.txt +7 -0
  223. runbooks-0.7.0.dist-info/licenses/LICENSE +201 -0
  224. runbooks-0.7.0.dist-info/top_level.txt +3 -0
  225. runbooks/python101/calculator.py +0 -34
  226. runbooks/python101/config.py +0 -1
  227. runbooks/python101/exceptions.py +0 -16
  228. runbooks/python101/file_manager.py +0 -218
  229. runbooks/python101/toolkit.py +0 -153
  230. runbooks-0.2.5.dist-info/METADATA +0 -439
  231. runbooks-0.2.5.dist-info/RECORD +0 -61
  232. runbooks-0.2.5.dist-info/entry_points.txt +0 -3
  233. runbooks-0.2.5.dist-info/top_level.txt +0 -1
  234. /runbooks/{security_baseline/__init__.py → inventory/tests/script_test_data.py} +0 -0
  235. /runbooks/{security_baseline → security}/checklist/__init__.py +0 -0
  236. /runbooks/{security_baseline → security}/checklist/account_level_bucket_public_access.py +0 -0
  237. /runbooks/{security_baseline → security}/checklist/direct_attached_policy.py +0 -0
  238. /runbooks/{security_baseline → security}/checklist/iam_password_policy.py +0 -0
  239. /runbooks/{security_baseline → security}/checklist/iam_user_mfa.py +0 -0
  240. /runbooks/{security_baseline → security}/checklist/multi_region_trail.py +0 -0
  241. /runbooks/{security_baseline → security}/checklist/root_mfa.py +0 -0
  242. /runbooks/{security_baseline → security}/checklist/root_usage.py +0 -0
  243. /runbooks/{security_baseline → security}/checklist/trail_enabled.py +0 -0
  244. /runbooks/{security_baseline → security}/checklist/trusted_advisor.py +0 -0
  245. /runbooks/{security_baseline → security}/utils/__init__.py +0 -0
  246. /runbooks/{security_baseline → security}/utils/enums.py +0 -0
  247. /runbooks/{security_baseline → security}/utils/language.py +0 -0
  248. /runbooks/{security_baseline → security}/utils/level_const.py +0 -0
  249. /runbooks/{security_baseline → security}/utils/permission_list.py +0 -0
@@ -0,0 +1,882 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ AWS Lambda Function Inventory and Runtime Management Tool
4
+
5
+ A comprehensive Lambda function discovery and runtime management tool for multi-account
6
+ AWS Organizations that provides detailed serverless infrastructure visibility and
7
+ automated runtime upgrade capabilities across all accounts and regions.
8
+
9
+ **AWS API Mapping**:
10
+ - `boto3.client('lambda').list_functions()`
11
+ - `boto3.client('lambda').update_function_configuration()`
12
+
13
+ **RUNTIME UPGRADE CAPABILITY**: This script can perform LIVE updates to Lambda function
14
+ runtimes, making it critical for security patching and compliance maintenance.
15
+
16
+ Features:
17
+ - Multi-account Lambda function discovery via AWS Organizations
18
+ - Runtime version inventory and compliance analysis
19
+ - Automated runtime upgrade with safety controls
20
+ - Fragment-based function filtering for targeted operations
21
+ - Comprehensive error handling and rollback capabilities
22
+ - Runtime usage analytics and deprecation warnings
23
+
24
+ Serverless Governance Use Cases:
25
+ - Runtime compliance auditing and security patching
26
+ - Automated migration to supported Lambda runtimes
27
+ - Function inventory and dependency analysis
28
+ - Cost optimization through runtime efficiency assessment
29
+ - Security vulnerability remediation (deprecated runtimes)
30
+ - Compliance validation for regulatory requirements
31
+
32
+ Compatibility:
33
+ - AWS Organizations with cross-account roles
34
+ - AWS Control Tower managed accounts
35
+ - Standalone AWS accounts
36
+ - All AWS regions including opt-in regions
37
+ - All Lambda runtime families (Python, Node.js, Java, .NET, Go, Ruby)
38
+
39
+ **SECURITY WARNING**: Runtime updates can affect function behavior:
40
+ - Test runtime changes in non-production environments first
41
+ - Verify function compatibility with target runtime
42
+ - Monitor function execution after runtime upgrades
43
+ - Maintain proper backup and rollback procedures
44
+
45
+ Example:
46
+ Discover all Lambda functions across organization:
47
+ ```bash
48
+ python list_lambda_functions.py --profile my-org-profile
49
+ ```
50
+
51
+ Find functions with deprecated Python 3.8 runtime:
52
+ ```bash
53
+ python list_lambda_functions.py --profile my-profile --runtime python3.8
54
+ ```
55
+
56
+ Upgrade Python 3.8 functions to Python 3.11:
57
+ ```bash
58
+ python list_lambda_functions.py --profile my-profile \
59
+ --runtime python3.8 --new_runtime python3.11 --fix
60
+ ```
61
+
62
+ Requirements:
63
+ - IAM permissions: `lambda:ListFunctions`, `lambda:UpdateFunctionConfiguration`, `sts:AssumeRole`
64
+ - AWS Organizations access (for multi-account scanning)
65
+ - Python 3.8+ with required dependencies
66
+
67
+ Author:
68
+ AWS Cloud Foundations Team
69
+
70
+ Version:
71
+ 2024.06.05
72
+ """
73
+
74
+ import logging
75
+ import sys
76
+ from os.path import split
77
+ from queue import Queue
78
+ from threading import Thread
79
+ from time import time
80
+
81
+ import boto3
82
+ import Inventory_Modules
83
+ from ArgumentsClass import CommonArguments
84
+ from botocore.exceptions import ClientError
85
+ from colorama import Fore, init
86
+ from Inventory_Modules import display_results, get_all_credentials
87
+ from tqdm.auto import tqdm
88
+
89
+ init()
90
+ __version__ = "2024.06.05"
91
+
92
+ ERASE_LINE = "\x1b[2K"
93
+ begin_time = time()
94
+
95
+
96
+ # TODO: Need a table at the bottom that creates a summary of the runtimes used, so that action can be taken if older runtimes are in use.
97
+ # TODO: Add runtime deprecation warnings based on AWS Lambda runtime support lifecycle
98
+ # TODO: Implement batch update capabilities for large-scale runtime migrations
99
+ # TODO: Add function dependency analysis to identify potential compatibility issues
100
+
101
+
102
+ ##################
103
+ # Functions
104
+ ##################
105
+ def parse_args(args):
106
+ """
107
+ Parse and validate command-line arguments for Lambda function inventory and runtime management.
108
+
109
+ Configures the argument parser with Lambda-specific options for comprehensive
110
+ serverless function discovery and automated runtime upgrade capabilities.
111
+ Uses the standardized CommonArguments framework for consistency.
112
+
113
+ Args:
114
+ args (list): Command-line arguments to parse (typically sys.argv[1:])
115
+
116
+ Returns:
117
+ argparse.Namespace: Parsed arguments containing:
118
+ - Profiles: AWS profiles for multi-account serverless discovery
119
+ - Regions: Target AWS regions for Lambda enumeration
120
+ - AccessRoles: Cross-account roles for Organizations access
121
+ - Runtime: Target runtime(s) to filter for (e.g., ['python3.8', 'nodejs14.x'])
122
+ - NewRuntime: Replacement runtime for upgrade operations
123
+ - Fragment: Function name fragment for targeted filtering
124
+ - pFixRun: Boolean flag to enable live runtime updates
125
+ - pDeletionRun: Boolean flag to enable function deletion
126
+ - Other standard framework arguments
127
+
128
+ Runtime Management Arguments:
129
+ --runtime: Critical for identifying functions with specific runtimes
130
+ - Supports multiple runtime specifications
131
+ - Essential for compliance and security patching
132
+ - Examples: python3.8, nodejs14.x, java11, dotnetcore3.1
133
+
134
+ --new_runtime: Target runtime for automated upgrades
135
+ - Must be compatible with existing function code
136
+ - Requires thorough testing before production use
137
+ - Examples: python3.11, nodejs18.x, java17
138
+
139
+ --fix: DANGEROUS flag enabling live runtime updates
140
+ - Performs immediate function configuration changes
141
+ - Cannot be undone without manual intervention
142
+ - Requires comprehensive testing and validation
143
+
144
+ Serverless Operations Use Cases:
145
+ - Runtime compliance auditing: Identify deprecated or vulnerable runtimes
146
+ - Security patching: Automated migration to supported runtime versions
147
+ - Function inventory: Complete Lambda function asset management
148
+ - Cost optimization: Runtime performance and efficiency analysis
149
+ - Dependency analysis: Function relationship and impact assessment
150
+ """
151
+ script_path, script_name = split(sys.argv[0])
152
+ parser = CommonArguments()
153
+ parser.multiprofile() # Allows for a single profile to be specified
154
+ parser.multiregion() # Allows for multiple regions to be specified at the command line
155
+ parser.fragment() # Allows for specifying a string fragment to be looked for
156
+ parser.extendedargs()
157
+ parser.rootOnly()
158
+ parser.save_to_file()
159
+ parser.timing()
160
+ parser.rolestouse()
161
+ parser.fix()
162
+ parser.deletion()
163
+ parser.verbosity() # Allows for the verbosity to be handled.
164
+ parser.version(__version__)
165
+ local = parser.my_parser.add_argument_group(script_name, "Parameters specific to this script")
166
+ local.add_argument(
167
+ "--runtime",
168
+ "--run",
169
+ "--rt",
170
+ dest="Runtime",
171
+ nargs="*",
172
+ metavar="language and version",
173
+ default=None,
174
+ help="Language runtime(s) you're looking for within your accounts",
175
+ )
176
+ local.add_argument(
177
+ "--new_runtime",
178
+ "--new",
179
+ "--new-runtime",
180
+ dest="NewRuntime",
181
+ metavar="language and version",
182
+ default=None,
183
+ help="Language runtime(s) you will replace what you've found with... ",
184
+ )
185
+ return parser.my_parser.parse_args(args)
186
+
187
+
188
+ def left(s, amount):
189
+ """
190
+ Extract leftmost characters from string for parsing and analysis.
191
+
192
+ Utility function for string manipulation in Lambda function name
193
+ and configuration parsing operations.
194
+
195
+ Args:
196
+ s (str): Source string to extract from
197
+ amount (int): Number of characters to extract from left
198
+
199
+ Returns:
200
+ str: Left substring of specified length
201
+ """
202
+ return s[:amount]
203
+
204
+
205
+ def right(s, amount):
206
+ """
207
+ Extract rightmost characters from string for parsing and analysis.
208
+
209
+ Utility function for string manipulation in Lambda function name
210
+ and configuration parsing operations.
211
+
212
+ Args:
213
+ s (str): Source string to extract from
214
+ amount (int): Number of characters to extract from right
215
+
216
+ Returns:
217
+ str: Right substring of specified length
218
+ """
219
+ return s[-amount:]
220
+
221
+
222
+ def mid(s, offset, amount):
223
+ """
224
+ Extract middle characters from string for parsing and analysis.
225
+
226
+ Utility function for string manipulation in Lambda function name
227
+ and configuration parsing operations.
228
+
229
+ Args:
230
+ s (str): Source string to extract from
231
+ offset (int): Starting position (1-indexed)
232
+ amount (int): Number of characters to extract
233
+
234
+ Returns:
235
+ str: Middle substring of specified length and position
236
+ """
237
+ return s[offset - 1 : offset + amount - 1]
238
+
239
+
240
+ def fix_runtime(CredentialList, new_runtime):
241
+ """
242
+ Execute multi-threaded Lambda function runtime upgrades across AWS accounts.
243
+
244
+ **CRITICAL FUNCTION**: Performs LIVE updates to Lambda function configurations,
245
+ directly modifying production serverless infrastructure. Essential for security
246
+ patching and compliance maintenance, but requires extreme caution.
247
+
248
+ Args:
249
+ CredentialList (list): List of functions requiring runtime updates with credentials
250
+ new_runtime (str): Target runtime version for upgrade (e.g., 'python3.11')
251
+
252
+ **SECURITY WARNINGS**:
253
+ - Performs IMMEDIATE and IRREVERSIBLE runtime changes
254
+ - Can break function execution if runtime compatibility issues exist
255
+ - May affect function performance and memory utilization
256
+ - Requires thorough testing before production deployment
257
+ - Should be executed during maintenance windows
258
+
259
+ Runtime Compatibility Considerations:
260
+ - Verify code compatibility with target runtime version
261
+ - Test all function dependencies and external libraries
262
+ - Validate function behavior with new runtime characteristics
263
+ - Consider performance implications of runtime changes
264
+ - Plan rollback strategy for failed upgrades
265
+
266
+ Threading Architecture:
267
+ - Uses worker thread pool for concurrent runtime updates
268
+ - Implements rate limiting to avoid API throttling
269
+ - Comprehensive error handling and retry logic
270
+ - Detailed logging for audit and troubleshooting
271
+
272
+ Enterprise Use Cases:
273
+ - Security patching: Migrate from deprecated/vulnerable runtimes
274
+ - Compliance maintenance: Ensure supported runtime versions
275
+ - Performance optimization: Upgrade to more efficient runtimes
276
+ - Cost optimization: Leverage improved runtime pricing models
277
+ """
278
+ from time import sleep
279
+
280
+ class UpdateRuntime(Thread):
281
+ """
282
+ Worker thread for concurrent Lambda function runtime updates.
283
+
284
+ **DESTRUCTIVE OPERATIONS**: Each worker thread performs live runtime
285
+ modifications on production Lambda functions. Implements comprehensive
286
+ error handling and logging for enterprise-grade safety.
287
+
288
+ Runtime Update Capabilities:
289
+ - Live function configuration modification
290
+ - Runtime version validation and compatibility checking
291
+ - Comprehensive error handling and rollback logging
292
+ - API throttling and retry logic
293
+ - Detailed audit trail for compliance
294
+ """
295
+
296
+ def __init__(self, queue):
297
+ """
298
+ Initialize worker thread with reference to shared work queue.
299
+
300
+ Args:
301
+ queue (Queue): Thread-safe queue containing runtime update work items
302
+ """
303
+ Thread.__init__(self)
304
+ self.queue = queue
305
+
306
+ def run(self):
307
+ """
308
+ Main worker thread execution loop for Lambda runtime updates.
309
+
310
+ **CRITICAL OPERATION**: Continuously processes functions from queue,
311
+ performs live runtime updates via AWS Lambda APIs, and maintains
312
+ comprehensive audit logging for compliance and troubleshooting.
313
+ """
314
+ while True:
315
+ # Get runtime update work item from thread-safe queue
316
+ c_account_credentials, c_function_name, c_new_runtime = self.queue.get()
317
+ Updated_Function = {}
318
+ logging.info(f"De-queued info for account {c_account_credentials['AccountId']}")
319
+ Success = False
320
+
321
+ try:
322
+ # CRITICAL: Attempting live runtime modification
323
+ logging.warning(f"ATTEMPTING LIVE RUNTIME UPDATE: {c_function_name} to {c_new_runtime}")
324
+
325
+ # Establish AWS session for Lambda API operations
326
+ session = boto3.Session(
327
+ aws_access_key_id=c_account_credentials["AccessKeyId"],
328
+ aws_secret_access_key=c_account_credentials["SecretAccessKey"],
329
+ aws_session_token=c_account_credentials["SessionToken"],
330
+ region_name=c_account_credentials["Region"],
331
+ )
332
+ client = session.client("lambda")
333
+ logging.info(f"Updating function {c_function_name} to runtime {c_new_runtime}")
334
+ Updated_Function = client.update_function_configuration(
335
+ FunctionName=c_function_name, Runtime=c_new_runtime
336
+ )
337
+ sleep(3)
338
+ Success = (
339
+ client.get_function_configuration(FunctionName=c_function_name)["LastUpdateStatus"]
340
+ == "Successful"
341
+ )
342
+ while not Success:
343
+ Status = client.get_function_configuration(FunctionName=c_function_name)["LastUpdateStatus"]
344
+ Success = True if Status == "Successful" else "False"
345
+ if Status == "InProgress":
346
+ sleep(3)
347
+ logging.info(f"Sleeping to allow {c_function_name} to update to runtime {c_new_runtime}")
348
+ elif Status == "Failed":
349
+ raise RuntimeError(f"Runtime update for {c_function_name} to {c_new_runtime} failed")
350
+ except TypeError as my_Error:
351
+ logging.info(f"Error: {my_Error}")
352
+ continue
353
+ except ClientError as my_Error:
354
+ if "AuthFailure" in str(my_Error):
355
+ logging.error(f"Account {c_account_credentials['AccountId']}: Authorization Failure")
356
+ continue
357
+ except KeyError as my_Error:
358
+ logging.error(f"Account Access failed - trying to access {c_account_credentials['AccountId']}")
359
+ logging.info(f"Actual Error: {my_Error}")
360
+ continue
361
+ finally:
362
+ if Success:
363
+ Updated_Function["MgmtAccount"] = c_account_credentials["MgmtAccount"]
364
+ Updated_Function["AccountId"] = c_account_credentials["AccountId"]
365
+ Updated_Function["Region"] = c_account_credentials["Region"]
366
+ Rolet = Updated_Function["Role"]
367
+ Updated_Function["Role"] = mid(Rolet, Rolet.find("/") + 2, len(Rolet))
368
+ FixedFuncs.extend(Updated_Function)
369
+ self.queue.task_done()
370
+
371
+ FixedFuncs = []
372
+ PlaceCount = 0
373
+ PlacesToLook = len(CredentialList)
374
+ WorkerThreads = min(len(CredentialList), 25)
375
+
376
+ checkqueue = Queue()
377
+
378
+ for x in range(WorkerThreads):
379
+ worker = UpdateRuntime(checkqueue)
380
+ # Setting daemon to True will let the main thread exit even though the workers are blocking
381
+ worker.daemon = True
382
+ worker.start()
383
+
384
+ for credential in CredentialList:
385
+ logging.info(f"Connecting to account {credential['AccountId']}")
386
+ try:
387
+ print(
388
+ f"{ERASE_LINE}Queuing function {credential['FunctionName']} in account {credential['AccountId']} in region {credential['Region']}",
389
+ end="\r",
390
+ )
391
+ checkqueue.put((credential, credential["FunctionName"], new_runtime))
392
+ PlaceCount += 1
393
+ except ClientError as my_Error:
394
+ if "AuthFailure" in str(my_Error):
395
+ logging.error(
396
+ f"Authorization Failure accessing account {credential['AccountId']} in {credential['Region']} region"
397
+ )
398
+ logging.error(f"It's possible that the region {credential['Region']} hasn't been opted-into")
399
+ pass
400
+ checkqueue.join()
401
+ return FixedFuncs
402
+
403
+
404
+ def check_accounts_for_functions(CredentialList, fFragments=None):
405
+ """
406
+ Execute multi-threaded Lambda function discovery across enterprise AWS accounts and regions.
407
+
408
+ Performs comprehensive serverless function inventory using optimized concurrent processing
409
+ to discover all Lambda functions across multiple AWS accounts and regions. Implements
410
+ enterprise-grade error handling, progress tracking, and credential management for
411
+ large-scale organizational serverless infrastructure analysis.
412
+
413
+ Args:
414
+ CredentialList (list): List of validated AWS credentials containing:
415
+ - AccountId: Target AWS account identifier for Lambda discovery
416
+ - Region: AWS region for serverless function enumeration
417
+ - Credentials: Temporary AWS credentials for API access
418
+ - MgmtAccount: Management account for organizational context
419
+
420
+ fFragments (list, optional): Function name fragments for targeted filtering:
421
+ - Enables focused discovery based on naming patterns
422
+ - Supports wildcard matching for flexible function identification
423
+ - Default None discovers all functions without filtering
424
+
425
+ Returns:
426
+ list: Comprehensive Lambda function inventory containing:
427
+ - Function metadata: Name, runtime, role, configuration details
428
+ - Account context: AccountId, MgmtAccount for organizational mapping
429
+ - Regional information: AWS region for geographic distribution analysis
430
+ - Access credentials: For potential runtime update operations
431
+
432
+ Multi-Threading Architecture:
433
+ - Concurrent account processing using optimized worker thread pool
434
+ - Queue-based work distribution for efficient resource utilization
435
+ - Progress tracking through tqdm for operational visibility
436
+ - Thread-safe result aggregation with comprehensive error handling
437
+ - Regional API optimization reducing cross-region latency impacts
438
+
439
+ Enterprise Serverless Discovery Features:
440
+ - Complete Lambda function asset inventory across organizational hierarchy
441
+ - Runtime version analysis for compliance and security assessment
442
+ - Function role and permission analysis for security auditing
443
+ - Memory and timeout configuration analysis for cost optimization
444
+ - Event source mapping discovery for architectural analysis
445
+
446
+ Performance Optimizations:
447
+ - Intelligent thread pool sizing based on credential set complexity (max 25 threads)
448
+ - AWS API optimization with connection pooling and retry logic
449
+ - Memory-efficient processing for large-scale serverless inventories
450
+ - Concurrent processing patterns optimized for AWS Lambda API rate limiting
451
+ - Real-time progress tracking for operational visibility during discovery
452
+
453
+ Error Handling & Resilience:
454
+ - Comprehensive AWS API error handling with retry and backoff logic
455
+ - Thread-safe error aggregation preventing batch processing failures
456
+ - Individual account failure isolation allowing continued processing
457
+ - Access permission validation with graceful degradation patterns
458
+ - Network connectivity resilience with automatic retry mechanisms
459
+
460
+ Security & Compliance Integration:
461
+ - Secure credential handling with temporary access patterns
462
+ - Comprehensive audit logging for security and compliance tracking
463
+ - Access control validation ensuring proper authorization levels
464
+ - Function security configuration analysis for vulnerability assessment
465
+ - Role and permission mapping for least privilege validation
466
+ """
467
+
468
+ class FindFunctions(Thread):
469
+ """
470
+ Thread-safe Lambda function discovery worker for concurrent multi-account processing.
471
+
472
+ Implements enterprise-grade concurrent processing for Lambda function discovery
473
+ and analysis across multiple AWS accounts and regions. Provides thread-safe
474
+ result aggregation with comprehensive error handling and operational resilience
475
+ for large-scale organizational serverless infrastructure audits.
476
+ """
477
+
478
+ def __init__(self, queue):
479
+ """
480
+ Initialize Lambda function discovery thread with work queue integration.
481
+
482
+ Args:
483
+ queue: Thread-safe work queue containing credential sets for processing
484
+ """
485
+ Thread.__init__(self)
486
+ self.queue = queue
487
+
488
+ def run(self):
489
+ """
490
+ Execute Lambda function discovery for queued account credentials with comprehensive error handling.
491
+
492
+ Processes account credentials from the thread-safe work queue, performing detailed
493
+ Lambda function discovery and analysis for each account-region combination with
494
+ fragment-based filtering. Implements robust error handling, logging, and result
495
+ aggregation patterns for enterprise-scale serverless infrastructure audits.
496
+ """
497
+ while True:
498
+ # Retrieve account credentials and fragment filters from thread-safe work queue
499
+ c_account_credentials, c_fragment_list = self.queue.get()
500
+ pbar.update() # Update progress bar for operational visibility
501
+ Functions = []
502
+ logging.info(f"De-queued info for account {c_account_credentials['AccountId']}")
503
+ try:
504
+ # Log Lambda function discovery initiation for audit trail
505
+ logging.info(f"Attempting to connect to {c_account_credentials['AccountId']}")
506
+
507
+ # Execute comprehensive Lambda function discovery with fragment filtering
508
+ Functions = Inventory_Modules.find_lambda_functions2(
509
+ c_account_credentials, c_account_credentials["Region"], c_fragment_list
510
+ )
511
+ except TypeError as my_Error:
512
+ # Handle AWS API data type conversion errors during Lambda function processing
513
+ logging.info(f"Error: {my_Error}")
514
+ continue # Continue processing other accounts despite individual failures
515
+ except ClientError as my_Error:
516
+ # Handle AWS API authorization and access errors with detailed logging
517
+ if "AuthFailure" in str(my_Error):
518
+ logging.error(f"Account {c_account_credentials['AccountId']}: Authorization Failure")
519
+ continue # Continue processing other accounts despite individual failures
520
+ except KeyError as my_Error:
521
+ # Handle credential or account access configuration errors
522
+ logging.error(f"Account Access failed - trying to access {c_account_credentials['AccountId']}")
523
+ logging.info(f"Actual Error: {my_Error}")
524
+ continue # Continue processing other accounts despite individual failures
525
+ finally:
526
+ # Enrich discovered Lambda functions with organizational and credential context
527
+ if len(Functions) > 0:
528
+ for _ in range(len(Functions)):
529
+ # Add organizational context for enterprise reporting and management
530
+ Functions[_]["MgmtAccount"] = c_account_credentials["MgmtAccount"]
531
+ Functions[_]["AccountId"] = c_account_credentials["AccountId"]
532
+ Functions[_]["Region"] = c_account_credentials["Region"]
533
+
534
+ # Preserve access credentials for potential runtime update operations
535
+ Functions[_]["AccessKeyId"] = c_account_credentials["AccessKeyId"]
536
+ Functions[_]["SecretAccessKey"] = c_account_credentials["SecretAccessKey"]
537
+ Functions[_]["SessionToken"] = c_account_credentials["SessionToken"]
538
+
539
+ # Extract and format IAM role name for cleaner display
540
+ Rolet = Functions[_]["Role"]
541
+ Functions[_]["Role"] = mid(Rolet, Rolet.find("/") + 2, len(Rolet))
542
+
543
+ # Thread-safe aggregation of discovered Lambda functions
544
+ AllFuncs.extend(Functions)
545
+
546
+ # Signal task completion for thread-safe work queue management
547
+ self.queue.task_done()
548
+
549
+ # Initialize thread-safe result aggregation for enterprise-scale Lambda function inventory
550
+ AllFuncs = [] # Global Lambda function inventory with comprehensive serverless metadata
551
+
552
+ # Optimize thread pool size for efficient processing while respecting AWS API limits
553
+ WorkerThreads = min(len(CredentialList), 25) # Cap at 25 threads for Lambda API rate limiting
554
+
555
+ # Initialize thread-safe work queue for concurrent account processing
556
+ checkqueue = Queue()
557
+
558
+ # Initialize progress tracking for operational visibility during discovery
559
+ pbar = tqdm(
560
+ desc=f"Finding instances from {len(CredentialList)} accounts / regions",
561
+ total=len(CredentialList),
562
+ unit=" locations",
563
+ )
564
+
565
+ # Initialize multi-threaded Lambda function discovery worker pool
566
+ for x in range(WorkerThreads):
567
+ worker = FindFunctions(checkqueue)
568
+ # Enable graceful shutdown with main thread termination for enterprise operational safety
569
+ worker.daemon = True
570
+ worker.start() # Begin concurrent Lambda function discovery processing
571
+
572
+ # Populate work queue with account credentials for distributed serverless discovery
573
+ for credential in CredentialList:
574
+ logging.info(f"Connecting to account {credential['AccountId']}")
575
+ try:
576
+ # Log work queue population for operational audit trail
577
+ logging.info(
578
+ f"{ERASE_LINE}Queuing account {credential['AccountId']} in region {credential['Region']}", end="\r"
579
+ )
580
+ # Add credential and fragment filter to processing queue
581
+ checkqueue.put((credential, fFragments))
582
+ except ClientError as my_Error:
583
+ # Handle AWS API authorization failures during queue population
584
+ if "AuthFailure" in str(my_Error):
585
+ logging.error(
586
+ f"Authorization Failure accessing account {credential['AccountId']} in {credential['Region']} region"
587
+ )
588
+ logging.error(f"It's possible that the region {credential['Region']} hasn't been opted-into")
589
+ pass # Continue processing remaining accounts despite individual failures
590
+
591
+ # Wait for all Lambda function discovery tasks to complete before result aggregation
592
+ checkqueue.join()
593
+
594
+ # Return comprehensive Lambda function inventory with enterprise serverless metadata
595
+ return AllFuncs
596
+
597
+
598
+ def collect_all_my_functions(AllCredentials, fFragments, fverbose=50):
599
+ """
600
+ Orchestrate comprehensive Lambda function collection and organize results for enterprise reporting.
601
+
602
+ Coordinates multi-threaded Lambda function discovery across organizational accounts
603
+ and regions, then sorts and formats results for enterprise serverless infrastructure
604
+ management and reporting. Provides operational visibility through configurable
605
+ verbosity controls and structured result organization.
606
+
607
+ Args:
608
+ AllCredentials (list): Complete list of validated AWS credentials containing:
609
+ - Account credentials for cross-account Lambda function access
610
+ - Regional configuration for comprehensive serverless coverage
611
+ - Management account context for organizational hierarchy mapping
612
+
613
+ fFragments (list): Function name fragments for targeted discovery filtering:
614
+ - Enables focused searches based on naming conventions
615
+ - Supports pattern matching for specific function categories
616
+ - Empty list discovers all functions without filtering
617
+
618
+ fverbose (int, optional): Logging verbosity level controlling output detail:
619
+ - Values < 50: Enable summary statistics and progress information
620
+ - Values >= 50: Minimal output for automated processing
621
+ - Default 50 provides balanced operational visibility
622
+
623
+ Returns:
624
+ list: Sorted Lambda function inventory organized by enterprise hierarchy:
625
+ - Primary sort: Management Account for organizational structure
626
+ - Secondary sort: AccountId for account-level grouping
627
+ - Tertiary sort: Region for geographic distribution analysis
628
+ - Final sort: FunctionName for alphabetical function organization
629
+
630
+ Enterprise Serverless Management Features:
631
+ - Hierarchical function organization for multi-account governance
632
+ - Geographic distribution analysis for compliance and performance
633
+ - Structured result formatting for integration with enterprise tools
634
+ - Operational summary reporting for executive visibility
635
+ - Scalable processing architecture for large serverless estates
636
+
637
+ Integration Capabilities:
638
+ - Compatible with enterprise reporting and monitoring systems
639
+ - Structured data format for CSV export and database integration
640
+ - Consistent sorting for reliable report generation
641
+ - Configurable verbosity for different operational contexts
642
+ - Ready for runtime analysis and compliance assessment workflows
643
+ """
644
+ # Execute comprehensive multi-threaded Lambda function discovery
645
+ AllFunctions = check_accounts_for_functions(AllCredentials, fFragments)
646
+
647
+ # Sort functions by enterprise hierarchy for structured reporting and management
648
+ sorted_AllFunctions = sorted(
649
+ AllFunctions, key=lambda k: (k["MgmtAccount"], k["AccountId"], k["Region"], k["FunctionName"])
650
+ )
651
+
652
+ # Provide operational summary when verbose logging is enabled
653
+ if fverbose < 50:
654
+ print(f"We found {len(AllFunctions)} functions in {len(AllCredentials)} places")
655
+
656
+ # Return enterprise-organized Lambda function inventory
657
+ return sorted_AllFunctions
658
+
659
+
660
+ def fix_my_functions(fAllFunctions, fRuntime, fNewRuntime, fForceDelete, fTiming):
661
+ """
662
+ Orchestrate Lambda function runtime upgrade operations with comprehensive safety controls.
663
+
664
+ **CRITICAL FUNCTION**: Manages live Lambda function runtime modifications with enterprise-grade
665
+ safety controls, user confirmation workflows, and performance timing. Essential for security
666
+ patching and compliance maintenance across organizational serverless infrastructure.
667
+
668
+ Args:
669
+ fAllFunctions (list): Lambda functions requiring runtime updates containing:
670
+ - Function metadata and current runtime configuration
671
+ - AWS credentials for runtime modification operations
672
+ - Account and regional context for enterprise tracking
673
+
674
+ fRuntime (str): Current runtime version being replaced (e.g., 'python3.8')
675
+ fNewRuntime (str): Target runtime version for upgrade (e.g., 'python3.11')
676
+ fForceDelete (bool): Override safety confirmation for automated operations
677
+ fTiming (bool): Enable performance timing for operational metrics
678
+
679
+ Returns:
680
+ list|str: Either updated function list or error message string:
681
+ - Success: List of successfully updated Lambda functions
682
+ - Failure: String message indicating no functions were modified
683
+
684
+ **ENTERPRISE SAFETY CONTROLS**:
685
+ - Mandatory target runtime validation preventing incomplete operations
686
+ - Interactive user confirmation for destructive operations (unless forced)
687
+ - Comprehensive error handling and rollback logging
688
+ - Performance timing for operational SLA compliance
689
+ - Audit trail generation for enterprise compliance requirements
690
+
691
+ Runtime Upgrade Safety Features:
692
+ - Pre-validation: Ensures target runtime is specified before processing
693
+ - User Confirmation: Interactive safety check for non-automated operations
694
+ - Force Override: Automated operation support with comprehensive logging
695
+ - Performance Monitoring: Operation timing for SLA and capacity planning
696
+ - Error Recovery: Graceful failure handling with detailed diagnostics
697
+
698
+ Enterprise Operational Workflows:
699
+ - Security Patching: Automated migration from vulnerable runtime versions
700
+ - Compliance Maintenance: Bulk runtime updates for regulatory requirements
701
+ - Performance Optimization: Upgrade to more efficient runtime versions
702
+ - Cost Optimization: Migration to cost-effective runtime configurations
703
+ - Deprecation Management: Proactive migration from end-of-life runtimes
704
+
705
+ **OPERATIONAL WARNINGS**:
706
+ - Runtime changes are IMMEDIATE and IRREVERSIBLE
707
+ - Function behavior may change with runtime version modifications
708
+ - Comprehensive testing required before production deployment
709
+ - Maintenance windows recommended for large-scale updates
710
+ - Rollback procedures must be planned and tested in advance
711
+ """
712
+ # Initialize performance timing for operational metrics and SLA tracking
713
+ begin_fix_time = time()
714
+
715
+ # Validate target runtime specification to prevent incomplete operations
716
+ if fNewRuntime is None:
717
+ print(
718
+ f"You provided the parameter at the command line to *fix* errors found, but didn't supply a new runtime to use, so exiting now... "
719
+ )
720
+ sys.exit(8) # Exit with error code for automation and monitoring systems
721
+
722
+ # Execute safety confirmation workflow based on force flag configuration
723
+ elif not fForceDelete:
724
+ print(f"You provided the parameter at the command line to *fix* errors found")
725
+ # Interactive safety confirmation for destructive runtime modification operations
726
+ ReallyDelete = input("Having seen what will change, are you still sure? (y/n): ") in ["y", "Y", "Yes", "yes"]
727
+ elif fForceDelete:
728
+ print(
729
+ f"You provided the parameter at the command line to *fix* errors found, as well as FORCING this change to happen... "
730
+ )
731
+ ReallyDelete = True # Override safety checks for automated operational workflows
732
+ else:
733
+ ReallyDelete = False
734
+
735
+ # Execute runtime upgrade operations based on safety confirmation results
736
+ if ReallyDelete:
737
+ print(f"Updating Runtime for all functions found from {fRuntime} to {fNewRuntime}")
738
+ # CRITICAL: Perform live Lambda function runtime modifications
739
+ return_response = fix_runtime(fAllFunctions, fNewRuntime)
740
+ else:
741
+ return_response = "No functions were remediated."
742
+
743
+ # Display performance timing for operational optimization and SLA compliance
744
+ if fTiming:
745
+ print(ERASE_LINE)
746
+ print(
747
+ f"{Fore.GREEN}Fixing {len(return_response)} functions took {time() - begin_fix_time:.3f} seconds{Fore.RESET}"
748
+ )
749
+
750
+ # Return operation results for enterprise reporting and audit trail
751
+ return return_response
752
+
753
+
754
+ ##################
755
+ # Main execution entry point for enterprise Lambda function inventory and runtime management
756
+ ##################
757
+
758
+ if __name__ == "__main__":
759
+ """
760
+ Main orchestration for comprehensive Lambda function discovery, analysis, and runtime management.
761
+
762
+ Coordinates multi-account, multi-region serverless infrastructure inventory with specialized
763
+ support for runtime upgrade operations and enterprise serverless governance workflows.
764
+ Implements comprehensive safety controls for production runtime modifications.
765
+ """
766
+ # Parse enterprise command-line arguments with Lambda-specific runtime management options
767
+ args = parse_args(sys.argv[1:])
768
+
769
+ # Extract configuration parameters for multi-account serverless discovery and management
770
+ pProfiles = args.Profiles # AWS profile list for federated serverless access
771
+ pRegionList = args.Regions # Target regions for Lambda function enumeration
772
+ pFragments = args.Fragments # Function name fragments for targeted discovery
773
+ pAccounts = args.Accounts # Specific account targeting for focused operations
774
+ pFix = args.Fix # CRITICAL: Enable live runtime modification operations
775
+ pForceDelete = args.Force # Override safety confirmations for automated workflows
776
+ pSaveFilename = args.Filename # CSV export file for enterprise reporting
777
+ pRuntime = args.Runtime # Target runtime(s) for compliance filtering
778
+ pNewRuntime = args.NewRuntime # Replacement runtime for upgrade operations
779
+
780
+ # Optimize fragment filtering when runtime-specific discovery is requested
781
+ if pFragments == ["all"] and pRuntime is not None:
782
+ pFragments = [] # Clear default 'all' filter for runtime-specific searches
783
+
784
+ # Extract operational control parameters for enterprise Lambda management
785
+ pSkipAccounts = args.SkipAccounts # Account exclusion list for organizational policy
786
+ pSkipProfiles = args.SkipProfiles # Profile exclusion for credential optimization
787
+ pRootOnly = args.RootOnly # Organization root account limitation flag
788
+ pRoleList = args.AccessRoles # Cross-account roles for Organizations access
789
+ pTiming = args.Time # Performance timing for operational optimization
790
+ pverbose = args.loglevel # Logging verbosity for operational visibility
791
+
792
+ # Configure enterprise logging infrastructure for serverless operations
793
+ logging.basicConfig(level=pverbose, format="[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s")
794
+
795
+ # Configure enterprise Lambda function inventory report display formatting
796
+ display_dict = {
797
+ "MgmtAccount": {"DisplayOrder": 1, "Heading": "Mgmt Acct"}, # Management account for organizational hierarchy
798
+ "AccountId": {
799
+ "DisplayOrder": 2,
800
+ "Heading": "Acct Number",
801
+ }, # Account identifier for serverless resource ownership
802
+ "Region": {"DisplayOrder": 3, "Heading": "Region"}, # AWS region for geographic Lambda distribution analysis
803
+ "FunctionName": {
804
+ "DisplayOrder": 4,
805
+ "Heading": "Function Name",
806
+ }, # Lambda function name for identification and management
807
+ "Role": {"DisplayOrder": 6, "Heading": "Role"}, # IAM execution role for security and permission analysis
808
+ }
809
+
810
+ # Configure runtime display column based on filtering parameters for targeted compliance analysis
811
+ if pRuntime is None and pFragments is None:
812
+ # Standard runtime display for comprehensive serverless inventory
813
+ display_dict.update({"Runtime": {"DisplayOrder": 5, "Heading": "Runtime"}})
814
+ elif pRuntime is not None and pFragments is None:
815
+ # Runtime-specific display for targeted compliance and security analysis
816
+ display_dict.update({"Runtime": {"DisplayOrder": 5, "Heading": "Runtime", "Condition": pRuntime}})
817
+ elif pRuntime is None and pFragments is not None:
818
+ # Fragment-based display for focused function category analysis
819
+ display_dict.update({"Runtime": {"DisplayOrder": 5, "Heading": "Runtime", "Condition": pFragments}})
820
+ elif pRuntime is not None and pFragments is not None:
821
+ # Combined runtime and fragment filtering for precise serverless governance
822
+ display_dict.update({"Runtime": {"DisplayOrder": 5, "Heading": "Runtime", "Condition": pRuntime + pFragments}})
823
+
824
+ # Initialize credential discovery for multi-account serverless infrastructure analysis
825
+ print(f"Collecting credentials... ")
826
+
827
+ # Execute enterprise credential discovery and validation across organizational hierarchy
828
+ CredentialList = get_all_credentials(
829
+ pProfiles, pTiming, pSkipProfiles, pSkipAccounts, pRootOnly, pAccounts, pRegionList, pRoleList
830
+ )
831
+
832
+ # Calculate organizational scope for executive reporting and operational planning
833
+ AccountNum = len(set([acct["AccountId"] for acct in CredentialList]))
834
+ RegionNum = len(set([acct["Region"] for acct in CredentialList]))
835
+ print()
836
+ print(f"Looking through {AccountNum} accounts and {RegionNum} regions ")
837
+ print()
838
+
839
+ # Combine fragment and runtime filters for comprehensive serverless discovery
840
+ # Note: pFragments defaults to ['all'], ensuring complete coverage when runtime filtering is applied
841
+ full_list_to_look_for = pFragments + pRuntime if pRuntime is not None else pFragments
842
+
843
+ # Execute comprehensive multi-threaded Lambda function discovery and analysis
844
+ AllFunctions = collect_all_my_functions(CredentialList, full_list_to_look_for, pverbose)
845
+
846
+ # Update scope metrics based on actual discovered serverless infrastructure
847
+ AccountNum = len(set([x["AccountId"] for x in AllFunctions]))
848
+ RegionNum = len(set([x["Region"] for x in AllFunctions]))
849
+
850
+ # Generate comprehensive Lambda function inventory report with CSV export capability
851
+ display_results(AllFunctions, display_dict, None, pSaveFilename)
852
+
853
+ # Execute runtime upgrade operations when fix flag is enabled (CRITICAL OPERATIONS)
854
+ if pFix:
855
+ # Validate runtime upgrade parameters to prevent incomplete operations
856
+ if pRuntime is None or pNewRuntime is None:
857
+ print(f"You neglected to provide the runtime you want to change from and to. Exiting here... ")
858
+ sys.exit(7) # Exit with error code for automation and monitoring systems
859
+
860
+ # CRITICAL: Execute live Lambda function runtime modifications with safety controls
861
+ FixedFunctions = fix_my_functions(AllFunctions, pRuntime, pNewRuntime, pForceDelete, pTiming)
862
+ print()
863
+ print("And since we remediated the functions - here's the updated list... ")
864
+ print()
865
+
866
+ # Display post-update function inventory for verification and audit trail
867
+ display_results(FixedFunctions, display_dict, None, pSaveFilename)
868
+
869
+ # Display performance timing metrics for operational optimization and SLA compliance
870
+ if pTiming:
871
+ print(ERASE_LINE)
872
+ print(f"{Fore.GREEN}This script took {time() - begin_time:.3f} seconds{Fore.RESET}")
873
+
874
+ print(ERASE_LINE)
875
+
876
+ # Display comprehensive operational summary for executive reporting and documentation
877
+ print(f"Found {len(AllFunctions)} functions across {AccountNum} accounts, across {RegionNum} regions")
878
+ print()
879
+
880
+ # Display completion message for user confirmation and operational closure
881
+ print("Thank you for using this script")
882
+ print()