AWSAccountHierarchy
Determine AWS account hierarchy by looking up parent objects until the organization level is reached.
python · AWS Enrichment and Remediation
Source
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 from typing import Any import traceback """ STANDALONE FUNCTION """ def lookup(parent_obj: str, level: int, instance_to_use: str) -> tuple[str, dict]: """ Lookup information on a organization unit (ou) or root object. Unless the current lookup is a root object, it returns parent object to lookup and results of current lookup. Args: parent_obj (str): root/ou object in number format. level (int): the current level that the object is (ascending). instance_to_use (str): what integration instance to use. Returns: str: parent object to look up next or "NONE" for error handling and "stop" if no parent. dict: dictionary of id, name and level of the lookup object. """ temp: dict[str, str] = {} try: if "ou-" in parent_obj: ou_info = execute_command( "aws-org-organization-unit-get", {"organization_unit_id": parent_obj, "using": instance_to_use}, ) if not ou_info: return "NONE", temp temp["level"] = str(level) temp["id"] = ou_info.get("Id", "") temp["name"] = ou_info.get("Name", "") temp["arn"] = ou_info.get("Arn", "") ou_parent = execute_command( "aws-org-parent-list", {"child_id": parent_obj, "using": instance_to_use}, ) if not ou_parent: return "NONE", temp next_one = ou_parent[0].get("Id", "") elif "r-" in parent_obj: next_one = "stop" root_info = execute_command("aws-org-root-list", {"using": instance_to_use}) if not root_info: return "NONE", temp root = root_info.get("AWS.Organizations.Root(val.Id && val.Id == obj.Id)")[0] temp["level"] = str(level) temp["id"] = root.get("Id", "") temp["name"] = root.get("Name", "") temp["arn"] = root.get("Arn", "") else: raise ValueError("unexpected object type") except TypeError: return "NONE", temp else: return next_one, temp """ COMMAND FUNCTION """ def aws_account_heirarchy(args: dict[str, Any]) -> CommandResults: """ Determine AWS account hierarchy by looking up parent objects until the root level is reached. Args: args (dict): Command arguments from XSOAR. Returns: list[CommandResults]: outputs, readable outputs and raw response for XSOAR. """ account_id = args.get("account_id") if not account_id: raise ValueError("account_id not specified") # Using `demisto.executeCommand` instead of `execute_command` because for # multiple integration instances we can expect one too error out. account_info = demisto.executeCommand("aws-org-account-list", {"account_id": account_id}) account_returned = [account for account in account_info if (not isError(account) and account.get("Contents").get("Arn"))] if not account_returned: return CommandResults(readable_output="could not find specified account info") else: match_account = account_returned[0].get("Contents") instance_to_use = account_returned[0]["Metadata"]["instance"] level = 1 hierarchy = [ { "level": "account", "id": match_account.get("Id", ""), "name": match_account.get("Name", ""), "arn": match_account.get("Arn", ""), } ] account_parent = demisto.executeCommand("aws-org-parent-list", {"child_id": account_id, "using": instance_to_use}) if isError(account_parent): return CommandResults(readable_output="could not find specified account parent") next_one, to_append = lookup(account_parent[0].get("Contents", {})[0].get("Id", ""), level, instance_to_use) if next_one == "NONE": return CommandResults(readable_output="could not find specified ou/root info") hierarchy.append(to_append) try: while "stop" not in next_one: level += 1 next_one, to_append = lookup(next_one, level, instance_to_use) if next_one == "NONE" or next_one is None: return CommandResults(readable_output="could not find specified ou/root info") hierarchy.append(to_append) except TypeError: return CommandResults(readable_output="could not find specified ou/root info") return CommandResults( outputs_prefix="AWSHierarchy", outputs_key_field="level", outputs=hierarchy, ) """ MAIN FUNCTION """ def main(): try: return_results(aws_account_heirarchy(demisto.args())) except Exception as ex: demisto.error(traceback.format_exc()) # print the traceback return_error(f"Failed to execute AWSAccountHierarchy. Error: {str(ex)}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()
README
Determine AWS account hierarchy by looking up parent objects until the organization level is reached.
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Cortex XSOAR Version | 6.10.0 |
Dependencies
This script uses the following commands and scripts.
- aws-org-parent-list
- aws-org-organization-unit-get
- aws-org-root-list
- aws-org-account-list
Inputs
| Argument Name | Description |
|---|---|
| account_id | The unique identifier (ID) of the Amazon Web Services account that you want information about. |
Outputs
| Path | Description | Type |
|---|---|---|
| AWSHierarchy.id | ID of the account/OU/root object such as `111111111111`. | string |
| AWSHierarchy.level | Level in relation to the original AWS account such as account, 1, 2, etc. | string |
| AWSHierarchy.arn | ARN of the account/OU/root object such as `arn:aws:organizations::111111111111:root/o-2222222222/r-3333`. | string |
| AWSHierarchy.name | Human readable name of the account/OU/root object such as `aws-account-n`. | Unknown |