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.
- conftest.py +26 -0
- jupyter-agent/.env +2 -0
- jupyter-agent/.env.template +2 -0
- jupyter-agent/.gitattributes +35 -0
- jupyter-agent/.gradio/certificate.pem +31 -0
- jupyter-agent/README.md +16 -0
- jupyter-agent/__main__.log +8 -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/tmp/4ojbs8a02ir/jupyter-agent.ipynb +68 -0
- jupyter-agent/tmp/cm5iasgpm3p/jupyter-agent.ipynb +91 -0
- jupyter-agent/tmp/crqbsseag5/jupyter-agent.ipynb +91 -0
- jupyter-agent/tmp/hohanq1u097/jupyter-agent.ipynb +57 -0
- jupyter-agent/tmp/jns1sam29wm/jupyter-agent.ipynb +53 -0
- jupyter-agent/tmp/jupyter-agent.ipynb +27 -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/README.md +337 -0
- runbooks/finops/__init__.py +86 -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/FAILED_SCRIPTS_TROUBLESHOOTING.md +619 -0
- runbooks/inventory/Inventory_Modules.py +6130 -0
- runbooks/inventory/LandingZone/delete_lz.py +1075 -0
- runbooks/inventory/PASSED_SCRIPTS_GUIDE.md +738 -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/aws_organization.png +0 -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/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 +1004 -0
- runbooks/organizations/__init__.py +12 -0
- runbooks/organizations/manager.py +374 -0
- runbooks/security/README.md +447 -0
- runbooks/security/__init__.py +71 -0
- runbooks/{security_baseline → security}/checklist/alternate_contacts.py +8 -1
- runbooks/{security_baseline → security}/checklist/bucket_public_access.py +4 -1
- runbooks/{security_baseline → security}/checklist/cloudwatch_alarm_configuration.py +9 -2
- runbooks/{security_baseline → security}/checklist/guardduty_enabled.py +9 -2
- runbooks/{security_baseline → security}/checklist/multi_region_instance_usage.py +5 -1
- runbooks/{security_baseline → security}/checklist/root_access_key.py +6 -1
- runbooks/{security_baseline → security}/config-origin.json +1 -1
- runbooks/{security_baseline → security}/config.json +1 -1
- runbooks/{security_baseline → security}/permission.json +1 -1
- runbooks/{security_baseline → security}/report_generator.py +10 -2
- runbooks/{security_baseline → security}/report_template_en.html +7 -7
- runbooks/{security_baseline → security}/report_template_jp.html +7 -7
- runbooks/{security_baseline → security}/report_template_kr.html +12 -12
- runbooks/{security_baseline → security}/report_template_vn.html +7 -7
- runbooks/{security_baseline → security}/run_script.py +8 -2
- runbooks/{security_baseline → security}/security_baseline_tester.py +12 -4
- runbooks/{security_baseline → security}/utils/common.py +5 -1
- runbooks/utils/__init__.py +204 -0
- runbooks-0.7.0.dist-info/METADATA +375 -0
- runbooks-0.7.0.dist-info/RECORD +249 -0
- {runbooks-0.2.5.dist-info → runbooks-0.7.0.dist-info}/WHEEL +1 -1
- runbooks-0.7.0.dist-info/entry_points.txt +7 -0
- runbooks-0.7.0.dist-info/licenses/LICENSE +201 -0
- runbooks-0.7.0.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.5.dist-info/METADATA +0 -439
- runbooks-0.2.5.dist-info/RECORD +0 -61
- runbooks-0.2.5.dist-info/entry_points.txt +0 -3
- runbooks-0.2.5.dist-info/top_level.txt +0 -1
- /runbooks/{security_baseline/__init__.py → inventory/tests/script_test_data.py} +0 -0
- /runbooks/{security_baseline → security}/checklist/__init__.py +0 -0
- /runbooks/{security_baseline → security}/checklist/account_level_bucket_public_access.py +0 -0
- /runbooks/{security_baseline → security}/checklist/direct_attached_policy.py +0 -0
- /runbooks/{security_baseline → security}/checklist/iam_password_policy.py +0 -0
- /runbooks/{security_baseline → security}/checklist/iam_user_mfa.py +0 -0
- /runbooks/{security_baseline → security}/checklist/multi_region_trail.py +0 -0
- /runbooks/{security_baseline → security}/checklist/root_mfa.py +0 -0
- /runbooks/{security_baseline → security}/checklist/root_usage.py +0 -0
- /runbooks/{security_baseline → security}/checklist/trail_enabled.py +0 -0
- /runbooks/{security_baseline → security}/checklist/trusted_advisor.py +0 -0
- /runbooks/{security_baseline → security}/utils/__init__.py +0 -0
- /runbooks/{security_baseline → security}/utils/enums.py +0 -0
- /runbooks/{security_baseline → security}/utils/language.py +0 -0
- /runbooks/{security_baseline → security}/utils/level_const.py +0 -0
- /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()
|