runbooks 0.2.3__py3-none-any.whl → 0.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- conftest.py +26 -0
- jupyter-agent/.env.template +2 -0
- jupyter-agent/.gitattributes +35 -0
- jupyter-agent/README.md +16 -0
- jupyter-agent/app.py +256 -0
- jupyter-agent/cloudops-agent.png +0 -0
- jupyter-agent/ds-system-prompt.txt +154 -0
- jupyter-agent/jupyter-agent.png +0 -0
- jupyter-agent/llama3_template.jinja +123 -0
- jupyter-agent/requirements.txt +9 -0
- jupyter-agent/utils.py +409 -0
- runbooks/__init__.py +71 -3
- runbooks/__main__.py +13 -0
- runbooks/aws/ec2_describe_instances.py +1 -1
- runbooks/aws/ec2_run_instances.py +8 -2
- runbooks/aws/ec2_start_stop_instances.py +17 -4
- runbooks/aws/ec2_unused_volumes.py +5 -1
- runbooks/aws/s3_create_bucket.py +4 -2
- runbooks/aws/s3_list_objects.py +6 -1
- runbooks/aws/tagging_lambda_handler.py +13 -2
- runbooks/aws/tags.json +12 -0
- runbooks/base.py +353 -0
- runbooks/cfat/README.md +49 -0
- runbooks/cfat/__init__.py +74 -0
- runbooks/cfat/app.ts +644 -0
- runbooks/cfat/assessment/__init__.py +40 -0
- runbooks/cfat/assessment/asana-import.csv +39 -0
- runbooks/cfat/assessment/cfat-checks.csv +31 -0
- runbooks/cfat/assessment/cfat.txt +520 -0
- runbooks/cfat/assessment/collectors.py +200 -0
- runbooks/cfat/assessment/jira-import.csv +39 -0
- runbooks/cfat/assessment/runner.py +387 -0
- runbooks/cfat/assessment/validators.py +290 -0
- runbooks/cfat/cli.py +103 -0
- runbooks/cfat/docs/asana-import.csv +24 -0
- runbooks/cfat/docs/cfat-checks.csv +31 -0
- runbooks/cfat/docs/cfat.txt +335 -0
- runbooks/cfat/docs/checks-output.png +0 -0
- runbooks/cfat/docs/cloudshell-console-run.png +0 -0
- runbooks/cfat/docs/cloudshell-download.png +0 -0
- runbooks/cfat/docs/cloudshell-output.png +0 -0
- runbooks/cfat/docs/downloadfile.png +0 -0
- runbooks/cfat/docs/jira-import.csv +24 -0
- runbooks/cfat/docs/open-cloudshell.png +0 -0
- runbooks/cfat/docs/report-header.png +0 -0
- runbooks/cfat/models.py +1026 -0
- runbooks/cfat/package-lock.json +5116 -0
- runbooks/cfat/package.json +38 -0
- runbooks/cfat/report.py +496 -0
- runbooks/cfat/reporting/__init__.py +46 -0
- runbooks/cfat/reporting/exporters.py +337 -0
- runbooks/cfat/reporting/formatters.py +496 -0
- runbooks/cfat/reporting/templates.py +135 -0
- runbooks/cfat/run-assessment.sh +23 -0
- runbooks/cfat/runner.py +69 -0
- runbooks/cfat/src/actions/check-cloudtrail-existence.ts +43 -0
- runbooks/cfat/src/actions/check-config-existence.ts +37 -0
- runbooks/cfat/src/actions/check-control-tower.ts +37 -0
- runbooks/cfat/src/actions/check-ec2-existence.ts +46 -0
- runbooks/cfat/src/actions/check-iam-users.ts +50 -0
- runbooks/cfat/src/actions/check-legacy-cur.ts +30 -0
- runbooks/cfat/src/actions/check-org-cloudformation.ts +30 -0
- runbooks/cfat/src/actions/check-vpc-existence.ts +43 -0
- runbooks/cfat/src/actions/create-asanaimport.ts +14 -0
- runbooks/cfat/src/actions/create-backlog.ts +372 -0
- runbooks/cfat/src/actions/create-jiraimport.ts +15 -0
- runbooks/cfat/src/actions/create-report.ts +616 -0
- runbooks/cfat/src/actions/define-account-type.ts +51 -0
- runbooks/cfat/src/actions/get-enabled-org-policy-types.ts +40 -0
- runbooks/cfat/src/actions/get-enabled-org-services.ts +26 -0
- runbooks/cfat/src/actions/get-idc-info.ts +34 -0
- runbooks/cfat/src/actions/get-org-da-accounts.ts +34 -0
- runbooks/cfat/src/actions/get-org-details.ts +35 -0
- runbooks/cfat/src/actions/get-org-member-accounts.ts +44 -0
- runbooks/cfat/src/actions/get-org-ous.ts +35 -0
- runbooks/cfat/src/actions/get-regions.ts +22 -0
- runbooks/cfat/src/actions/zip-assessment.ts +27 -0
- runbooks/cfat/src/types/index.d.ts +147 -0
- runbooks/cfat/tests/__init__.py +141 -0
- runbooks/cfat/tests/test_cli.py +340 -0
- runbooks/cfat/tests/test_integration.py +290 -0
- runbooks/cfat/tests/test_models.py +505 -0
- runbooks/cfat/tests/test_reporting.py +354 -0
- runbooks/cfat/tsconfig.json +16 -0
- runbooks/cfat/webpack.config.cjs +27 -0
- runbooks/config.py +260 -0
- runbooks/finops/__init__.py +88 -0
- runbooks/finops/aws_client.py +245 -0
- runbooks/finops/cli.py +151 -0
- runbooks/finops/cost_processor.py +410 -0
- runbooks/finops/dashboard_runner.py +448 -0
- runbooks/finops/helpers.py +355 -0
- runbooks/finops/main.py +14 -0
- runbooks/finops/profile_processor.py +174 -0
- runbooks/finops/types.py +66 -0
- runbooks/finops/visualisations.py +80 -0
- runbooks/inventory/.gitignore +354 -0
- runbooks/inventory/ArgumentsClass.py +261 -0
- runbooks/inventory/Inventory_Modules.py +6130 -0
- runbooks/inventory/LandingZone/delete_lz.py +1075 -0
- runbooks/inventory/README.md +1320 -0
- runbooks/inventory/__init__.py +62 -0
- runbooks/inventory/account_class.py +532 -0
- runbooks/inventory/all_my_instances_wrapper.py +123 -0
- runbooks/inventory/aws_decorators.py +201 -0
- runbooks/inventory/cfn_move_stack_instances.py +1526 -0
- runbooks/inventory/check_cloudtrail_compliance.py +614 -0
- runbooks/inventory/check_controltower_readiness.py +1107 -0
- runbooks/inventory/check_landingzone_readiness.py +711 -0
- runbooks/inventory/cloudtrail.md +727 -0
- runbooks/inventory/collectors/__init__.py +20 -0
- runbooks/inventory/collectors/aws_compute.py +518 -0
- runbooks/inventory/collectors/aws_networking.py +275 -0
- runbooks/inventory/collectors/base.py +222 -0
- runbooks/inventory/core/__init__.py +19 -0
- runbooks/inventory/core/collector.py +303 -0
- runbooks/inventory/core/formatter.py +296 -0
- runbooks/inventory/delete_s3_buckets_objects.py +169 -0
- runbooks/inventory/discovery.md +81 -0
- runbooks/inventory/draw_org_structure.py +748 -0
- runbooks/inventory/ec2_vpc_utils.py +341 -0
- runbooks/inventory/find_cfn_drift_detection.py +272 -0
- runbooks/inventory/find_cfn_orphaned_stacks.py +719 -0
- runbooks/inventory/find_cfn_stackset_drift.py +733 -0
- runbooks/inventory/find_ec2_security_groups.py +669 -0
- runbooks/inventory/find_landingzone_versions.py +201 -0
- runbooks/inventory/find_vpc_flow_logs.py +1221 -0
- runbooks/inventory/inventory.sh +659 -0
- runbooks/inventory/list_cfn_stacks.py +558 -0
- runbooks/inventory/list_cfn_stackset_operation_results.py +252 -0
- runbooks/inventory/list_cfn_stackset_operations.py +734 -0
- runbooks/inventory/list_cfn_stacksets.py +453 -0
- runbooks/inventory/list_config_recorders_delivery_channels.py +681 -0
- runbooks/inventory/list_ds_directories.py +354 -0
- runbooks/inventory/list_ec2_availability_zones.py +286 -0
- runbooks/inventory/list_ec2_ebs_volumes.py +244 -0
- runbooks/inventory/list_ec2_instances.py +425 -0
- runbooks/inventory/list_ecs_clusters_and_tasks.py +562 -0
- runbooks/inventory/list_elbs_load_balancers.py +411 -0
- runbooks/inventory/list_enis_network_interfaces.py +526 -0
- runbooks/inventory/list_guardduty_detectors.py +568 -0
- runbooks/inventory/list_iam_policies.py +404 -0
- runbooks/inventory/list_iam_roles.py +518 -0
- runbooks/inventory/list_iam_saml_providers.py +359 -0
- runbooks/inventory/list_lambda_functions.py +882 -0
- runbooks/inventory/list_org_accounts.py +446 -0
- runbooks/inventory/list_org_accounts_users.py +354 -0
- runbooks/inventory/list_rds_db_instances.py +406 -0
- runbooks/inventory/list_route53_hosted_zones.py +318 -0
- runbooks/inventory/list_servicecatalog_provisioned_products.py +575 -0
- runbooks/inventory/list_sns_topics.py +360 -0
- runbooks/inventory/list_ssm_parameters.py +402 -0
- runbooks/inventory/list_vpc_subnets.py +433 -0
- runbooks/inventory/list_vpcs.py +422 -0
- runbooks/inventory/lockdown_cfn_stackset_role.py +224 -0
- runbooks/inventory/models/__init__.py +24 -0
- runbooks/inventory/models/account.py +192 -0
- runbooks/inventory/models/inventory.py +309 -0
- runbooks/inventory/models/resource.py +247 -0
- runbooks/inventory/recover_cfn_stack_ids.py +205 -0
- runbooks/inventory/requirements.txt +12 -0
- runbooks/inventory/run_on_multi_accounts.py +211 -0
- runbooks/inventory/tests/common_test_data.py +3661 -0
- runbooks/inventory/tests/common_test_functions.py +204 -0
- runbooks/inventory/tests/script_test_data.py +0 -0
- runbooks/inventory/tests/setup.py +24 -0
- runbooks/inventory/tests/src.py +18 -0
- runbooks/inventory/tests/test_cfn_describe_stacks.py +208 -0
- runbooks/inventory/tests/test_ec2_describe_instances.py +162 -0
- runbooks/inventory/tests/test_inventory_modules.py +55 -0
- runbooks/inventory/tests/test_lambda_list_functions.py +86 -0
- runbooks/inventory/tests/test_moto_integration_example.py +273 -0
- runbooks/inventory/tests/test_org_list_accounts.py +49 -0
- runbooks/inventory/update_aws_actions.py +173 -0
- runbooks/inventory/update_cfn_stacksets.py +1215 -0
- runbooks/inventory/update_cloudwatch_logs_retention_policy.py +294 -0
- runbooks/inventory/update_iam_roles_cross_accounts.py +478 -0
- runbooks/inventory/update_s3_public_access_block.py +539 -0
- runbooks/inventory/utils/__init__.py +23 -0
- runbooks/inventory/utils/aws_helpers.py +510 -0
- runbooks/inventory/utils/threading_utils.py +493 -0
- runbooks/inventory/utils/validation.py +682 -0
- runbooks/inventory/verify_ec2_security_groups.py +1430 -0
- runbooks/main.py +785 -0
- runbooks/organizations/__init__.py +12 -0
- runbooks/organizations/manager.py +374 -0
- runbooks/security_baseline/README.md +324 -0
- runbooks/security_baseline/checklist/alternate_contacts.py +8 -1
- runbooks/security_baseline/checklist/bucket_public_access.py +4 -1
- runbooks/security_baseline/checklist/cloudwatch_alarm_configuration.py +9 -2
- runbooks/security_baseline/checklist/guardduty_enabled.py +9 -2
- runbooks/security_baseline/checklist/multi_region_instance_usage.py +5 -1
- runbooks/security_baseline/checklist/root_access_key.py +6 -1
- runbooks/security_baseline/config-origin.json +1 -1
- runbooks/security_baseline/config.json +1 -1
- runbooks/security_baseline/permission.json +1 -1
- runbooks/security_baseline/report_generator.py +10 -2
- runbooks/security_baseline/report_template_en.html +8 -8
- runbooks/security_baseline/report_template_jp.html +8 -8
- runbooks/security_baseline/report_template_kr.html +13 -13
- runbooks/security_baseline/report_template_vn.html +8 -8
- runbooks/security_baseline/requirements.txt +7 -0
- runbooks/security_baseline/run_script.py +8 -2
- runbooks/security_baseline/security_baseline_tester.py +10 -2
- runbooks/security_baseline/utils/common.py +5 -1
- runbooks/utils/__init__.py +204 -0
- runbooks-0.6.1.dist-info/METADATA +373 -0
- runbooks-0.6.1.dist-info/RECORD +237 -0
- {runbooks-0.2.3.dist-info → runbooks-0.6.1.dist-info}/WHEEL +1 -1
- runbooks-0.6.1.dist-info/entry_points.txt +7 -0
- runbooks-0.6.1.dist-info/licenses/LICENSE +201 -0
- runbooks-0.6.1.dist-info/top_level.txt +3 -0
- runbooks/python101/calculator.py +0 -34
- runbooks/python101/config.py +0 -1
- runbooks/python101/exceptions.py +0 -16
- runbooks/python101/file_manager.py +0 -218
- runbooks/python101/toolkit.py +0 -153
- runbooks-0.2.3.dist-info/METADATA +0 -435
- runbooks-0.2.3.dist-info/RECORD +0 -61
- runbooks-0.2.3.dist-info/entry_points.txt +0 -3
- runbooks-0.2.3.dist-info/top_level.txt +0 -1
@@ -0,0 +1,734 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
|
3
|
+
"""
|
4
|
+
AWS CloudFormation StackSet Operations Discovery and Analysis Script
|
5
|
+
|
6
|
+
This enterprise-grade inventory and monitoring script provides comprehensive StackSet operations
|
7
|
+
discovery, analysis, and tracking across multi-account AWS Organizations environments. Designed
|
8
|
+
for infrastructure teams, DevOps engineers, and cloud architects managing large-scale CloudFormation
|
9
|
+
StackSet deployments with centralized operational oversight and deployment orchestration.
|
10
|
+
|
11
|
+
Key Features:
|
12
|
+
- StackSet operations discovery and lifecycle tracking across organizational accounts
|
13
|
+
- Multi-threaded StackSet instance enumeration for deployment topology analysis
|
14
|
+
- Last operation status analysis with failure detection and operational insights
|
15
|
+
- Stack instance detailed status tracking for deployment troubleshooting
|
16
|
+
- Fragment-based filtering for targeted StackSet operations analysis and monitoring
|
17
|
+
- Comprehensive error handling for authorization, throttling, and connectivity issues
|
18
|
+
- Progress tracking with real-time operational feedback and performance metrics
|
19
|
+
- Flexible output formatting with CSV export for reporting and integration
|
20
|
+
|
21
|
+
Authentication and Access:
|
22
|
+
- Single-profile authentication for centralized StackSet management operations
|
23
|
+
- Support for AWS Organizations cross-account role-based access patterns
|
24
|
+
- Regional validation and access control for StackSet operational boundaries
|
25
|
+
- Comprehensive error handling for authentication and authorization failures
|
26
|
+
|
27
|
+
Enterprise Use Cases:
|
28
|
+
- Centralized StackSet deployment monitoring and operational excellence
|
29
|
+
- Infrastructure governance and compliance tracking for organizational standards
|
30
|
+
- Deployment failure analysis and troubleshooting for operational support
|
31
|
+
- StackSet lifecycle management and capacity planning across accounts
|
32
|
+
- Operational dashboards and reporting for infrastructure management teams
|
33
|
+
|
34
|
+
Performance and Scalability:
|
35
|
+
- Multi-threaded architecture for efficient StackSet instance discovery
|
36
|
+
- Queue-based worker pattern for concurrent StackSet operations analysis
|
37
|
+
- Optimized AWS API usage with progress tracking and performance timing
|
38
|
+
- Configurable concurrency limits for API rate limiting and throttling management
|
39
|
+
|
40
|
+
Security Considerations:
|
41
|
+
- Read-only operations ensuring no accidental StackSet modifications
|
42
|
+
- Comprehensive audit logging for compliance and operational tracking
|
43
|
+
- Secure credential handling with profile-based authentication
|
44
|
+
- Access validation and error handling for enterprise security requirements
|
45
|
+
|
46
|
+
Dependencies:
|
47
|
+
- boto3: AWS SDK for CloudFormation StackSet operations
|
48
|
+
- colorama: Enhanced terminal output with color coding
|
49
|
+
- tqdm: Progress bars for long-running discovery operations
|
50
|
+
- Inventory_Modules: Custom AWS inventory and discovery utilities
|
51
|
+
- ArgumentsClass: Standardized CLI argument parsing and validation
|
52
|
+
- account_class: AWS account access and credential management
|
53
|
+
|
54
|
+
Example Usage:
|
55
|
+
# Basic StackSet operations discovery
|
56
|
+
python list_cfn_stackset_operations.py --profile production
|
57
|
+
|
58
|
+
# Fragment-based operations analysis
|
59
|
+
python list_cfn_stackset_operations.py --fragment SecurityBaseline
|
60
|
+
|
61
|
+
# Detailed instance enumeration with timing
|
62
|
+
python list_cfn_stackset_operations.py --instances --timing
|
63
|
+
|
64
|
+
Output:
|
65
|
+
Displays discovered StackSet operations with last operation status, failure counts,
|
66
|
+
completion timestamps, and deployment topology insights for operational monitoring.
|
67
|
+
"""
|
68
|
+
|
69
|
+
import logging
|
70
|
+
import os
|
71
|
+
import sys
|
72
|
+
from queue import Queue
|
73
|
+
from threading import Thread
|
74
|
+
from time import time
|
75
|
+
|
76
|
+
import Inventory_Modules
|
77
|
+
from account_class import aws_acct_access
|
78
|
+
from ArgumentsClass import CommonArguments
|
79
|
+
from botocore.exceptions import ClientError
|
80
|
+
from colorama import Fore, init
|
81
|
+
from Inventory_Modules import display_results, find_stacksets3, get_regions3
|
82
|
+
from tqdm.auto import tqdm
|
83
|
+
|
84
|
+
init()
|
85
|
+
|
86
|
+
__version__ = "2024.05.18"
|
87
|
+
ERASE_LINE = "\x1b[2K"
|
88
|
+
begin_time = time()
|
89
|
+
DefaultMaxWorkerThreads = 5
|
90
|
+
|
91
|
+
|
92
|
+
##################
|
93
|
+
# Functions
|
94
|
+
##################
|
95
|
+
def parse_args(args: object):
|
96
|
+
"""
|
97
|
+
Parse and validate CLI arguments for StackSet operations discovery and analysis.
|
98
|
+
|
99
|
+
Configures comprehensive argument parsing for StackSet operations inventory across
|
100
|
+
AWS Organizations with support for fragment-based filtering, instance enumeration,
|
101
|
+
status tracking, and operational analysis. Provides enterprise-grade CLI interface
|
102
|
+
for infrastructure teams managing large-scale StackSet deployments.
|
103
|
+
|
104
|
+
Args:
|
105
|
+
args (object): Command-line arguments list for parsing and validation
|
106
|
+
|
107
|
+
Returns:
|
108
|
+
argparse.Namespace: Parsed arguments object containing:
|
109
|
+
- Profile: AWS profile for StackSet management operations access
|
110
|
+
- Region: Target AWS region for StackSet operations discovery
|
111
|
+
- Fragments: StackSet name fragments for targeted search and filtering
|
112
|
+
- Exact: Boolean flag for exact fragment matching vs. substring matching
|
113
|
+
- RootOnly: Boolean flag to limit discovery to root account only
|
114
|
+
- Timing: Boolean flag to enable performance timing and metrics
|
115
|
+
- Verbosity: Logging level for operational visibility and debugging
|
116
|
+
- pinstancecount: Boolean flag for StackSet instance enumeration
|
117
|
+
- pstatus: StackSet status filter ('Active' or 'Deleted')
|
118
|
+
- Filename: Optional output file path for CSV export and reporting
|
119
|
+
|
120
|
+
CLI Arguments:
|
121
|
+
Single Profile Authentication:
|
122
|
+
- --profile: AWS profile for centralized StackSet management access
|
123
|
+
- Single-profile mode for focused operational analysis
|
124
|
+
|
125
|
+
Regional Configuration:
|
126
|
+
- --region: Target AWS region for StackSet operations discovery
|
127
|
+
- Single-region mode for focused operational boundaries
|
128
|
+
|
129
|
+
StackSet Filtering:
|
130
|
+
- --fragment: StackSet name fragments for targeted operations analysis
|
131
|
+
- --exact: Enable exact fragment matching for precise filtering
|
132
|
+
- --status: Filter by StackSet status (Active/Deleted) for lifecycle tracking
|
133
|
+
|
134
|
+
Instance Analysis:
|
135
|
+
- --instances: Enable StackSet instance enumeration for topology analysis
|
136
|
+
- Provides deployment pattern insights and capacity planning data
|
137
|
+
|
138
|
+
Operational Controls:
|
139
|
+
- --root-only: Limit discovery to root account StackSet operations
|
140
|
+
- --timing: Enable performance timing for operational metrics
|
141
|
+
- --save-to-file: Export results to CSV for reporting and integration
|
142
|
+
- --verbose: Control logging verbosity for debugging and audit trails
|
143
|
+
|
144
|
+
Enterprise Features:
|
145
|
+
- Standardized CLI interface consistent with inventory tooling
|
146
|
+
- Fragment-based search for targeted StackSet operations analysis
|
147
|
+
- Instance enumeration for deployment topology and capacity insights
|
148
|
+
- Status filtering for StackSet lifecycle and operational tracking
|
149
|
+
- Output formatting with CSV export for enterprise reporting
|
150
|
+
|
151
|
+
Validation and Error Handling:
|
152
|
+
- Argument validation with informative error messages
|
153
|
+
- Help text generation for operational documentation
|
154
|
+
- Version information for tooling compatibility tracking
|
155
|
+
- Default value configuration for operational convenience
|
156
|
+
"""
|
157
|
+
script_path, script_name = os.path.split(sys.argv[0])
|
158
|
+
parser = CommonArguments()
|
159
|
+
|
160
|
+
# Configure standardized CLI arguments for enterprise inventory operations
|
161
|
+
parser.singleprofile() # Single AWS profile for centralized StackSet management access
|
162
|
+
parser.singleregion() # Single region specification for focused operational boundaries
|
163
|
+
parser.fragment() # Fragment-based filtering for targeted StackSet operations analysis
|
164
|
+
parser.extendedargs() # Extended argument support for advanced filtering capabilities
|
165
|
+
parser.save_to_file() # CSV export functionality for enterprise reporting and integration
|
166
|
+
parser.rootOnly() # Root account only mode for organizational StackSet oversight
|
167
|
+
parser.timing() # Performance timing metrics for operational analysis
|
168
|
+
parser.verbosity() # Configurable logging verbosity for debugging and audit trails
|
169
|
+
parser.version(__version__) # Version information for tooling compatibility tracking
|
170
|
+
|
171
|
+
# Add script-specific arguments for StackSet operations analysis
|
172
|
+
local = parser.my_parser.add_argument_group(script_name, "Parameters specific to this script")
|
173
|
+
local.add_argument(
|
174
|
+
"-i",
|
175
|
+
"--instances",
|
176
|
+
dest="pinstancecount",
|
177
|
+
action="store_true",
|
178
|
+
default=False,
|
179
|
+
help="Enable StackSet instance enumeration for deployment topology analysis and capacity planning",
|
180
|
+
)
|
181
|
+
local.add_argument(
|
182
|
+
"-s",
|
183
|
+
"--status",
|
184
|
+
dest="pstatus",
|
185
|
+
metavar="CloudFormation status",
|
186
|
+
default="Active",
|
187
|
+
choices=["active", "ACTIVE", "Active", "deleted", "DELETED", "Deleted"],
|
188
|
+
help="Filter StackSets by lifecycle status - 'ACTIVE' for operational StackSets or 'DELETED' for cleanup analysis",
|
189
|
+
)
|
190
|
+
return parser.my_parser.parse_args(args)
|
191
|
+
|
192
|
+
|
193
|
+
def setup_auth_and_regions(
|
194
|
+
fProfile: str, fRegion: str = None, fStackFrag: list = None, fExact: bool = False
|
195
|
+
) -> (aws_acct_access, list):
|
196
|
+
"""
|
197
|
+
Initialize authentication and configure regional access for StackSet operations discovery.
|
198
|
+
|
199
|
+
Establishes AWS authentication context and validates regional configuration for StackSet
|
200
|
+
operations analysis and monitoring. Performs single-region validation and provides
|
201
|
+
operational context display for infrastructure teams managing centralized StackSet
|
202
|
+
deployments across AWS Organizations environments.
|
203
|
+
|
204
|
+
Args:
|
205
|
+
fProfile (str): AWS profile name for authentication and StackSet management access
|
206
|
+
If None, uses default profile or credential chain
|
207
|
+
fRegion (str): Target AWS region for StackSet operations discovery
|
208
|
+
Defaults to 'us-east-1' if not specified
|
209
|
+
fStackFrag (list): StackSet name fragments for targeted search and filtering
|
210
|
+
Defaults to ['all'] for comprehensive discovery
|
211
|
+
fExact (bool): Enable exact fragment matching for precise filtering
|
212
|
+
Default False for substring-based matching
|
213
|
+
|
214
|
+
Returns:
|
215
|
+
tuple: Two-element tuple containing:
|
216
|
+
- aws_acct_access: Authenticated account access object for StackSet operations
|
217
|
+
- list: Validated AWS regions list for StackSet discovery operations
|
218
|
+
|
219
|
+
Authentication and Validation:
|
220
|
+
- Establishes AWS authentication using the specified profile
|
221
|
+
- Validates single-region configuration for focused operational boundaries
|
222
|
+
- Performs regional access validation for StackSet management operations
|
223
|
+
- Handles authentication failures with appropriate error messaging
|
224
|
+
|
225
|
+
Regional Configuration:
|
226
|
+
- Single-region mode for focused StackSet operations analysis
|
227
|
+
- Regional validation to ensure StackSet management capabilities
|
228
|
+
- Error handling for invalid or inaccessible regions
|
229
|
+
- Operational context display for transparency and troubleshooting
|
230
|
+
|
231
|
+
Operational Display:
|
232
|
+
- Account type and number identification for organizational context
|
233
|
+
- Regional scope confirmation for operational boundaries
|
234
|
+
- Fragment matching configuration display for search transparency
|
235
|
+
- Clear operational intent communication for infrastructure teams
|
236
|
+
|
237
|
+
Error Handling:
|
238
|
+
- Connection error detection with appropriate system exit
|
239
|
+
- Profile validation and authentication failure management
|
240
|
+
- Regional access validation with informative error messages
|
241
|
+
- Comprehensive error logging for troubleshooting and audit trails
|
242
|
+
|
243
|
+
Enterprise Features:
|
244
|
+
- Single-region focus for targeted StackSet operations monitoring
|
245
|
+
- Clear operational scope display for infrastructure governance
|
246
|
+
- Fragment-based search configuration for operational efficiency
|
247
|
+
- Account type awareness for organizational structure recognition
|
248
|
+
"""
|
249
|
+
|
250
|
+
# Set default values for optional parameters to ensure consistent operation
|
251
|
+
if fStackFrag is None:
|
252
|
+
fStackfrag = ["all"] # Default to comprehensive StackSet discovery
|
253
|
+
if fRegion is None:
|
254
|
+
fRegion = "us-east-1" # Default to primary AWS region for StackSet management
|
255
|
+
|
256
|
+
try:
|
257
|
+
# Establish AWS authentication using the specified profile
|
258
|
+
aws_acct = aws_acct_access(fProfile)
|
259
|
+
except ConnectionError as my_Error:
|
260
|
+
# Handle authentication and connection failures with appropriate logging
|
261
|
+
logging.error(f"Exiting due to error: {my_Error}")
|
262
|
+
sys.exit(8)
|
263
|
+
|
264
|
+
# Validate regional access and availability for StackSet operations
|
265
|
+
RegionList = get_regions3(aws_acct, [fRegion])
|
266
|
+
|
267
|
+
# Enforce single-region constraint for focused StackSet operations analysis
|
268
|
+
if fRegion.lower() not in RegionList:
|
269
|
+
print()
|
270
|
+
print(
|
271
|
+
f"{Fore.RED}You specified '{fRegion}' as the region, but this script only works with a single region.\n"
|
272
|
+
f"Please run the command again and specify only a single, valid region{Fore.RESET}"
|
273
|
+
)
|
274
|
+
print()
|
275
|
+
raise ValueError(f"You specified '{fRegion}' as the region, but this script only works with a single region.")
|
276
|
+
|
277
|
+
# Display operational scope and configuration for transparency
|
278
|
+
print()
|
279
|
+
action = "but not modify" # Read-only operations for safety
|
280
|
+
print(f"You asked me to find ({action}) stacksets that match the following:")
|
281
|
+
print(f"\t\tIn the {aws_acct.AccountType} account {aws_acct.acct_number}")
|
282
|
+
print(f"\t\tIn this Region: {fRegion}")
|
283
|
+
|
284
|
+
# Display fragment matching configuration for search transparency
|
285
|
+
if fExact:
|
286
|
+
print(f"\t\tFor stacksets that {Fore.RED}exactly match{Fore.RESET} these fragments: {fStackfrag}")
|
287
|
+
else:
|
288
|
+
print(f"\t\tFor stacksets that contains these fragments: {fStackfrag}")
|
289
|
+
|
290
|
+
print()
|
291
|
+
return aws_acct, RegionList
|
292
|
+
|
293
|
+
|
294
|
+
def collect_cfnstacksets(faws_acct: aws_acct_access, fRegion: str) -> (dict, dict, dict):
|
295
|
+
"""
|
296
|
+
Collect and aggregate StackSet information with comprehensive instance enumeration and analysis.
|
297
|
+
|
298
|
+
Performs comprehensive StackSet discovery, instance enumeration, and metadata aggregation
|
299
|
+
for operational analysis and infrastructure governance. Orchestrates StackSet collection
|
300
|
+
with detailed instance topology mapping and account/region distribution analysis for
|
301
|
+
enterprise infrastructure teams managing large-scale CloudFormation deployments.
|
302
|
+
|
303
|
+
Args:
|
304
|
+
faws_acct (aws_acct_access): Authenticated AWS account access object for StackSet operations
|
305
|
+
fRegion (str): Target AWS region for StackSet discovery and instance enumeration
|
306
|
+
|
307
|
+
Returns:
|
308
|
+
tuple: Three-element tuple containing comprehensive StackSet information:
|
309
|
+
dict: StackSet aggregation containing:
|
310
|
+
- combined_stack_set_instances: Complete list of StackSet instances with metadata
|
311
|
+
- StackSets: Raw StackSet discovery results from inventory modules
|
312
|
+
- StackSetsList: Filtered list of StackSet names in operational scope
|
313
|
+
dict: Account aggregation containing:
|
314
|
+
- AccountList: Unique list of accounts with StackSet instances
|
315
|
+
dict: Region aggregation containing:
|
316
|
+
- FoundRegionList: Unique list of regions with StackSet deployments
|
317
|
+
|
318
|
+
StackSet Discovery Process:
|
319
|
+
- Fragment-based StackSet discovery using inventory modules
|
320
|
+
- Comprehensive instance enumeration across organizational accounts
|
321
|
+
- Account and region filtering based on operational scope
|
322
|
+
- Metadata extraction for deployment topology analysis
|
323
|
+
|
324
|
+
Instance Analysis Features:
|
325
|
+
- Multi-threaded instance discovery for performance optimization
|
326
|
+
- Account filtering for targeted operational analysis
|
327
|
+
- Regional distribution mapping for capacity planning
|
328
|
+
- Status tracking and deployment pattern analysis
|
329
|
+
|
330
|
+
Data Aggregation:
|
331
|
+
- Deduplication of accounts and regions for clean reporting
|
332
|
+
- StackSet name filtering and scope management
|
333
|
+
- Comprehensive metadata preservation for analysis
|
334
|
+
- Structured data organization for downstream processing
|
335
|
+
|
336
|
+
Enterprise Infrastructure Governance:
|
337
|
+
- Organizational StackSet visibility and management
|
338
|
+
- Deployment topology analysis for operational excellence
|
339
|
+
- Account and region distribution insights for capacity planning
|
340
|
+
- Infrastructure governance and compliance tracking
|
341
|
+
|
342
|
+
Error Handling:
|
343
|
+
- AWS connection validation with appropriate error messaging
|
344
|
+
- Failed discovery detection with comprehensive error reporting
|
345
|
+
- Graceful degradation for partial discovery scenarios
|
346
|
+
- Comprehensive logging for troubleshooting and audit trails
|
347
|
+
"""
|
348
|
+
# Discover StackSets from the Management Account using fragment-based filtering
|
349
|
+
StackSets = find_stacksets3(faws_acct, fRegion, pStackfrag, pExact)
|
350
|
+
if not StackSets["Success"]:
|
351
|
+
# Handle failed StackSet discovery with comprehensive error messaging
|
352
|
+
error_message = (
|
353
|
+
"Something went wrong with the AWS connection. Please check the parameters supplied and try again."
|
354
|
+
)
|
355
|
+
sys.exit(error_message)
|
356
|
+
logging.info(f"Found {len(StackSets['StackSets'])} StackSetNames that matched your fragment")
|
357
|
+
|
358
|
+
# Perform comprehensive StackSet instance enumeration across organizational accounts
|
359
|
+
combined_stack_set_instances = find_stack_set_instances(StackSets["StackSets"], fRegion)
|
360
|
+
|
361
|
+
print(ERASE_LINE)
|
362
|
+
logging.info(f"Found {len(combined_stack_set_instances)} stack instances.")
|
363
|
+
|
364
|
+
# Initialize aggregation lists for account and region distribution analysis
|
365
|
+
AccountList = []
|
366
|
+
StackSetsList = []
|
367
|
+
FoundRegionList = []
|
368
|
+
|
369
|
+
# Process and filter StackSet instances based on account inclusion criteria
|
370
|
+
for _ in range(len(combined_stack_set_instances)):
|
371
|
+
if pAccountList is None: # Include all discovered instances when no specific account list provided
|
372
|
+
StackSetsList.append(combined_stack_set_instances[_]["StackSetName"])
|
373
|
+
AccountList.append(combined_stack_set_instances[_]["ChildAccount"])
|
374
|
+
FoundRegionList.append(combined_stack_set_instances[_]["ChildRegion"])
|
375
|
+
elif pAccountList is not None:
|
376
|
+
# Filter instances to include only those in the specified account list
|
377
|
+
if combined_stack_set_instances[_]["ChildAccount"] in pAccountList:
|
378
|
+
StackSetsList.append(combined_stack_set_instances[_]["StackSetName"])
|
379
|
+
AccountList.append(combined_stack_set_instances[_]["ChildAccount"])
|
380
|
+
FoundRegionList.append(combined_stack_set_instances[_]["ChildRegion"])
|
381
|
+
|
382
|
+
# Deduplicate and sort aggregated lists for clean reporting and analysis
|
383
|
+
# Filter out None values that occur when StackSets have no deployed instances
|
384
|
+
AccountList = sorted(list(set([item for item in AccountList if item is not None])))
|
385
|
+
|
386
|
+
# Regional aggregation for deployment topology analysis
|
387
|
+
# Note: Regional scope is maintained at StackSet level rather than per-account
|
388
|
+
# Future enhancement: Consider per-account regional filtering for granular control
|
389
|
+
FoundRegionList = sorted(list(set([item for item in FoundRegionList if item is not None])))
|
390
|
+
StackSetsList = sorted(list(set(StackSetsList)))
|
391
|
+
|
392
|
+
# Structure aggregated data for downstream processing and analysis
|
393
|
+
StackSet_Dict = {
|
394
|
+
"combined_stack_set_instances": combined_stack_set_instances,
|
395
|
+
"StackSets": StackSets,
|
396
|
+
"StackSetsList": StackSetsList,
|
397
|
+
}
|
398
|
+
Account_Dict = {"AccountList": AccountList}
|
399
|
+
Region_Dict = {"FoundRegionList": FoundRegionList}
|
400
|
+
return StackSet_Dict, Account_Dict, Region_Dict
|
401
|
+
|
402
|
+
|
403
|
+
def find_stack_set_instances(fStackSetNames: list, fRegion: str) -> list:
|
404
|
+
"""
|
405
|
+
Discover and enumerate StackSet instances across organizational accounts using multi-threaded processing.
|
406
|
+
|
407
|
+
Performs comprehensive StackSet instance discovery using concurrent worker threads for efficient
|
408
|
+
enumeration across large-scale CloudFormation StackSet deployments. Provides detailed instance
|
409
|
+
metadata extraction, status tracking, and deployment topology analysis for enterprise infrastructure
|
410
|
+
teams managing multi-account StackSet orchestration and operational monitoring.
|
411
|
+
|
412
|
+
Args:
|
413
|
+
fStackSetNames (list): List of StackSet names for instance discovery and enumeration
|
414
|
+
Reserved keyword 'all' enables comprehensive discovery
|
415
|
+
fRegion (str): Target AWS region for StackSet instance discovery operations
|
416
|
+
|
417
|
+
Returns:
|
418
|
+
list: Comprehensive list of StackSet instance dictionaries containing:
|
419
|
+
- ParentAccountNumber: Management account hosting the StackSet
|
420
|
+
- ChildAccount: Target account where StackSet instance is deployed
|
421
|
+
- ChildRegion: Target region for StackSet instance deployment
|
422
|
+
- StackStatus: Current deployment status of the StackSet instance
|
423
|
+
- DetailedStatus: Detailed operational status for troubleshooting
|
424
|
+
- StatusReason: Reason description for failed or problematic deployments
|
425
|
+
- OrganizationalUnitId: AWS Organizations OU for organizational structure
|
426
|
+
- PermissionModel: StackSet permission model (SELF_MANAGED/SERVICE_MANAGED)
|
427
|
+
- StackSetName: Parent StackSet name for instance relationship tracking
|
428
|
+
|
429
|
+
Multi-threaded Architecture:
|
430
|
+
- Queue-based worker pattern for concurrent instance discovery
|
431
|
+
- Configurable worker thread pool for performance optimization
|
432
|
+
- Progress tracking with real-time operational feedback
|
433
|
+
- Graceful error handling for authorization and throttling issues
|
434
|
+
|
435
|
+
Instance Discovery Features:
|
436
|
+
- Comprehensive metadata extraction for operational analysis
|
437
|
+
- Account filtering support for targeted instance enumeration
|
438
|
+
- Regional validation for deployment boundary enforcement
|
439
|
+
- Status tracking for deployment lifecycle management
|
440
|
+
|
441
|
+
Performance Optimization:
|
442
|
+
- Concurrent processing for efficient large-scale discovery
|
443
|
+
- Progress bars for operational visibility during long-running operations
|
444
|
+
- Worker thread scaling based on StackSet count for optimal performance
|
445
|
+
- Queue management for efficient work distribution and completion tracking
|
446
|
+
|
447
|
+
Enterprise Infrastructure Management:
|
448
|
+
- Organizational StackSet instance visibility across accounts
|
449
|
+
- Deployment topology mapping for capacity planning and governance
|
450
|
+
- Status monitoring for operational excellence and troubleshooting
|
451
|
+
- Permission model tracking for security and compliance analysis
|
452
|
+
|
453
|
+
Error Handling:
|
454
|
+
- Authorization failure detection with graceful degradation
|
455
|
+
- AWS API throttling management with retry logic
|
456
|
+
- Connection error handling with comprehensive logging
|
457
|
+
- Partial discovery support for operational resilience
|
458
|
+
"""
|
459
|
+
|
460
|
+
class FindStackSets(Thread):
|
461
|
+
"""
|
462
|
+
Multi-threaded worker class for concurrent StackSet instance discovery and enumeration.
|
463
|
+
|
464
|
+
Implements thread-safe StackSet instance discovery using queue-based work distribution
|
465
|
+
for efficient processing of large-scale StackSet deployments across organizational accounts.
|
466
|
+
"""
|
467
|
+
|
468
|
+
def __init__(self, queue):
|
469
|
+
Thread.__init__(self)
|
470
|
+
self.queue = queue
|
471
|
+
|
472
|
+
def run(self):
|
473
|
+
while True:
|
474
|
+
# Extract work item from queue with StackSet information and processing context
|
475
|
+
c_stacksetname, c_region, c_stackset_info, c_PlaceCount = self.queue.get()
|
476
|
+
logging.info(f"De-queued info for stack set name {c_stacksetname}")
|
477
|
+
|
478
|
+
try:
|
479
|
+
# Perform StackSet instance discovery for the current StackSet
|
480
|
+
# This is the most time-intensive operation in the discovery process
|
481
|
+
logging.info(
|
482
|
+
f"{ERASE_LINE}Looking through {c_PlaceCount} of {len(fStackSetNames)} stacksets found with {pStackfrag} string in them"
|
483
|
+
)
|
484
|
+
|
485
|
+
# Call inventory module to discover instances for the current StackSet
|
486
|
+
# Note: Empty StackSets (without instances) may be excluded from results
|
487
|
+
StackInstances = Inventory_Modules.find_stack_instances3(aws_acct, c_region, c_stacksetname)
|
488
|
+
logging.warning(f"Found {len(StackInstances)} Stack Instances within the StackSet {c_stacksetname}")
|
489
|
+
|
490
|
+
# Process each discovered StackSet instance with metadata extraction
|
491
|
+
for StackInstance in StackInstances:
|
492
|
+
# Validate StackSet instance deployment status
|
493
|
+
if "StackId" not in StackInstance.keys():
|
494
|
+
logging.info(
|
495
|
+
f"The stack instance found {StackInstance} doesn't have a stackid associated. Which means it's never been deployed and probably OUTDATED"
|
496
|
+
)
|
497
|
+
pass
|
498
|
+
|
499
|
+
# Apply account filtering for targeted instance enumeration
|
500
|
+
if pAccountList is None or StackInstance["Account"] in pAccountList:
|
501
|
+
# Include instance if no account filter specified or account matches filter
|
502
|
+
# Supports comprehensive discovery and targeted operational analysis
|
503
|
+
logging.debug(f"This is Instance #: {str(StackInstance)}")
|
504
|
+
logging.debug(f"This is instance status: {str(StackInstance['Status'])}")
|
505
|
+
logging.debug(f"This is ChildAccount: {StackInstance['Account']}")
|
506
|
+
logging.debug(f"This is ChildRegion: {StackInstance['Region']}")
|
507
|
+
|
508
|
+
# Validate regional scope and add instance to results
|
509
|
+
if StackInstance["Region"] in RegionList:
|
510
|
+
# Aggregate comprehensive instance metadata for analysis
|
511
|
+
f_combined_stack_set_instances.append(
|
512
|
+
{
|
513
|
+
"ParentAccountNumber": aws_acct.acct_number, # Management account hosting StackSet
|
514
|
+
"ChildAccount": StackInstance["Account"], # Target deployment account
|
515
|
+
"ChildRegion": StackInstance["Region"], # Target deployment region
|
516
|
+
"StackStatus": StackInstance["Status"], # Current deployment status
|
517
|
+
"DetailedStatus": StackInstance["StackInstanceStatus"]["DetailedStatus"]
|
518
|
+
if "DetailedStatus" in StackInstance["StackInstanceStatus"]
|
519
|
+
else None, # Detailed status for troubleshooting
|
520
|
+
"StatusReason": StackInstance["StatusReason"]
|
521
|
+
if "StatusReason" in StackInstance
|
522
|
+
else None, # Failure reason for operational analysis
|
523
|
+
"OrganizationalUnitId": StackInstance["OrganizationalUnitId"]
|
524
|
+
if "OrganizationalUnitId" in StackInstance
|
525
|
+
else None, # AWS Organizations OU for structural analysis
|
526
|
+
"PermissionModel": c_stackset_info["PermissionModel"]
|
527
|
+
if "PermissionModel" in c_stackset_info
|
528
|
+
else "SELF_MANAGED", # StackSet permission model for security analysis
|
529
|
+
"StackSetName": c_stacksetname, # Parent StackSet name for relationship tracking
|
530
|
+
}
|
531
|
+
)
|
532
|
+
elif not (StackInstance["Account"] in pAccountList):
|
533
|
+
# Skip instances that don't match the specified account filter
|
534
|
+
# Supports targeted operational analysis for specific accounts
|
535
|
+
logging.debug(
|
536
|
+
f"Found a stack instance, but the account didn't match {pAccountList}... exiting"
|
537
|
+
)
|
538
|
+
continue
|
539
|
+
|
540
|
+
except KeyError as my_Error:
|
541
|
+
# Handle missing key errors during instance metadata extraction
|
542
|
+
logging.error(f"Account Access failed - trying to access {c_stacksetname}")
|
543
|
+
logging.info(f"Actual Error: {my_Error}")
|
544
|
+
pass
|
545
|
+
except AttributeError as my_Error:
|
546
|
+
# Handle attribute errors likely caused by incorrect profile configuration
|
547
|
+
logging.error(f"Error: Likely that one of the supplied profiles was wrong")
|
548
|
+
logging.info(f"Actual Error: {my_Error}")
|
549
|
+
continue
|
550
|
+
except ClientError as my_Error:
|
551
|
+
# Handle AWS API errors including throttling and authorization failures
|
552
|
+
logging.error(f"Error: Likely throttling errors from too much activity")
|
553
|
+
logging.info(f"Actual Error: {my_Error}")
|
554
|
+
continue
|
555
|
+
finally:
|
556
|
+
# Complete processing and update progress tracking
|
557
|
+
logging.info(
|
558
|
+
f"{ERASE_LINE}Finished finding stack instances in stackset {c_stacksetname} in region {c_region} - {c_PlaceCount} / {len(fStackSetNames)}"
|
559
|
+
)
|
560
|
+
pbar.update() # Update progress bar for operational visibility
|
561
|
+
self.queue.task_done() # Mark queue item as completed
|
562
|
+
|
563
|
+
###########
|
564
|
+
|
565
|
+
# Initialize processing context and data structures
|
566
|
+
if fRegion is None:
|
567
|
+
fRegion = "us-east-1" # Default to primary AWS region for StackSet operations
|
568
|
+
checkqueue = Queue() # Queue for work distribution across worker threads
|
569
|
+
|
570
|
+
f_combined_stack_set_instances = [] # Aggregated results list for all discovered instances
|
571
|
+
PlaceCount = 0 # Progress counter for operational visibility
|
572
|
+
|
573
|
+
# Configure optimal worker thread count based on StackSet count and system limits
|
574
|
+
WorkerThreads = min(len(fStackSetNames), DefaultMaxWorkerThreads)
|
575
|
+
|
576
|
+
# Initialize progress tracking for operational visibility during discovery
|
577
|
+
pbar = tqdm(
|
578
|
+
desc=f"Finding Stackset instances from {len(fStackSetNames)} stacksets",
|
579
|
+
total=len(fStackSetNames),
|
580
|
+
unit=" stacksets",
|
581
|
+
)
|
582
|
+
|
583
|
+
# Create and start worker thread pool for concurrent StackSet instance discovery
|
584
|
+
for x in range(WorkerThreads):
|
585
|
+
worker = FindStackSets(checkqueue)
|
586
|
+
# Daemon threads allow main thread exit even if workers are still processing
|
587
|
+
worker.daemon = True
|
588
|
+
worker.start()
|
589
|
+
|
590
|
+
# Queue StackSet discovery work items for worker thread processing
|
591
|
+
for stacksetname in fStackSetNames:
|
592
|
+
logging.debug(f"Beginning to queue data - starting with {stacksetname}")
|
593
|
+
try:
|
594
|
+
# Queue StackSet information for worker thread processing
|
595
|
+
# Note: Tuple structure is critical for proper parameter expansion in worker threads
|
596
|
+
PlaceCount += 1
|
597
|
+
checkqueue.put((stacksetname, fRegion, stacksetname, PlaceCount))
|
598
|
+
except ClientError as my_Error:
|
599
|
+
# Handle authorization failures with informative error messaging
|
600
|
+
if "AuthFailure" in str(my_Error):
|
601
|
+
logging.error(
|
602
|
+
f"Authorization Failure accessing stack set {stacksetname['StackSetName']} in {fRegion} region"
|
603
|
+
)
|
604
|
+
logging.warning(f"It's possible that the region {fRegion} hasn't been opted-into")
|
605
|
+
pass
|
606
|
+
|
607
|
+
# Wait for all worker threads to complete processing
|
608
|
+
checkqueue.join()
|
609
|
+
pbar.close() # Close progress bar after completion
|
610
|
+
return f_combined_stack_set_instances
|
611
|
+
|
612
|
+
|
613
|
+
def find_last_operations(faws_acct: aws_acct_access, fStackSetNames: list):
|
614
|
+
"""
|
615
|
+
Discover and analyze the most recent operations for CloudFormation StackSets.
|
616
|
+
|
617
|
+
Retrieves the last operation performed on each StackSet for operational monitoring,
|
618
|
+
failure analysis, and deployment lifecycle tracking. Provides essential operational
|
619
|
+
insights for infrastructure teams managing large-scale StackSet deployments across
|
620
|
+
AWS Organizations environments.
|
621
|
+
|
622
|
+
Args:
|
623
|
+
faws_acct (aws_acct_access): Authenticated AWS account access object for StackSet operations
|
624
|
+
fStackSetNames (list): List of StackSet names for operation history discovery
|
625
|
+
|
626
|
+
Returns:
|
627
|
+
list: List of StackSet operation dictionaries containing:
|
628
|
+
- StackSetName: StackSet identifier for operation correlation
|
629
|
+
- Operation: Last operation type (CREATE_STACK_SET, UPDATE_STACK_SET, DELETE_STACK_SET)
|
630
|
+
- LatestStatus: Current status of the last operation (SUCCEEDED, FAILED, STOPPED)
|
631
|
+
- LatestDate: Completion timestamp for operational timeline analysis
|
632
|
+
- Details: Failed stack instances count for troubleshooting and analysis
|
633
|
+
|
634
|
+
Operation Discovery Features:
|
635
|
+
- Latest operation retrieval for each StackSet with comprehensive metadata
|
636
|
+
- Operation status tracking for deployment lifecycle monitoring
|
637
|
+
- Failure count analysis for operational excellence and troubleshooting
|
638
|
+
- Timestamp tracking for deployment pattern analysis and audit trails
|
639
|
+
|
640
|
+
Operational Monitoring:
|
641
|
+
- Progress tracking with real-time feedback during operation discovery
|
642
|
+
- Sequential processing for reliable operation history retrieval
|
643
|
+
- Comprehensive error handling for authorization and connectivity issues
|
644
|
+
- Operation metadata extraction for enterprise infrastructure governance
|
645
|
+
|
646
|
+
Enterprise Use Cases:
|
647
|
+
- Deployment failure analysis and operational troubleshooting
|
648
|
+
- StackSet lifecycle monitoring for infrastructure governance
|
649
|
+
- Operational dashboards and reporting for infrastructure management
|
650
|
+
- Compliance tracking and audit trail generation
|
651
|
+
|
652
|
+
Error Handling:
|
653
|
+
- AWS API error management with graceful degradation
|
654
|
+
- Authorization failure detection with appropriate logging
|
655
|
+
- Missing operation handling for newly created StackSets
|
656
|
+
- Comprehensive error reporting for troubleshooting
|
657
|
+
"""
|
658
|
+
# Initialize CloudFormation client for StackSet operations discovery
|
659
|
+
StackSetOps_client = faws_acct.session.client("cloudformation")
|
660
|
+
AllStackSetOps = []
|
661
|
+
|
662
|
+
# Discover last operation for each StackSet with progress tracking
|
663
|
+
for stacksetname in tqdm(fStackSetNames, desc="Checking stackset operations"):
|
664
|
+
# Retrieve most recent operation for the current StackSet
|
665
|
+
StackSetOps = StackSetOps_client.list_stack_set_operations(
|
666
|
+
StackSetName=stacksetname, MaxResults=1, CallAs="SELF"
|
667
|
+
)["Summaries"]
|
668
|
+
|
669
|
+
# Extract and aggregate operation metadata for analysis
|
670
|
+
AllStackSetOps.append(
|
671
|
+
{
|
672
|
+
"StackSetName": stacksetname, # StackSet identifier for correlation
|
673
|
+
"Operation": StackSetOps[0]["Action"], # Operation type for lifecycle tracking
|
674
|
+
"LatestStatus": StackSetOps[0]["Status"], # Current operation status
|
675
|
+
"LatestDate": StackSetOps[0]["EndTimestamp"], # Completion timestamp
|
676
|
+
"Details": StackSetOps[0]["StatusDetails"]["FailedStackInstancesCount"], # Failure count for analysis
|
677
|
+
}
|
678
|
+
)
|
679
|
+
return AllStackSetOps
|
680
|
+
|
681
|
+
|
682
|
+
##################
|
683
|
+
# Main
|
684
|
+
##################
|
685
|
+
if __name__ == "__main__":
|
686
|
+
args = parse_args(sys.argv[1:])
|
687
|
+
|
688
|
+
pProfile = args.Profile
|
689
|
+
pRegion = args.Region
|
690
|
+
pInstanceCount = args.pinstancecount
|
691
|
+
pRootOnly = args.RootOnly
|
692
|
+
verbose = args.loglevel
|
693
|
+
pTiming = args.Time
|
694
|
+
pStackfrag: list = args.Fragments
|
695
|
+
pExact: bool = args.Exact
|
696
|
+
pAccountList = args.Accounts
|
697
|
+
pstatus = args.pstatus
|
698
|
+
pFilename = args.Filename
|
699
|
+
# Setup logging levels
|
700
|
+
logging.basicConfig(level=verbose, format="[%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s")
|
701
|
+
logging.getLogger("boto3").setLevel(logging.CRITICAL)
|
702
|
+
logging.getLogger("botocore").setLevel(logging.CRITICAL)
|
703
|
+
logging.getLogger("s3transfer").setLevel(logging.CRITICAL)
|
704
|
+
logging.getLogger("urllib3").setLevel(logging.CRITICAL)
|
705
|
+
|
706
|
+
display_dict = {
|
707
|
+
"StackSetName": {"DisplayOrder": 1, "Heading": "Stackset Name"},
|
708
|
+
"Operation": {"DisplayOrder": 2, "Heading": "Action"},
|
709
|
+
"LatestStatus": {"DisplayOrder": 3, "Heading": "Last status", "Condition": ["FAILED", "STOPPED"]},
|
710
|
+
"LatestDate": {"DisplayOrder": 4, "Heading": "Last completed"},
|
711
|
+
"Details": {"DisplayOrder": 5, "Heading": "Failures"},
|
712
|
+
}
|
713
|
+
|
714
|
+
# Setup the aws_acct object
|
715
|
+
aws_acct, RegionList = setup_auth_and_regions(pProfile)
|
716
|
+
# Collect the stacksets, AccountList and RegionList involved
|
717
|
+
StackSets, Accounts, Regions = collect_cfnstacksets(aws_acct, pRegion)
|
718
|
+
# Get the last operations from the Stacksets we've found
|
719
|
+
StackSets_and_Operations = find_last_operations(aws_acct, StackSets["StackSetsList"])
|
720
|
+
# Display what we've found
|
721
|
+
sorted_StackSets_and_Operations = sorted(StackSets_and_Operations, key=lambda x: x["LatestDate"], reverse=True)
|
722
|
+
display_results(sorted_StackSets_and_Operations, display_dict, None, pFilename)
|
723
|
+
|
724
|
+
print()
|
725
|
+
print(ERASE_LINE)
|
726
|
+
print(
|
727
|
+
f"{Fore.RED}Found {len(StackSets['StackSetsList'])} Stacksets across {len(Accounts)} accounts across {len(Regions)} regions{Fore.RESET}"
|
728
|
+
)
|
729
|
+
print()
|
730
|
+
if pTiming:
|
731
|
+
print(ERASE_LINE)
|
732
|
+
print(f"{Fore.GREEN}This script took {time() - begin_time:.2f} seconds{Fore.RESET}")
|
733
|
+
print("Thanks for using this script...")
|
734
|
+
print()
|