@@ -669,6 +669,9 @@ def deploy_config_rules(region, accounts, resource_properties):
669669 for acct in accounts :
670670
671671 if rule_deploy is False :
672+ LOGGER .info (f"{ rule_name } is not to be deployed. Checking to see if it needs to be removed..." )
673+ delete_custom_config_rule (rule_name , acct , region )
674+ delete_custom_config_iam_role (rule_name , acct )
672675 continue
673676 if rule_accounts :
674677 LOGGER .info (f"{ rule_name } accounts: { rule_accounts } " )
@@ -1173,9 +1176,127 @@ def update_event(event, context):
11731176 # cfnresponse.send(event, context, cfnresponse.SUCCESS, data, CFN_RESOURCE_ID)
11741177 return CFN_RESOURCE_ID
11751178
1179+ def delete_custom_config_rule (rule_name : str , acct : str , region : str ):
1180+ # Delete the config rule
1181+ config .CONFIG_CLIENT = sts .assume_role (acct , sts .CONFIGURATION_ROLE , "config" , region )
1182+ config_rule_search = config .find_config_rule (rule_name )
1183+ if config_rule_search [0 ] is True :
1184+ if DRY_RUN is False :
1185+ LOGGER .info (f"Deleting { rule_name } config rule for account { acct } in { region } " )
1186+ config .delete_config_rule (rule_name )
1187+ LIVE_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _Delete" ] = f"Deleted { rule_name } custom config rule"
1188+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
1189+ CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] -= 1
1190+ remove_state_table_record (config_rule_search [1 ]["ConfigRules" ][0 ]["ConfigRuleArn" ])
1191+ else :
1192+ LOGGER .info (f"DRY_RUN: Deleting { rule_name } config rule for account { acct } in { region } " )
1193+ DRY_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _Delete" ] = f"DRY_RUN: Delete { rule_name } custom config rule"
1194+ else :
1195+ LOGGER .info (f"{ rule_name } config rule for account { acct } in { region } does not exist." )
1196+
1197+ # Delete lambda for custom config rule
1198+ lambdas .LAMBDA_CLIENT = sts .assume_role (acct , sts .CONFIGURATION_ROLE , "lambda" , region )
1199+ lambda_search = lambdas .find_lambda_function (rule_name )
1200+ # TODO(liamschn): this will be a mypy error - need to have lambda_search return string, not None
1201+ if lambda_search is not None :
1202+ if DRY_RUN is False :
1203+ LOGGER .info (f"Deleting { rule_name } lambda function for account { acct } in { region } " )
1204+ lambdas .delete_lambda_function (rule_name )
1205+ LIVE_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _Delete" ] = f"Deleted { rule_name } lambda function"
1206+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
1207+ CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] -= 1
1208+ remove_state_table_record (lambda_search ["Configuration" ]["FunctionArn" ])
1209+ else :
1210+ LOGGER .info (f"DRY_RUN: Deleting { rule_name } lambda function for account { acct } in { region } " )
1211+ DRY_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _Delete" ] = f"DRY_RUN: Delete { rule_name } lambda function"
1212+ else :
1213+ LOGGER .info (f"{ rule_name } lambda function for account { acct } in { region } does not exist." )
1214+
1215+ def delete_custom_config_iam_role (rule_name : str , acct : str ):
1216+ global DRY_RUN_DATA
1217+ global LIVE_RUN_DATA
1218+ global CFN_RESPONSE_DATA
1219+
1220+ region = iam .get_iam_global_region ()
1221+ # Detach IAM policies
1222+ iam .IAM_CLIENT = sts .assume_role (acct , sts .CONFIGURATION_ROLE , "iam" , region )
1223+ attached_policies = iam .list_attached_iam_policies (rule_name )
1224+ if attached_policies is not None :
1225+ for policy in attached_policies :
1226+ if DRY_RUN is False :
1227+ LOGGER .info (f"Detaching { policy ['PolicyName' ]} IAM policy from account { acct } in { region } " )
1228+ iam .detach_policy (rule_name , policy ["PolicyArn" ])
1229+ LIVE_RUN_DATA [
1230+ f"{ rule_name } _{ acct } _{ region } _PolicyDetach"
1231+ ] = f"Detached { policy ['PolicyName' ]} IAM policy from account { acct } in { region } "
1232+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
1233+ else :
1234+ LOGGER .info (f"DRY_RUN: Detach { policy ['PolicyName' ]} IAM policy from account { acct } in { region } " )
1235+ DRY_RUN_DATA [
1236+ f"{ rule_name } _{ acct } _{ region } _Delete"
1237+ ] = f"DRY_RUN: Detach { policy ['PolicyName' ]} IAM policy from account { acct } in { region } "
1238+ else :
1239+ LOGGER .info (f"No IAM policies attached to { rule_name } for account { acct } in { region } " )
1240+
1241+ # Delete IAM policy
1242+ policy_arn = f"arn:{ sts .PARTITION } :iam::{ acct } :policy/{ rule_name } -lamdba-basic-execution"
1243+ LOGGER .info (f"Policy ARN: { policy_arn } " )
1244+ policy_search = iam .check_iam_policy_exists (policy_arn )
1245+ if policy_search is True :
1246+ if DRY_RUN is False :
1247+ LOGGER .info (f"Deleting { rule_name } -lamdba-basic-execution IAM policy for account { acct } in { region } " )
1248+ iam .delete_policy (policy_arn )
1249+ LIVE_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _Delete" ] = f"Deleted { rule_name } IAM policy"
1250+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
1251+ CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] -= 1
1252+ remove_state_table_record (policy_arn )
1253+ else :
1254+ LOGGER .info (f"DRY_RUN: Delete { rule_name } -lamdba-basic-execution IAM policy for account { acct } in { region } " )
1255+ DRY_RUN_DATA [
1256+ f"{ rule_name } _{ acct } _{ region } _PolicyDelete"
1257+ ] = f"DRY_RUN: Delete { rule_name } -lamdba-basic-execution IAM policy for account { acct } in { region } "
1258+ else :
1259+ LOGGER .info (f"{ rule_name } -lamdba-basic-execution IAM policy for account { acct } in { region } does not exist." )
1260+
1261+ policy_arn2 = f"arn:{ sts .PARTITION } :iam::{ acct } :policy/{ rule_name } "
1262+ LOGGER .info (f"Policy ARN: { policy_arn2 } " )
1263+ policy_search = iam .check_iam_policy_exists (policy_arn2 )
1264+ if policy_search is True :
1265+ if DRY_RUN is False :
1266+ LOGGER .info (f"Deleting { rule_name } IAM policy for account { acct } in { region } " )
1267+ iam .delete_policy (policy_arn2 )
1268+ LIVE_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _Delete" ] = f"Deleted { rule_name } IAM policy"
1269+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
1270+ CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] -= 1
1271+ remove_state_table_record (policy_arn2 )
1272+ else :
1273+ LOGGER .info (f"DRY_RUN: Delete { rule_name } IAM policy for account { acct } in { region } " )
1274+ DRY_RUN_DATA [
1275+ f"{ rule_name } _{ acct } _{ region } _PolicyDelete"
1276+ ] = f"DRY_RUN: Delete { rule_name } IAM policy for account { acct } in { region } "
1277+ else :
1278+ LOGGER .info (f"{ rule_name } IAM policy for account { acct } in { region } does not exist." )
1279+
1280+ # Delete IAM execution role for custom config rule lambda
1281+ role_search = iam .check_iam_role_exists (rule_name )
1282+ if role_search [0 ] is True :
1283+ if DRY_RUN is False :
1284+ LOGGER .info (f"Deleting { rule_name } IAM role for account { acct } in { region } " )
1285+ iam .delete_role (rule_name )
1286+ LIVE_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _Delete" ] = f"Deleted { rule_name } IAM role"
1287+ CFN_RESPONSE_DATA ["deployment_info" ]["action_count" ] += 1
1288+ CFN_RESPONSE_DATA ["deployment_info" ]["resources_deployed" ] -= 1
1289+ remove_state_table_record (role_search [1 ])
1290+ else :
1291+ LOGGER .info (f"DRY_RUN: Delete { rule_name } IAM role for account { acct } in { region } " )
1292+ DRY_RUN_DATA [f"{ rule_name } _{ acct } _{ region } _RoleDelete" ] = f"DRY_RUN: Delete { rule_name } IAM role for account { acct } in { region } "
1293+ else :
1294+ LOGGER .info (f"{ rule_name } IAM role for account { acct } in { region } does not exist." )
1295+
11761296
11771297def delete_event (event , context ):
11781298 # TODO(liamschn): handle delete error if IAM policy is updated out-of-band - botocore.errorfactory.DeleteConflictException: An error occurred (DeleteConflict) when calling the DeletePolicy operation: This policy has more than one version. Before you delete a policy, you must delete the policy's versions. The default version is deleted with the policy.
1299+ # TODO(liamschn): move re-used delete event operation code to separate functions
11791300 global DRY_RUN_DATA
11801301 global LIVE_RUN_DATA
11811302 global CFN_RESPONSE_DATA
0 commit comments