Skip to content

[ERROR] KeyError: 'AwsEc2Instance' in lambda function, which works in different account.

0

I am managing 2 AWS accounts. I have a lambda function that I am using to query AWS Security Hub Findings, securityhub.get_findings. I am trying to reuse this lambda function that is working in account A, in account B. After creating the lambda function in account B, I am seeing the following error when testing:

LAMBDA_WARNING: Unhandled exception. The most likely cause is an issue in the function code. However, in rare cases, a Lambda runtime update can cause unexpected function behavior. For functions using managed runtimes, runtime updates can be triggered by a function change, or can be applied automatically. To determine if the runtime has been updated, check the runtime version in the INIT_START log entry. If this error correlates with a change in the runtime version, you may be able to mitigate this error by temporarily rolling back to the previous runtime version. For more information, see https://docs.aws.amazon.com/lambda/latest/dg/runtimes-update.html [ERROR] KeyError: 'AwsEc2Instance' Traceback (most recent call last):   File "/var/task/lambda_function.py", line 23, in lambda_handler     message = "\n".join([f"{f['Resources'][0]['Details']['AwsEc2Instance']['KeyName']}: {f['Severity']['Label']} \n{f['Title']}: {f['Description']}" "\n" for f in findings])   File "/var/task/lambda_function.py", line 23, in <listcomp>     message = "\n".join([f"{f['Resources'][0]['Details']['AwsEc2Instance']['KeyName']}: {f['Severity']['Label']} \n{f['Title']}: {f['Description']}" "\n" for f in findings]) END RequestId: b0cf9ea1-642c-4ac0-b070-a0b7a1ead147 REPORT RequestId: b0cf9ea1-642c-4ac0-b070-a0b7a1ead147 Duration: 516.59 ms Billed Duration: 517 ms Memory Size: 128 MB Max Memory Used: 80 MB Init Duration: 419.75 ms

It failing here:

    message = "\n".join([f"{f['Resources'][0]['Details']['AwsEc2Instance']['KeyName']}: {f['Severity']['Label']} \n{f['Title']}: {f['Description']}" "\n" for f in findings])

But as noted, this works perfectly fine in account A.

As part of the debug logging, I added a print(findings) to see response used in message and I can see this in the log: , 'LastObservedAt': '2025-02-08T17:14:53.268Z', 'CreatedAt': '2024-11-11T16:42:42.410Z', 'UpdatedAt': '2025-02-08T17:15:01.641Z', 'Severity': {'Product': 70, 'Label': 'HIGH', 'Normalized': 70, 'Original': 'HIGH'}, 'Title': 'Inspector.4 Amazon Inspector Lambda standard scanning should be enabled', 'Description': "This control checks whether Amazon Inspector Lambda standard scanning is enabled. For a standalone account, the control fails if Amazon Inspector Lambda standard scanning is disabled in the account. In a multi-account environment, the control fails if the delegated Inspector administrator account and all member accounts don't have Lambda standard scanning enabled.", 'Remediation': {'Recommendation': {'Text': 'For information on how to correct this issue, consult the AWS Security Hub controls documentation.', 'Url': 'https://docs.aws.amazon.com/console/securityhub/Inspector.4/remediation'}}, 'ProductFields': {'StandardsArn': 'arn:aws:securityhub:::standards/aws-foundational-security-best-practices/v/1.0.0', 'StandardsSubscriptionArn': 'arn:aws:securityhub:ap-southeast-3:############:subscription/aws-foundational-security-best-practices/v/1.0.0', 'ControlId': 'Inspector.4', 'RecommendationUrl': 'https://docs.aws.amazon.com/console/securityhub/Inspector.4/remediation', 'RelatedAWSResources:0/name': 'securityhub-inspector-lambda-standard-scan-enabled-c11b1759', 'RelatedAWSResources:0/type': 'AWS::Config::ConfigRule', 'StandardsControlArn': 'arn:aws:securityhub:ap-southeast-3:############:control/aws-foundational-security-best-practices/v/1.0.0/Inspector.4', 'aws/securityhub/ProductName': 'Security Hub', 'aws/securityhub/CompanyName': 'AWS', 'Resources:0/Id': 'arn:aws:iam::############:root', 'aws/securityhub/FindingId': 'arn:aws:securityhub:ap-southeast-3::product/aws/securityhub/arn:aws:securityhub:ap-southeast-3:############:subscription/aws-foundational-security-best-practices/v/1.0.0/Inspector.4/finding/44019834-328b-4fd7-874d-0bed8da2703e'}, 'Resources': [{'Type': 'AwsAccount', 'Id': 'AWS::::Account:############', 'Partition': 'aws', 'Region': 'ap-southeast-3'}], 'Compliance': {'Status': 'FAILED', 'SecurityControlId': 'Inspector.4', 'AssociatedStandards': [{'StandardsId': 'standards/aws-foundational-security-best-practices/v/1.0.0'}]}, 'WorkflowState': 'NEW', 'Workflow': {'Status': 'NEW'}, 'RecordState': 'ACTIVE', 'FindingProviderFields': {'Severity': {'Label': 'HIGH', 'Original': 'HIGH'}, 'Types': ['Software and Configuration Checks/Industry and Regulatory Standards/AWS-Foundational-Security-Best-Practices']}, 'ProcessedAt': '2025-02-08T17:15:24.757Z', 'AwsAccountName': 'REDACTED'}]

Can someone help me understand why I am seeing this different behavior when the "Resources" properties appear to be the same? is there an alternate solution in getting the the "KeyName" in Resources > Details > AwsEc2Instance?

1 Answer
1

The error you're encountering is due to a difference in the structure of the findings between your two accounts. In account A, where the function works, the findings likely contain EC2 instance-specific information. However, in account B, the findings don't seem to include the 'AwsEc2Instance' key in the 'Resources' section.

The error occurs because your code is trying to access 'AwsEc2Instance' and 'KeyName' for every finding, but not all findings have this information. In the sample data you provided, the 'Resources' section only contains an 'AwsAccount' type resource, not an 'AwsEc2Instance'.

To resolve this issue, you should modify your code to handle cases where 'AwsEc2Instance' or 'KeyName' might not be present. Here's a suggestion for a more robust approach:

  1. Check if the required keys exist before accessing them.
  2. Provide a default value or skip the finding if the required information is not available.

Here's an example of how you could modify your code:

message = "\n".join([
    f"{f['Resources'][0].get('Details', {}).get('AwsEc2Instance', {}).get('KeyName', 'N/A')}: {f['Severity']['Label']} \n{f['Title']}: {f['Description']}"
    for f in findings
    if f['Resources'] and 'Severity' in f and 'Title' in f and 'Description' in f
])

This modification will use 'N/A' if 'KeyName' or 'AwsEc2Instance' is not present, and it will skip findings that don't have the required fields.

Additionally, you might want to add more specific error handling and logging to better understand the structure of findings in account B. This will help you determine if there are other differences between the accounts that you need to account for in your code.

Remember that Security Hub findings can vary based on the enabled standards, rules, and the resources present in each account. Your lambda function should be flexible enough to handle these variations across different accounts.
Sources
lambda error when getting a trigger event from an S3 bucket in another account and reading the object | AWS re:Post
Lambda Runtime Error | AWS re:Post

answered a year ago

EXPERT

reviewed a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.