runbooks 0.2.5__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 +7 -7
- runbooks/security_baseline/report_template_jp.html +7 -7
- runbooks/security_baseline/report_template_kr.html +12 -12
- runbooks/security_baseline/report_template_vn.html +7 -7
- 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.5.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.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/cfat/app.ts
ADDED
@@ -0,0 +1,644 @@
|
|
1
|
+
import {defineAccountType} from './src/actions/define-account-type.js';
|
2
|
+
import checkIamUsers from './src/actions/check-iam-users.js';
|
3
|
+
import getEnabledOrgPolicyTypes from './src/actions/get-enabled-org-policy-types.js';
|
4
|
+
import getEnabledOrgServices from './src/actions/get-enabled-org-services.js'
|
5
|
+
import getOrgCloudFormation from './src/actions/check-org-cloudformation.js';
|
6
|
+
import getIdcInfo from './src/actions/get-idc-info.js';
|
7
|
+
import getOrgDetails from './src/actions/get-org-details.js'
|
8
|
+
import getOrgTopLevelOus from './src/actions/get-org-ous.js';
|
9
|
+
import getAllRegions from './src/actions/get-regions.js';
|
10
|
+
import checkEc2Exists from './src/actions/check-ec2-existence.js';
|
11
|
+
import checkVpcExists from './src/actions/check-vpc-existence.js';
|
12
|
+
import checkCloudTrailExists from './src/actions/check-cloudtrail-existence.js';
|
13
|
+
import getOrgDaAccounts from './src/actions/get-org-da-accounts.js';
|
14
|
+
import checkConfigExists from './src/actions/check-config-existence.js';
|
15
|
+
import getOrgMemberAccounts from './src/actions/get-org-member-accounts.js';
|
16
|
+
import getControlTower from './src/actions/check-control-tower.js';
|
17
|
+
import checkLegacyCur from './src/actions/check-legacy-cur.js';
|
18
|
+
import createReport from './src/actions/create-report.js'
|
19
|
+
import createBacklog from './src/actions/create-backlog.js'
|
20
|
+
import createJiraImport from './src/actions/create-jiraimport.js'
|
21
|
+
import createAsanaImport from './src/actions/create-asanaimport.js';
|
22
|
+
import { CfatCheck, CloudFoundationAssessment, Task } from './src/types/index.js';
|
23
|
+
import zipAssessmentFiles from './src/actions/zip-assessment.js'
|
24
|
+
import * as fs from 'fs';
|
25
|
+
|
26
|
+
|
27
|
+
function objectToCSV(data: Record<string, any> | Record<string, any>[]): string {
|
28
|
+
const dataArray = Array.isArray(data) ? data : [data];
|
29
|
+
const keys = dataArray.length > 0 ? Object.keys(dataArray[0]) : [];
|
30
|
+
const rows = [keys.join(',')];
|
31
|
+
for (const obj of dataArray) {
|
32
|
+
const values = keys.map(key => {
|
33
|
+
const value = obj[key];
|
34
|
+
return typeof value === 'string' ? `"${value.replace(/"/g, '""')}"` : value;
|
35
|
+
});
|
36
|
+
rows.push(values.join(','));
|
37
|
+
}
|
38
|
+
return rows.join('\n');
|
39
|
+
}
|
40
|
+
|
41
|
+
const main = async (): Promise<void> => {
|
42
|
+
let report:CloudFoundationAssessment = {};
|
43
|
+
let cfatChecks:CfatCheck[] = [];
|
44
|
+
const region = process.env.AWS_REGION || 'us-east-1';
|
45
|
+
const allRegions = await getAllRegions();
|
46
|
+
console.log("discovering your AWS environment...")
|
47
|
+
const accountType = await defineAccountType(region);
|
48
|
+
let transitionalFound,suspendedFound,infrastructureFound:boolean = false;
|
49
|
+
let workloadsFound:boolean = false;
|
50
|
+
let securityFound:boolean = false;
|
51
|
+
let cfatIamUserPass:boolean = false;
|
52
|
+
let cfatIamIdPOrgServicePass:boolean = false;
|
53
|
+
let cfatIamIdcConfiguredPass:boolean = false;
|
54
|
+
let cfatCloudTrailPass:boolean = false;
|
55
|
+
let cfatCloudTrailOrgTrailPass:boolean = false;
|
56
|
+
let cfatVpcPass:boolean = true;
|
57
|
+
let cfatEc2Pass:boolean = false;
|
58
|
+
let cfatConfigManagementAccountPass:boolean = false;
|
59
|
+
let cfatConfigRecorderManagementAccountPass:boolean = false;
|
60
|
+
let cfatCloudTrailOrgServiceEnabledPass:boolean = false;
|
61
|
+
let cfatTagPoliciesEnabledPass:boolean = false;
|
62
|
+
let cfatScpEnabledPass:boolean = false;
|
63
|
+
let cfatBackupPoliciesEnabledPass:boolean = false;
|
64
|
+
let cfatOrgCloudFormationEnabledPass:boolean = false;
|
65
|
+
let cfatOrgCloudFormationStatusPass:boolean = false;
|
66
|
+
let cfatOrgServiceGuardDutyEnabledPass:boolean = false;
|
67
|
+
let cfatOrgServiceSecurityHubEnabledPass:boolean = false;
|
68
|
+
let cfatOrgServiceIamAccessAnalyzerEnabledPass:boolean = false;
|
69
|
+
let cfatOrgServiceAwsConfigEnabledPass:boolean = false;
|
70
|
+
let cfatOrgServiceRamEnabledPass:boolean = false;
|
71
|
+
let cfatControlTowerDeployedPass:boolean = false;
|
72
|
+
let cfatControlTowerNotDriftedPass:boolean = false;
|
73
|
+
let cfatControlTowerLatestVersionPass:boolean = false;
|
74
|
+
let cfatLogArchiveAccountPass:boolean = false;
|
75
|
+
let cfatAuditAccountPass:boolean = false;
|
76
|
+
let cfatManagementAccountPass:boolean = true;
|
77
|
+
let cfatOrgServiceBackupEnabledPass = false
|
78
|
+
|
79
|
+
if (accountType) {
|
80
|
+
report.organizationDeploy = accountType.isInOrganization
|
81
|
+
report.managementAccount = accountType.isManagementAccount
|
82
|
+
if(accountType.isManagementAccount === undefined){
|
83
|
+
accountType.isManagementAccount = false
|
84
|
+
console.log("AWS account is not the Management Account of an AWS Organization")
|
85
|
+
}
|
86
|
+
cfatManagementAccountPass = accountType.isManagementAccount;
|
87
|
+
}
|
88
|
+
|
89
|
+
console.log("discovering IAM Users...")
|
90
|
+
const iamUserResult = await checkIamUsers();
|
91
|
+
|
92
|
+
if (iamUserResult && iamUserResult.length > 0) {
|
93
|
+
console.log("IAM Users discovered.")
|
94
|
+
report.iamUserChecks = iamUserResult;
|
95
|
+
} else {
|
96
|
+
cfatIamUserPass = true
|
97
|
+
}
|
98
|
+
console.log("discovering EC2 instances across all AWS Regions...")
|
99
|
+
const ec2Check = await checkEc2Exists(allRegions);
|
100
|
+
if(ec2Check && ec2Check.find(param => param.ec2Found === true)){
|
101
|
+
report.ec2Checks = ec2Check
|
102
|
+
console.info("warning: EC2 instances discovered.")
|
103
|
+
for (const ec2 of ec2Check ){
|
104
|
+
cfatEc2Pass = false;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
console.log("discovering VPCs across all AWS Regions...")
|
108
|
+
const vpcCheck = await checkVpcExists(allRegions);
|
109
|
+
report.vpcChecks = vpcCheck;
|
110
|
+
if(vpcCheck && vpcCheck.length >0){
|
111
|
+
cfatVpcPass = false;
|
112
|
+
console.log("warning: VPCs discovered.")
|
113
|
+
}
|
114
|
+
console.log("discovering AWS Config configurations across all AWS Regions...")
|
115
|
+
report.cloudTrailDetails = await checkCloudTrailExists(allRegions);
|
116
|
+
report.configDetails = await checkConfigExists(allRegions);
|
117
|
+
if(report.configDetails && report.configDetails.find(param => param.configRecorderFound === true)){
|
118
|
+
for (const configFind of report.configDetails){
|
119
|
+
if(configFind.configRecorderFound){
|
120
|
+
cfatConfigManagementAccountPass = true
|
121
|
+
}
|
122
|
+
if(configFind.configDeliveryChannelFound){
|
123
|
+
cfatConfigRecorderManagementAccountPass = true
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
// all the following calls require an AWS Organization to exist and the account be a management account
|
128
|
+
if (accountType.isInOrganization && accountType.isManagementAccount) {
|
129
|
+
console.log("collecting general AWS Organization details...")
|
130
|
+
const orgDetails = await getOrgDetails('us-east-1');
|
131
|
+
console.log("collecting CUR details...")
|
132
|
+
const legacyCurCheck = await checkLegacyCur('us-east-1');
|
133
|
+
console.log("collecting AWS Organization Policy details...")
|
134
|
+
const enableOrgPoliciesCheck = await getEnabledOrgPolicyTypes('us-east-1');
|
135
|
+
console.log("collecting AWS Organization service trusted access details...")
|
136
|
+
report.orgServices = await getEnabledOrgServices('us-east-1');
|
137
|
+
console.log("collecting AWS Organization CloudFormation status details...")
|
138
|
+
const cfnOrgStatus = await getOrgCloudFormation(region);
|
139
|
+
console.log("collecting AWS Control Tower details...")
|
140
|
+
const controlTowerDetails = await getControlTower(region);
|
141
|
+
report.idcInfo= await getIdcInfo(allRegions);
|
142
|
+
console.log("collecting AWS Organization service delegated admin details...")
|
143
|
+
report.orgDelegatedAdminAccounts = await getOrgDaAccounts();
|
144
|
+
console.log("collecting AWS Organization member account details...")
|
145
|
+
report.orgMemberAccounts = await getOrgMemberAccounts();
|
146
|
+
report.isLegacyCurSetup = legacyCurCheck.isLegacyCurSetup
|
147
|
+
report.orgArn = orgDetails.arn
|
148
|
+
report.orgId = orgDetails.id
|
149
|
+
report.orgRootOuId = orgDetails.rootOuId
|
150
|
+
report.backupPolicyEnabled = enableOrgPoliciesCheck.backupPolicyEnabled;
|
151
|
+
report.scpEnabled = enableOrgPoliciesCheck.scpEnabled;
|
152
|
+
report.tagPolicyEnabled = enableOrgPoliciesCheck.tagPolicyEnabled;
|
153
|
+
report.orgCloudFormationStatus = cfnOrgStatus.status
|
154
|
+
report.controlTowerDeployedVersion = controlTowerDetails.deployedVersion
|
155
|
+
report.controlTowerDriftStatus= controlTowerDetails.driftStatus
|
156
|
+
report.controlTowerLatestAvailableVersion = controlTowerDetails.latestAvailableVersion
|
157
|
+
report.controlTowerRegion = controlTowerDetails.controlTowerRegion
|
158
|
+
report.controlTowerStatus = controlTowerDetails.status
|
159
|
+
if(report.idcInfo.arn){
|
160
|
+
cfatIamIdcConfiguredPass = true;
|
161
|
+
}
|
162
|
+
if(report.cloudTrailDetails && report.cloudTrailDetails.length > 0) {
|
163
|
+
cfatCloudTrailPass = true;
|
164
|
+
for(const ctFind of report.cloudTrailDetails){
|
165
|
+
if(ctFind.trailFound){
|
166
|
+
if(ctFind.isOrgTrail){cfatCloudTrailOrgTrailPass = true}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
if(report.orgServices.find(param=> param.service === 'cloudtrail.amazonaws.com')){
|
171
|
+
cfatCloudTrailOrgServiceEnabledPass = true;
|
172
|
+
}
|
173
|
+
if(report.orgServices.find(param=> param.service === 'config.amazonaws.com')){
|
174
|
+
cfatOrgServiceAwsConfigEnabledPass = true;
|
175
|
+
}
|
176
|
+
if(enableOrgPoliciesCheck.scpEnabled) {
|
177
|
+
cfatScpEnabledPass = true;
|
178
|
+
}
|
179
|
+
if(enableOrgPoliciesCheck.tagPolicyEnabled) {
|
180
|
+
cfatTagPoliciesEnabledPass = true;
|
181
|
+
}
|
182
|
+
if(enableOrgPoliciesCheck.backupPolicyEnabled) {
|
183
|
+
cfatBackupPoliciesEnabledPass = true;
|
184
|
+
}
|
185
|
+
if(orgDetails.rootOuId){
|
186
|
+
console.log("collecting OU and member account details...")
|
187
|
+
report.orgOuInfo = await getOrgTopLevelOus('us-east-1', orgDetails.rootOuId);
|
188
|
+
if(report.orgOuInfo && report.orgOuInfo.length > 0){
|
189
|
+
for (const ou of report.orgOuInfo){
|
190
|
+
if(ou.name?.toLowerCase() === 'suspended'){suspendedFound = true}
|
191
|
+
if(ou.name?.toLowerCase() === 'transitional'){transitionalFound = true}
|
192
|
+
if(ou.name?.toLowerCase() === 'workloads'){workloadsFound=true}
|
193
|
+
if(ou.name?.toLowerCase() === 'security'){securityFound=true}
|
194
|
+
if(ou.name?.toLowerCase() === 'infrastructure'){infrastructureFound=true}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
}
|
198
|
+
if(report.orgMemberAccounts && report.orgMemberAccounts.length > 0){
|
199
|
+
for (const memberAccount of report.orgMemberAccounts){
|
200
|
+
if(memberAccount.accountName){
|
201
|
+
if(memberAccount.accountName.toLowerCase() === 'log archive'){cfatLogArchiveAccountPass = true;}
|
202
|
+
if(memberAccount.accountName.toLowerCase() === 'audit'){cfatAuditAccountPass = true;}
|
203
|
+
if(memberAccount.accountName.toLowerCase() === 'security tooling'){cfatAuditAccountPass = true;}
|
204
|
+
}
|
205
|
+
}
|
206
|
+
}
|
207
|
+
let identityDelegated:boolean = false
|
208
|
+
let securityHubDelegated:boolean = false
|
209
|
+
let guardDutyDelegated:boolean = false
|
210
|
+
let configDelegated:boolean = false
|
211
|
+
let iamAccessAnalyzerDelegated:boolean = false
|
212
|
+
let s3StorageLensDelegated:boolean = false
|
213
|
+
let ipamDelegated:boolean = false
|
214
|
+
let accountDelegated:boolean = false
|
215
|
+
let backupDelegated:boolean = false
|
216
|
+
if(report.orgDelegatedAdminAccounts && report.orgDelegatedAdminAccounts.length > 0){
|
217
|
+
for (const account of report.orgDelegatedAdminAccounts){
|
218
|
+
if(account.services && account.services.length > 0 ){
|
219
|
+
for (const srv of account.services){
|
220
|
+
if(srv.ServicePrincipal === 'securityhub.amazonaws.com'){securityHubDelegated=true}
|
221
|
+
if(srv.ServicePrincipal === 'guardduty.amazonaws.com'){guardDutyDelegated=true}
|
222
|
+
if(srv.ServicePrincipal === 'sso.amazonaws.com'){identityDelegated=true}
|
223
|
+
if(srv.ServicePrincipal === 'config.amazonaws.com'){configDelegated=true}
|
224
|
+
if(srv.ServicePrincipal === 'access-analyzer.amazonaws.com'){iamAccessAnalyzerDelegated=true}
|
225
|
+
if(srv.ServicePrincipal === 'storage-lens.s3.amazonaws.com'){s3StorageLensDelegated=true}
|
226
|
+
if(srv.ServicePrincipal === 'ipam.amazonaws.com'){ipamDelegated=true}
|
227
|
+
if(srv.ServicePrincipal === 'account.amazonaws.com'){accountDelegated=true}
|
228
|
+
if(srv.ServicePrincipal === 'backup.amazonaws.com'){backupDelegated=true}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
if(controlTowerDetails.controlTowerRegion){
|
234
|
+
cfatControlTowerDeployedPass = true;
|
235
|
+
}
|
236
|
+
if(controlTowerDetails.driftStatus !== 'DRIFTED'){
|
237
|
+
cfatControlTowerNotDriftedPass = true;
|
238
|
+
}
|
239
|
+
if(controlTowerDetails.deployedVersion === controlTowerDetails.latestAvailableVersion){
|
240
|
+
cfatControlTowerLatestVersionPass = true;
|
241
|
+
}
|
242
|
+
if(report.orgServices.find(param=> param.service === 'member.org.stacksets.cloudformation.amazonaws.com')){
|
243
|
+
cfatOrgCloudFormationStatusPass = true
|
244
|
+
}
|
245
|
+
if(report.orgServices.find(param=> param.service === 'sso.amazonaws.com')){
|
246
|
+
cfatIamIdPOrgServicePass = true;
|
247
|
+
}
|
248
|
+
if(report.orgServices.find(param=> param.service === 'guardduty.amazonaws.com')){
|
249
|
+
cfatOrgServiceGuardDutyEnabledPass = true;
|
250
|
+
}
|
251
|
+
if(report.orgServices.find(param=> param.service === 'securityhub.amazonaws.com')){
|
252
|
+
cfatOrgServiceSecurityHubEnabledPass = true;
|
253
|
+
}
|
254
|
+
if(report.orgServices.find(param=> param.service === 'access-analyzer.amazonaws.com')){
|
255
|
+
cfatOrgServiceIamAccessAnalyzerEnabledPass = true;
|
256
|
+
}
|
257
|
+
if(report.orgServices.find(param=> param.service === 'ram.amazonaws.com')){
|
258
|
+
cfatOrgServiceRamEnabledPass = true;
|
259
|
+
}
|
260
|
+
if(report.orgServices.find(param=> param.service === 'backup.amazonaws.com')){
|
261
|
+
cfatOrgServiceBackupEnabledPass = true;
|
262
|
+
}
|
263
|
+
if(report.orgCloudFormationStatus === 'ENABLED'){
|
264
|
+
cfatOrgCloudFormationEnabledPass = true;
|
265
|
+
}
|
266
|
+
|
267
|
+
} else if (accountType.isInOrganization && !accountType.isManagementAccount) {
|
268
|
+
const message:string = '\nWARNING: You are running CFAT from an account that is a member of your AWS Organization. Please run the solution from your AWS Management account.'
|
269
|
+
console.warn(message);
|
270
|
+
} else {
|
271
|
+
const message:string = '\nWARNING: You are running CFAT from an account that not part of an AWS Organization. This account will be treated as a standalone account.'
|
272
|
+
console.warn(message);
|
273
|
+
}
|
274
|
+
|
275
|
+
let OrgCheck:CfatCheck = {
|
276
|
+
check: "AWS Organization created",
|
277
|
+
description: "AWS Organization is enabled.",
|
278
|
+
status: accountType.isInOrganization ? "complete": "incomplete",
|
279
|
+
required: true,
|
280
|
+
weight: 6,
|
281
|
+
loe: 1,
|
282
|
+
remediationLink: "https://aws.amazon.com/organizations/getting-started/"
|
283
|
+
}
|
284
|
+
cfatChecks.push(OrgCheck);
|
285
|
+
|
286
|
+
let MACheck:CfatCheck = {
|
287
|
+
check: "Management Account created",
|
288
|
+
description: "AWS Management account exists.",
|
289
|
+
status: cfatManagementAccountPass ? "complete": "incomplete",
|
290
|
+
required: true,
|
291
|
+
weight: 6,
|
292
|
+
loe: 1,
|
293
|
+
remediationLink: "https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-creating.html"
|
294
|
+
}
|
295
|
+
cfatChecks.push(MACheck);
|
296
|
+
|
297
|
+
const cfatIamUserCheck:CfatCheck = {
|
298
|
+
check: "Management Account IAM users removed",
|
299
|
+
description: "IAM Users should not exist in Management Account.",
|
300
|
+
status: cfatIamUserPass ? "complete": "incomplete",
|
301
|
+
required: false,
|
302
|
+
weight: 4,
|
303
|
+
loe: 1,
|
304
|
+
remediationLink: "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html#id_users_deleting"
|
305
|
+
}
|
306
|
+
cfatChecks.push(cfatIamUserCheck);
|
307
|
+
|
308
|
+
const cfatEc2Check:CfatCheck = {
|
309
|
+
check: "Management Account EC2 instances removed",
|
310
|
+
description: "EC2 Instances should not exist in Management Account.",
|
311
|
+
status: cfatEc2Pass ? "complete": "incomplete",
|
312
|
+
required: false,
|
313
|
+
weight: 4,
|
314
|
+
loe: 1,
|
315
|
+
remediationLink: "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html"
|
316
|
+
}
|
317
|
+
cfatChecks.push(cfatEc2Check);
|
318
|
+
|
319
|
+
const cfatVpcCheck:CfatCheck = {
|
320
|
+
check: "Management Account VPCs removed",
|
321
|
+
description: "Management Account should not have any VPCs.",
|
322
|
+
status: cfatVpcPass ? "complete": "incomplete",
|
323
|
+
required: false,
|
324
|
+
weight: 4,
|
325
|
+
loe: 1,
|
326
|
+
remediationLink: "https://github.com/cloud-foundations-on-aws/cloud-foundations-templates/blob/main/network/network-default-vpc-deletion/README.md"
|
327
|
+
}
|
328
|
+
cfatChecks.push(cfatVpcCheck);
|
329
|
+
|
330
|
+
const cfatLegacyCurCheck:CfatCheck = {
|
331
|
+
check: "Legacy CUR setup",
|
332
|
+
description: "Legacy Cost and Usage Report (CUR) should be setup or data exports.",
|
333
|
+
status: report.isLegacyCurSetup ? "complete": "incomplete",
|
334
|
+
required: false,
|
335
|
+
weight: 4,
|
336
|
+
loe: 1,
|
337
|
+
remediationLink: "https://docs.aws.amazon.com/cur/latest/userguide/dataexports-create-legacy.html"
|
338
|
+
}
|
339
|
+
|
340
|
+
const cfatCloudTrailCheck:CfatCheck = {
|
341
|
+
check: "CloudTrail Trail created",
|
342
|
+
description: "CloudTrail should be enabled within the account.",
|
343
|
+
status: cfatCloudTrailPass ? "complete": "incomplete",
|
344
|
+
required: true,
|
345
|
+
weight: 6,
|
346
|
+
loe: 3,
|
347
|
+
remediationLink: "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/creating-trail-organization.html"
|
348
|
+
}
|
349
|
+
cfatChecks.push(cfatCloudTrailCheck);
|
350
|
+
|
351
|
+
const cfatCloudTrailOrgServiceEnabledCheck:CfatCheck = {
|
352
|
+
check: "CloudTrail Organization Service enabled",
|
353
|
+
description: "CloudTrail should be enabled on the Organization.",
|
354
|
+
status: cfatCloudTrailOrgServiceEnabledPass ? "complete": "incomplete",
|
355
|
+
required: true,
|
356
|
+
weight: 6,
|
357
|
+
loe: 1,
|
358
|
+
remediationLink:"https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-cloudtrail.html"
|
359
|
+
}
|
360
|
+
cfatChecks.push(cfatCloudTrailOrgServiceEnabledCheck);
|
361
|
+
|
362
|
+
const cfatCloudTrailOrgTrailCheck:CfatCheck = {
|
363
|
+
check: "CloudTrail Org Trail deployed",
|
364
|
+
description: "At least one CloudTrail Organization Trail should be enabled.",
|
365
|
+
status: cfatCloudTrailOrgTrailPass ? "complete": "incomplete",
|
366
|
+
required: true,
|
367
|
+
weight: 6,
|
368
|
+
loe: 1,
|
369
|
+
remediationLink:"https://docs.aws.amazon.com/awscloudtrail/latest/userguide/creating-trail-organization.html"
|
370
|
+
}
|
371
|
+
cfatChecks.push(cfatCloudTrailOrgTrailCheck);
|
372
|
+
|
373
|
+
const cfatConfigManagementAccountCheck:CfatCheck = {
|
374
|
+
check: "Config Recorder in Management Account configured",
|
375
|
+
description: "Config Recorder in the Management Account should be enabled.",
|
376
|
+
status: cfatConfigManagementAccountPass ? "complete": "incomplete",
|
377
|
+
required: true,
|
378
|
+
weight: 6,
|
379
|
+
loe: 2,
|
380
|
+
remediationLink: "https://aws.amazon.com/blogs/mt/managing-aws-organizations-accounts-using-aws-config-and-aws-cloudformation-stacksets/"
|
381
|
+
}
|
382
|
+
cfatChecks.push(cfatConfigManagementAccountCheck);
|
383
|
+
|
384
|
+
const cfatConfigRecorderManagementAccountCheck:CfatCheck= {
|
385
|
+
check: "Config Delivery Channel in Management Account configured",
|
386
|
+
description: "Config Delivery Channel in Management Account should be enabled.",
|
387
|
+
status: cfatConfigRecorderManagementAccountPass ? "complete": "incomplete",
|
388
|
+
required: true,
|
389
|
+
weight: 6,
|
390
|
+
loe: 2,
|
391
|
+
remediationLink: "https://aws.amazon.com/blogs/mt/managing-aws-organizations-accounts-using-aws-config-and-aws-cloudformation-stacksets/"
|
392
|
+
}
|
393
|
+
cfatChecks.push(cfatConfigRecorderManagementAccountCheck);
|
394
|
+
|
395
|
+
const cfatCloudFormationEnableCheck:CfatCheck = {
|
396
|
+
check: "CloudFormation StackSets activated",
|
397
|
+
description: "CloudFormation StackSets should be activated in the CloudFormation console.",
|
398
|
+
status: cfatOrgCloudFormationEnabledPass ? "complete": "incomplete",
|
399
|
+
required: false,
|
400
|
+
weight: 5,
|
401
|
+
loe: 1,
|
402
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-cloudformation.html#integrate-enable-ta-cloudformation"
|
403
|
+
}
|
404
|
+
cfatChecks.push(cfatCloudFormationEnableCheck);
|
405
|
+
|
406
|
+
const cfatOrgServiceGuardDutyCheck:CfatCheck = {
|
407
|
+
check: "GuardDuty Organization service enabled",
|
408
|
+
description: "GuardDuty Organization services should be enabled.",
|
409
|
+
status: cfatOrgServiceGuardDutyEnabledPass ? "complete": "incomplete",
|
410
|
+
required: false,
|
411
|
+
weight: 4,
|
412
|
+
loe: 1,
|
413
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-guardduty.html#integrate-enable-ta-guardduty"
|
414
|
+
}
|
415
|
+
cfatChecks.push(cfatOrgServiceGuardDutyCheck);
|
416
|
+
|
417
|
+
const cfatOrgServiceRamCheck:CfatCheck = {
|
418
|
+
check: "RAM Organization service enabled",
|
419
|
+
description: "Resource Access Manager (RAM) trusted access should be enabled in the AWS Organization.",
|
420
|
+
status: cfatOrgServiceRamEnabledPass ? "complete": "incomplete",
|
421
|
+
required: false,
|
422
|
+
weight: 4,
|
423
|
+
loe: 1,
|
424
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-ram.html#integrate-enable-ta-ram"
|
425
|
+
}
|
426
|
+
cfatChecks.push(cfatOrgServiceRamCheck);
|
427
|
+
|
428
|
+
const cfatOrgServiceSecurityHubCheck:CfatCheck = {
|
429
|
+
check: "Security Hub Organization service enabled",
|
430
|
+
description: "Security Hub trusted access should be enabled in the AWS Organization.",
|
431
|
+
status: cfatOrgServiceSecurityHubEnabledPass ? "complete": "incomplete",
|
432
|
+
required: false,
|
433
|
+
weight: 4,
|
434
|
+
loe: 1,
|
435
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-securityhub.html#integrate-enable-ta-securityhub"
|
436
|
+
}
|
437
|
+
cfatChecks.push(cfatOrgServiceSecurityHubCheck);
|
438
|
+
|
439
|
+
const cfatOrgServiceIamAccessAnalyzerCheck:CfatCheck = {
|
440
|
+
check: "IAM Access Analyzer Organization service enabled",
|
441
|
+
description: "IAM Access Analyzer trusted access should be enabled in the AWS Organization.",
|
442
|
+
status: cfatOrgServiceIamAccessAnalyzerEnabledPass ? "complete": "incomplete",
|
443
|
+
required: false,
|
444
|
+
weight: 4,
|
445
|
+
loe: 1,
|
446
|
+
remediationLink: "https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html#access-analyzer-enabling"
|
447
|
+
}
|
448
|
+
cfatChecks.push(cfatOrgServiceIamAccessAnalyzerCheck);
|
449
|
+
|
450
|
+
const cfatOrgServiceConfigCheck:CfatCheck = {
|
451
|
+
check: "Config Organization service enabled",
|
452
|
+
description: "AWS Config trusted access should be enabled in the AWS Organization.",
|
453
|
+
status: cfatOrgServiceAwsConfigEnabledPass ? "complete": "incomplete",
|
454
|
+
required: false,
|
455
|
+
weight: 4,
|
456
|
+
loe: 1,
|
457
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-config.html#integrate-enable-ta-config"
|
458
|
+
}
|
459
|
+
cfatChecks.push(cfatOrgServiceConfigCheck);
|
460
|
+
|
461
|
+
const cfatOrgServiceCloudFormationCheck:CfatCheck = {
|
462
|
+
check: "CloudFormation Organization service enabled",
|
463
|
+
description: "CloudFormation trusted access should be enabled in the AWS Organization.",
|
464
|
+
status: cfatOrgCloudFormationStatusPass ? "complete": "incomplete",
|
465
|
+
required: false,
|
466
|
+
weight: 5,
|
467
|
+
loe: 1,
|
468
|
+
remediationLink: "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-orgs-activate-trusted-access.html"
|
469
|
+
}
|
470
|
+
cfatChecks.push(cfatOrgServiceCloudFormationCheck)
|
471
|
+
|
472
|
+
const cfatOrgServiceBackupCheck:CfatCheck = {
|
473
|
+
check: "Backup Organization service enabled",
|
474
|
+
description: "Backup trusted access should be enabled in the AWS Organization.",
|
475
|
+
status: cfatOrgServiceBackupEnabledPass ? "complete": "incomplete",
|
476
|
+
required: false,
|
477
|
+
weight: 4,
|
478
|
+
loe: 1,
|
479
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/services-that-can-integrate-backup.html#integrate-enable-ta-backup"
|
480
|
+
}
|
481
|
+
|
482
|
+
const cfatInfraOuCheck:CfatCheck = {
|
483
|
+
check: "Top-level Infrastructure OU deployed",
|
484
|
+
description: "Top-level Infrastructure OU should exist.",
|
485
|
+
status: infrastructureFound ? "complete": "incomplete",
|
486
|
+
required: false,
|
487
|
+
weight: 5,
|
488
|
+
loe: 2,
|
489
|
+
remediationLink: "https://catalog.workshops.aws/control-tower/en-US/introduction/manage-ou"
|
490
|
+
}
|
491
|
+
cfatChecks.push(cfatInfraOuCheck);
|
492
|
+
|
493
|
+
const cfatSecurityOuCheck:CfatCheck = {
|
494
|
+
check: "Top-level Security OU deployed",
|
495
|
+
description: "Top-level Security OU should exist.",
|
496
|
+
status: securityFound ? "complete": "incomplete",
|
497
|
+
required: true,
|
498
|
+
weight: 6,
|
499
|
+
loe: 2,
|
500
|
+
remediationLink: "https://catalog.workshops.aws/control-tower/en-US/introduction/manage-ou"
|
501
|
+
}
|
502
|
+
cfatChecks.push(cfatSecurityOuCheck);
|
503
|
+
|
504
|
+
const cfatWorkloadOuCheck:CfatCheck = {
|
505
|
+
check: "Top-level Workloads OU deployed",
|
506
|
+
description: "Top-level Workloads OU should exist.",
|
507
|
+
status: workloadsFound ? "complete": "incomplete",
|
508
|
+
required: false,
|
509
|
+
weight: 5,
|
510
|
+
loe: 2,
|
511
|
+
remediationLink: "https://catalog.workshops.aws/control-tower/en-US/introduction/manage-ou"
|
512
|
+
}
|
513
|
+
cfatChecks.push(cfatWorkloadOuCheck);
|
514
|
+
|
515
|
+
const cfatIamIdCOrgServiceCheck:CfatCheck = {
|
516
|
+
check: "IAM IdC Organization service enabled",
|
517
|
+
description: "IAM Identity Center trusted access should be enabled in the AWS Organization",
|
518
|
+
status: cfatIamIdPOrgServicePass ? "complete": "incomplete",
|
519
|
+
required: true,
|
520
|
+
weight: 6,
|
521
|
+
loe: 1,
|
522
|
+
remediationLink: "https://docs.aws.amazon.com/singlesignon/latest/userguide/get-set-up-for-idc.html"
|
523
|
+
}
|
524
|
+
cfatChecks.push(cfatIamIdCOrgServiceCheck);
|
525
|
+
|
526
|
+
const cfatIamIdcConfiguredCheck:CfatCheck = {
|
527
|
+
check: "IAM IdC configured",
|
528
|
+
description: "IAM Identity Center should be configured.",
|
529
|
+
status: cfatIamIdcConfiguredPass ? "complete": "incomplete",
|
530
|
+
required: true,
|
531
|
+
weight: 6,
|
532
|
+
loe: 3,
|
533
|
+
remediationLink: "https://docs.aws.amazon.com/singlesignon/latest/userguide/tutorials.html"
|
534
|
+
}
|
535
|
+
cfatChecks.push(cfatIamIdcConfiguredCheck);
|
536
|
+
|
537
|
+
const cfatOrgPolicyScpEnabled:CfatCheck = {
|
538
|
+
check: "Service Control Policies enabled",
|
539
|
+
description: "Service Control Policy should be enabled within the AWS Organization.",
|
540
|
+
status: cfatScpEnabledPass ? "complete": "incomplete",
|
541
|
+
required: true,
|
542
|
+
weight: 6,
|
543
|
+
loe: 1,
|
544
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_enable-disable.html"
|
545
|
+
}
|
546
|
+
cfatChecks.push(cfatOrgPolicyScpEnabled);
|
547
|
+
|
548
|
+
const cfatOrgPolicyTagPolicyCheck:CfatCheck = {
|
549
|
+
check: "Organization Tag Policy enabled",
|
550
|
+
description: "Tag Policy should be enabled within the AWS Organization.",
|
551
|
+
status: cfatTagPoliciesEnabledPass ? "complete": "incomplete",
|
552
|
+
required: true,
|
553
|
+
weight: 6,
|
554
|
+
loe: 1,
|
555
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_enable-disable.html"
|
556
|
+
}
|
557
|
+
cfatChecks.push(cfatOrgPolicyTagPolicyCheck);
|
558
|
+
|
559
|
+
const cfatBackupPoliciesEnabledCheck:CfatCheck = {
|
560
|
+
check: "Organization Backup Policy enabled",
|
561
|
+
description: "Backup Policy should be enabled within the AWS Organization.",
|
562
|
+
status: cfatBackupPoliciesEnabledPass ? "complete": "incomplete",
|
563
|
+
required: false,
|
564
|
+
weight: 5,
|
565
|
+
loe: 1,
|
566
|
+
remediationLink: "https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_enable-disable.html"
|
567
|
+
}
|
568
|
+
cfatChecks.push(cfatBackupPoliciesEnabledCheck);
|
569
|
+
|
570
|
+
const cfatControlTowerDeployedCheck:CfatCheck= {
|
571
|
+
check: "Control Tower deployed",
|
572
|
+
description: "Control Tower should be deployed.",
|
573
|
+
status: cfatControlTowerDeployedPass ? "complete": "incomplete",
|
574
|
+
required: true,
|
575
|
+
weight: 6,
|
576
|
+
loe: 6,
|
577
|
+
remediationLink: "https://catalog.workshops.aws/control-tower/en-US/prerequisites/deploying"
|
578
|
+
}
|
579
|
+
cfatChecks.push(cfatControlTowerDeployedCheck);
|
580
|
+
|
581
|
+
const cfatControlTowerLatestVersionCheck:CfatCheck = {
|
582
|
+
check: "Control Tower latest version",
|
583
|
+
description: "Control Tower should be the latest version.",
|
584
|
+
status: cfatControlTowerLatestVersionPass ? "complete": "incomplete",
|
585
|
+
required: false,
|
586
|
+
weight: 5,
|
587
|
+
loe: 2,
|
588
|
+
remediationLink: "https://docs.aws.amazon.com/controltower/latest/userguide/update-controltower.html"
|
589
|
+
}
|
590
|
+
cfatChecks.push(cfatControlTowerLatestVersionCheck);
|
591
|
+
|
592
|
+
const cfatControlTowerNotDriftedCheck:CfatCheck = {
|
593
|
+
check: "Control Tower not drifted",
|
594
|
+
description: "Control Tower should not be drifted.",
|
595
|
+
status: cfatControlTowerNotDriftedPass ? "complete": "incomplete",
|
596
|
+
required: true,
|
597
|
+
weight: 6,
|
598
|
+
loe: 2,
|
599
|
+
remediationLink:"https://docs.aws.amazon.com/controltower/latest/userguide/resolve-drift.html"
|
600
|
+
}
|
601
|
+
cfatChecks.push(cfatControlTowerNotDriftedCheck);
|
602
|
+
|
603
|
+
const cfatLogArchiveAccountCheck:CfatCheck = {
|
604
|
+
check: "Log Archive account deployed",
|
605
|
+
description: "Log Archive account should exist.",
|
606
|
+
status: cfatLogArchiveAccountPass ? "complete": "incomplete",
|
607
|
+
required: true,
|
608
|
+
weight: 6,
|
609
|
+
loe: 2,
|
610
|
+
remediationLink: "https://docs.aws.amazon.com/controltower/latest/userguide/getting-started-from-console.html"
|
611
|
+
}
|
612
|
+
cfatChecks.push(cfatLogArchiveAccountCheck);
|
613
|
+
|
614
|
+
const cfatAuditAccountCheck:CfatCheck = {
|
615
|
+
check: "Audit account deployed",
|
616
|
+
description: "Audit/Security Tooling account should exist.",
|
617
|
+
status: cfatAuditAccountPass ? "complete": "incomplete",
|
618
|
+
required: true,
|
619
|
+
weight: 6,
|
620
|
+
loe: 2,
|
621
|
+
remediationLink: "https://docs.aws.amazon.com/controltower/latest/userguide/getting-started-from-console.html"
|
622
|
+
}
|
623
|
+
cfatChecks.push(cfatAuditAccountCheck);
|
624
|
+
|
625
|
+
report.cfatChecks = cfatChecks
|
626
|
+
|
627
|
+
console.table(cfatChecks, ["check", "status","required", "loe"]);
|
628
|
+
// write CFAT checks to CSV file for use in the CFAT report
|
629
|
+
const cfatChecksCsvFile = "./cfat-checks.csv"
|
630
|
+
console.log(`writing assessment summary checks to ./cfat/cfat-checks.csv...`)
|
631
|
+
const objectArrayCSV = objectToCSV(cfatChecks);
|
632
|
+
fs.writeFileSync(cfatChecksCsvFile, objectArrayCSV);
|
633
|
+
|
634
|
+
const reportFile = "./cfat.txt"
|
635
|
+
const tasks:Task[] = await createReport(report)
|
636
|
+
const backlog:Task[] = await createBacklog(report);
|
637
|
+
console.log(`cloud foundation assessment complete. Access your report at ./cfat/cfat.txt`)
|
638
|
+
console.log(`assessment summary checks written to ./cfat/cfat-checks.csv`)
|
639
|
+
createJiraImport(backlog)
|
640
|
+
await createAsanaImport(backlog);
|
641
|
+
await zipAssessmentFiles();
|
642
|
+
console.log(`assessment files zipped to ./cfat/assessment.zip`)
|
643
|
+
};
|
644
|
+
main();
|
@@ -0,0 +1,40 @@
|
|
1
|
+
"""
|
2
|
+
Assessment Engine for Cloud Foundations Assessment Tool.
|
3
|
+
|
4
|
+
This module contains the core assessment logic including:
|
5
|
+
- Assessment execution orchestration
|
6
|
+
- AWS resource collectors
|
7
|
+
- Compliance rule validation
|
8
|
+
- Check discovery and management
|
9
|
+
|
10
|
+
The assessment engine provides modular, extensible assessment
|
11
|
+
capabilities with enterprise-grade performance and reliability.
|
12
|
+
"""
|
13
|
+
|
14
|
+
from runbooks.cfat.assessment.collectors import (
|
15
|
+
CloudTrailCollector,
|
16
|
+
ConfigCollector,
|
17
|
+
EC2Collector,
|
18
|
+
IAMCollector,
|
19
|
+
OrganizationsCollector,
|
20
|
+
VPCCollector,
|
21
|
+
)
|
22
|
+
from runbooks.cfat.assessment.runner import CloudFoundationsAssessment
|
23
|
+
from runbooks.cfat.assessment.validators import (
|
24
|
+
ComplianceValidator,
|
25
|
+
OperationalValidator,
|
26
|
+
SecurityValidator,
|
27
|
+
)
|
28
|
+
|
29
|
+
__all__ = [
|
30
|
+
"CloudFoundationsAssessment",
|
31
|
+
"IAMCollector",
|
32
|
+
"VPCCollector",
|
33
|
+
"CloudTrailCollector",
|
34
|
+
"ConfigCollector",
|
35
|
+
"OrganizationsCollector",
|
36
|
+
"EC2Collector",
|
37
|
+
"ComplianceValidator",
|
38
|
+
"SecurityValidator",
|
39
|
+
"OperationalValidator",
|
40
|
+
]
|