From 158b92e6030b1775ec6c03812e4c1857dbe92570 Mon Sep 17 00:00:00 2001 From: Ed Tan <60517496+edtan-caseware@users.noreply.github.com> Date: Wed, 28 May 2025 14:34:02 -0400 Subject: [PATCH 1/3] AWS Inspector - update ECR rescan settings This fixes https://github.com/aws-samples/aws-security-reference-architecture-examples/issues/300. This updates the code so that it allows setting the ECR image pull and push settings separately. Additionally, it updates the code to allow setting the scan settings to the other available durations. --- .../inspector/inspector_org/lambda/src/app.py | 11 +++++++---- .../inspector_org/lambda/src/inspector.py | 15 +++++++++++---- .../sra-inspector-org-configuration.yaml | 16 +++++++++++++--- .../solutions/inspector/configuration/invoke.tf | 2 ++ .../solutions/inspector/configuration/main.tf | 1 + .../inspector/configuration/variables.tf | 8 +++++++- 6 files changed, 41 insertions(+), 12 deletions(-) diff --git a/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/app.py b/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/app.py index d12107af6..9e4cfc593 100644 --- a/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/app.py +++ b/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/app.py @@ -183,7 +183,8 @@ def get_validated_parameters(event: Dict[str, Any]) -> dict: pattern=r"(?i)^((ec2|ecr|lambda|lambda_code),?){0,3}(ec2|ecr|lambda|lambda_code){1}$", ) ) - params.update(parameter_pattern_validator("ECR_SCAN_DURATION", os.environ.get("ECR_SCAN_DURATION"), pattern=r"^(LIFETIME|DAYS_30|DAYS_180){1}$")) + params.update(parameter_pattern_validator("ECR_PULL_SCAN_DURATION", os.environ.get("ECR_PULL_SCAN_DURATION"), pattern=r"^(LIFETIME|DAYS_14|DAYS_30|DAYS_60|DAYS_90|DAYS_180){1}$")) + params.update(parameter_pattern_validator("ECR_SCAN_DURATION", os.environ.get("ECR_SCAN_DURATION"), pattern=r"^(LIFETIME|DAYS_14|DAYS_30|DAYS_60|DAYS_90|DAYS_180){1}$")) # Optional Parameters params.update( @@ -374,7 +375,8 @@ def setup_inspector_in_region( management_account: str, configuration_role_name: str, scan_components: list, - ecr_scan_duration: Literal["DAYS_180", "DAYS_30", "LIFETIME"], + ecr_pull_scan_duration: Literal["DAYS_14", "DAYS_30", "DAYS_60", "DAYS_90", "DAYS_180", "LIFETIME"], + ecr_scan_duration: Literal["DAYS_14", "DAYS_30", "DAYS_60", "DAYS_90", "DAYS_180", "LIFETIME"], ) -> None: """Regional setup process of the inspector feature. @@ -411,8 +413,8 @@ def setup_inspector_in_region( inspector.set_auto_enable_inspector_in_org(region, configuration_role_name, delegated_admin_account, scan_component_dict) - LOGGER.info(f"setup_inspector_in_region: ECR_SCAN_DURATION - {ecr_scan_duration}") - inspector.set_ecr_scan_duration(region, configuration_role_name, delegated_admin_account, ecr_scan_duration) + LOGGER.info(f"setup_inspector_in_region: ECR_PULL_SCAN_DURATION (on image pull) - {ecr_pull_scan_duration}, ECR_SCAN_DURATION (on image push) - {ecr_scan_duration}") + inspector.set_ecr_scan_duration(region, configuration_role_name, delegated_admin_account, ecr_pull_scan_duration, ecr_scan_duration) inspector.associate_inspector_member_accounts(configuration_role_name, delegated_admin_account, accounts, region) @@ -539,6 +541,7 @@ def process_event_sns(event: dict) -> None: params["MANAGEMENT_ACCOUNT_ID"], params["CONFIGURATION_ROLE_NAME"], scan_components, + params["ECR_PULL_SCAN_DURATION"], params["ECR_SCAN_DURATION"], ) diff --git a/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py b/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py index 3bd16520c..e4d396262 100644 --- a/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py +++ b/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py @@ -421,14 +421,18 @@ def enable_inspector2_in_member_accounts( def set_ecr_scan_duration( - region: str, configuration_role_name: str, delegated_admin_account_id: str, ecr_scan_duration: Literal["DAYS_180", "DAYS_30", "LIFETIME"] + region: str, configuration_role_name: str, + delegated_admin_account_id: str, + ecr_pull_scan_duration: Literal["DAYS_14", "DAYS_30", "DAYS_60", "DAYS_90", "DAYS_180", "LIFETIME"], + ecr_scan_duration: Literal["DAYS_14", "DAYS_30", "DAYS_60", "DAYS_90", "DAYS_180", "LIFETIME"] ) -> None: """Set the ECR scan duration in the delegated administrator account. Args: configuration_role_name: configuration role name delegated_admin_account_id: delegated admin account id - ecr_scan_duration: ecr scan duration + ecr_pull_scan_duration: ecr scan duration (on image pull) + ecr_scan_duration: ecr scan duration (on image push) region: AWS region Returns: @@ -439,13 +443,16 @@ def set_ecr_scan_duration( f"creating delegated admin session with ({configuration_role_name}) in account ({delegated_admin_account_id}) to set ecr scan duration" ) inspector_delegated_admin_region_client: Inspector2Client = delegated_admin_session.client("inspector2", region) - LOGGER.info(f"Setting ECR scan duration in delegated admin account to {ecr_scan_duration} in {region}") + LOGGER.info(f"In delegated admin account, setting ECR push scan duration to {ecr_scan_duration} and ECR pull scan duration to {ecr_pull_scan_duration} in {region}") LOGGER.info(f"delegated admin client region: {inspector_delegated_admin_region_client.meta.region_name}") LOGGER.info(f"Region: {delegated_admin_session.region_name}") sts_client = delegated_admin_session.client("sts", region_name=region) LOGGER.info(f"caller identity: {sts_client.get_caller_identity()}") configuration_response: dict = inspector_delegated_admin_region_client.update_configuration( - ecrConfiguration={"rescanDuration": ecr_scan_duration} + ecrConfiguration={ + "pullDateRescanDuration": ecr_pull_scan_duration + "rescanDuration": ecr_scan_duration + } ) api_call_details = {"API_Call": "inspector:UpdateConfiguration", "API_Response": configuration_response} LOGGER.info(api_call_details) diff --git a/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml b/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml index e6bd65335..7999b6137 100644 --- a/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml +++ b/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml @@ -35,6 +35,7 @@ Metadata: - pControlTowerRegionsOnly - pEnabledRegions - pScanComponents + - pEcrPullRescanDuration - pEcrRescanDuration - Label: @@ -89,8 +90,10 @@ Metadata: default: Inspector Configuration Role Name pScanComponents: default: Comma separated list of scan components (EC2, ECR, LAMBDA, LAMBDA_CODE) + pEcrPullRescanDuration: + default: ECR Rescan Duration on image pull pEcrRescanDuration: - default: ECR Rescan Duration + default: ECR Rescan Duration on image push Parameters: pComplianceFrequency: @@ -199,10 +202,15 @@ Parameters: Default: EC2, ECR, LAMBDA, LAMBDA_CODE Description: Lambda Function Logging Level Type: CommaDelimitedList + pEcrPullRescanDuration: + AllowedValues: [LIFETIME, DAYS_14, DAYS_30, DAYS_60, DAYS_90, DAYS_180] + Default: LIFETIME + Description: ECR Rescan Duration on image pull + Type: String pEcrRescanDuration: - AllowedValues: [LIFETIME, DAYS_30, DAYS_180] + AllowedValues: [LIFETIME, DAYS_14, DAYS_30, DAYS_60, DAYS_90, DAYS_180] Default: LIFETIME - Description: ECR Rescan Duration + Description: ECR Rescan Duration on image push Type: String Conditions: @@ -471,6 +479,7 @@ Resources: SCAN_COMPONENTS: !Join - ',' - !Ref pScanComponents + ECR_PULL_SCAN_DURATION: !Ref pEcrPullRescanDuration ECR_SCAN_DURATION: !Ref pEcrRescanDuration Tags: - Key: sra-solution @@ -497,6 +506,7 @@ Resources: SCAN_COMPONENTS: !Join - ',' - !Ref pScanComponents + ECR_PULL_SCAN_DURATION: !Ref pEcrPullRescanDuration ECR_SCAN_DURATION: !Ref pEcrRescanDuration rInspectorOrgTopic: diff --git a/aws_sra_examples/terraform/solutions/inspector/configuration/invoke.tf b/aws_sra_examples/terraform/solutions/inspector/configuration/invoke.tf index 4f889c129..4b0a2b25f 100644 --- a/aws_sra_examples/terraform/solutions/inspector/configuration/invoke.tf +++ b/aws_sra_examples/terraform/solutions/inspector/configuration/invoke.tf @@ -20,6 +20,7 @@ resource "aws_lambda_invocation" "lambda_invoke" { "MANAGEMENT_ACCOUNT_ID" : "${local.current_account}", "SNS_TOPIC_ARN" : "${aws_sns_topic.inspector_org_topic.arn}", "SCAN_COMPONENTS" : "${var.scan_components}", + "ECR_PULL_SCAN_DURATION" : "${var.ecr_pull_rescan_duration}", "ECR_SCAN_DURATION" : "${var.ecr_rescan_duration}", } }) @@ -45,6 +46,7 @@ resource "aws_lambda_invocation" "lambda_disable_invoke" { "MANAGEMENT_ACCOUNT_ID" : "${local.current_account}", "SNS_TOPIC_ARN" : "${aws_sns_topic.inspector_org_topic.arn}", "SCAN_COMPONENTS" : "${var.scan_components}", + "ECR_SCAN_DURATION" : "${var.ecr_pull_rescan_duration}", "ECR_SCAN_DURATION" : "${var.ecr_rescan_duration}", } }) diff --git a/aws_sra_examples/terraform/solutions/inspector/configuration/main.tf b/aws_sra_examples/terraform/solutions/inspector/configuration/main.tf index 2fcbecbf9..d62c79c34 100644 --- a/aws_sra_examples/terraform/solutions/inspector/configuration/main.tf +++ b/aws_sra_examples/terraform/solutions/inspector/configuration/main.tf @@ -395,6 +395,7 @@ resource "aws_lambda_function" "inspector_org_lambda_function" { MANAGEMENT_ACCOUNT_ID = local.current_account SNS_TOPIC_ARN = aws_sns_topic.inspector_org_topic.arn SCAN_COMPONENTS = var.scan_components + ECR_PULL_SCAN_DURATION = var.ecr_pull_rescan_duration ECR_SCAN_DURATION = var.ecr_rescan_duration } } diff --git a/aws_sra_examples/terraform/solutions/inspector/configuration/variables.tf b/aws_sra_examples/terraform/solutions/inspector/configuration/variables.tf index c2466e38c..a52131b9c 100644 --- a/aws_sra_examples/terraform/solutions/inspector/configuration/variables.tf +++ b/aws_sra_examples/terraform/solutions/inspector/configuration/variables.tf @@ -57,8 +57,14 @@ variable "inspector_configuration_role_name" { type = string } +variable "ecr_pull_rescan_duration" { + description = "ECR Rescan Duration on image pull" + type = string + default = "LIFETIME" +} + variable "ecr_rescan_duration" { - description = "ECR Rescan Duration" + description = "ECR Rescan Duration on image push" type = string default = "LIFETIME" } From ace2d795f97d85297280f2f6bb165984368a9b63 Mon Sep 17 00:00:00 2001 From: Ed Tan <60517496+edtan-caseware@users.noreply.github.com> Date: Mon, 2 Jun 2025 10:06:30 -0400 Subject: [PATCH 2/3] add missing comma --- .../solutions/inspector/inspector_org/lambda/src/inspector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py b/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py index e4d396262..c45c6c674 100644 --- a/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py +++ b/aws_sra_examples/solutions/inspector/inspector_org/lambda/src/inspector.py @@ -450,7 +450,7 @@ def set_ecr_scan_duration( LOGGER.info(f"caller identity: {sts_client.get_caller_identity()}") configuration_response: dict = inspector_delegated_admin_region_client.update_configuration( ecrConfiguration={ - "pullDateRescanDuration": ecr_pull_scan_duration + "pullDateRescanDuration": ecr_pull_scan_duration, "rescanDuration": ecr_scan_duration } ) From 649447e957b366601e73ae6e90870e15b0b8d8b5 Mon Sep 17 00:00:00 2001 From: Ed Tan <60517496+edtan-caseware@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:51:07 -0400 Subject: [PATCH 3/3] Also document requirement for newer boto3 version --- .../templates/sra-inspector-org-configuration.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml b/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml index 7999b6137..7afa8b224 100644 --- a/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml +++ b/aws_sra_examples/solutions/inspector/inspector_org/templates/sra-inspector-org-configuration.yaml @@ -491,7 +491,7 @@ Resources: Content: S3Bucket: !Ref pSRAStagingS3BucketName S3Key: !Sub ${pSRASolutionName}/layer_code/${pSRASolutionName}-layer.zip - Description: Boto3 version 1.26.24 layer to enable newer API of inspector2 + Description: Boto3 version 1.38.27 layer to enable newer API of inspector2 with pullDateRescanDuration parameter LayerName: !Sub ${pInspectorOrgLambdaFunctionName}-updated-boto3-layer rInspectorOrgLambdaCustomResource: