Checkov CKV2_AWS_4规则校验失败排查:API Gateway配置问题
问题:Checkov CKV2_AWS_4规则检测失败排查
问题背景
使用Terraform定义AWS API Gateway资源,通过Checkov检测Terraform计划输出时,始终触发CKV2_AWS_4规则("确保API Gateway阶段配置了合适的日志级别")失败。即使替换为官方示例配置,问题依然存在。
触发失败的Checkov规则定义
metadata: id: "CKV2_AWS_4" name: "Ensure API Gateway stage have logging level defined as appropriate" category: "LOGGING" definition: and: - resource_types: - aws_api_gateway_stage connected_resource_types: - aws_api_gateway_method_settings operator: exists cond_type: connection - or: - cond_type: "attribute" resource_types: - "aws_api_gateway_method_settings" attribute: "settings.logging_level" operator: "equals" value: "ERROR" - cond_type: "attribute" resource_types: - "aws_api_gateway_method_settings" attribute: "settings.logging_level" operator: "equals" value: "INFO" - cond_type: "attribute" resource_types: - "aws_api_gateway_method_settings" attribute: "settings.metrics_enabled" operator: "equals" value: true - cond_type: filter attribute: resource_type value: - aws_api_gateway_stage operator: within
所用Terraform代码
data "aws_caller_identity" "current" {} locals { # 目标账号ID account_id = data.aws_caller_identity.current.account_id # 后缀,通常为development/nonproduction/production/feature/{name} name_suffix = terraform.workspace } resource "aws_api_gateway_rest_api" "example" { body = jsonencode({ openapi = "3.0.1" info = { title = "example" version = "1.0" } paths = { "/path1" = { get = { x-amazon-apigateway-integration = { httpMethod = "GET" payloadFormatVersion = "1.0" type = "HTTP_PROXY" uri = "https://ip-ranges.amazonaws.com/ip-ranges.json" } } } } }) name = "example" } resource "aws_api_gateway_deployment" "example" { rest_api_id = aws_api_gateway_rest_api.example.id triggers = { redeployment = sha1(jsonencode(aws_api_gateway_rest_api.example.body)) } lifecycle { create_before_destroy = true } } resource "aws_api_gateway_stage" "example" { deployment_id = "${aws_api_gateway_deployment.example.id}" rest_api_id = "${aws_api_gateway_rest_api.example.id}" stage_name = "example" cache_cluster_enabled = true cache_cluster_size = 6.1 xray_tracing_enabled = true access_log_settings { destination_arn = aws_cloudwatch_log_group.transfer_apigw_log_group.arn format = "$context.identity.sourceIp,$context.identity.caller,$context.identity.user,$context.requestTime,$context.httpMethod,$context.resourcePath,$context.protocol,$context.status,$context.responseLength,$context.requestId,$context.extendedRequestId" } } resource "aws_api_gateway_method_settings" "all" { rest_api_id = "${aws_api_gateway_rest_api.example.id}" stage_name = "${aws_api_gateway_stage.example.stage_name}" method_path = "*/*" settings { metrics_enabled = true logging_level = "ERROR" caching_enabled = true } } resource "aws_api_gateway_method_settings" "path_specific" { rest_api_id = aws_api_gateway_rest_api.example.id stage_name = aws_api_gateway_stage.example.stage_name method_path = "path1/GET" settings { metrics_enabled = true logging_level = "INFO" caching_enabled = true } } resource "aws_cloudwatch_log_group" "transfer_apigw_log_group" { name = "transfer_apigw_log_group-${var.region}-${local.name_suffix}" retention_in_days = 30 kms_key_id = "alias/aws/apigateway" }
Terraform计划输出(Checkov读取内容片段)
{ "format_version": "1.1", "terraform_version": "1.2.7", "planned_values": { "root_module": { "child_modules": [ { "resources": [ { "address": "module.api_gateway_uk.aws_api_gateway_deployment.example", "mode": "managed", "type": "aws_api_gateway_deployment", "name": "example", "provider_name": "registry.terraform.io/hashicorp/aws", "schema_version": 0, "values": { "description": null, "stage_description": null, "stage_name": null, "triggers": { "redeployment": "145be397ea51cabb14595b0f0ace006017953f0a" }, "variables": null }, "sensitive_values": { "triggers": {} } }, { "address": "module.api_gateway_uk.aws_api_gateway_method_settings.all", "mode": "managed", "type": "aws_api_gateway_method_settings", "name": "all", "provider_name": "registry.terraform.io/hashicorp/aws", "schema_version": 0, "values": { "method_path": "*/*", "settings": [ { "caching_enabled": true, "logging_level": "ERROR", "metrics_enabled": true, "throttling_burst_limit": -1, "throttling_rate_limit": -1 } ], "stage_name": "example" }, "sensitive_values": { "settings": [ {} ] } }, { "address": "module.api_gateway_uk.aws_api_gateway_method_settings.path_specific", "mode": "managed", "type": "aws_api_gateway_method_settings", "name": "path_specific", "provider_name": "registry.terraform.io/hashicorp/aws", "schema_version": 0, "values": { "method_path": "path1/GET", "settings": [ { "caching_enabled": true, "logging_level": "INFO", "metrics_enabled": true, "throttling_burst_limit": -1, "throttling_rate_limit": -1 } ], "stage_name": "example" }, "sensitive_values": { "settings": [ {} ] } }, { "address": "module.api_gateway_uk.aws_api_gateway_rest_api.example", "mode": "managed", "type": "aws_api_gateway_rest_api", "name": "example", "provider_name": "registry.terraform.io/hashicorp/aws", "schema_version": 0, "values": { "body": "{\"info\":{\"title\":\"example\",\"version\":\"1.0\"},\"openapi\":\"3.0.1\",\"paths\":{\"/path1\":{\"get\":{\"x-amazon-apigateway-integration\":{\"httpMethod\":\"GET\",\"payloadFormatVersion\":\"1.0\",\"type\":\"HTTP_PROXY\",\"uri\":\"https://ip-ranges.amazonaws.com/ip-ranges.json\"}}}}}", "minimum_compression_size": -1, "name": "example", "parameters": null, "put_rest_api_mode": null, "tags": null }, "sensitive_values": { "binary_media_types": [], "endpoint_configuration": [], "tags_all": {} } }, { "address": "module.api_gateway_uk.aws_api_gateway_stage.example", "mode": "managed", "type": "aws_api_gateway_stage", "name": "example", "provider_name": "registry.terraform.io/hashicorp/aws", "schema_version": 0, "values": { "access_log_settings": [ { "format": "$context.identity.sourceIp,$context.identity.caller,$context.identity.user,$context.requestTime,$context.httpMethod,$context.resourcePath,$context.protocol,$context.status,$context.responseLength,$context.requestId,$context.extendedRequestId" } ], "cache_cluster_enabled": true, "cache_cluster_size": "6.1", "canary_settings": [], "client_certificate_id": null, "description": null, "documentation_version": null, "stage_name": "example", "tags": null, "variables": null, "xray_tracing_enabled": true }, "sensitive_values": { "access_log_settings": [ {} ], "canary_settings": [], "tags_all": {} } }, { "address": "module.api_gateway_uk.aws_cloudwatch_log_group.transfer_apigw_log_group", "mode": "managed", "type": "aws_cloudwatch_log_group", "name": "transfer_apigw_log_group", "provider_name": "registry.terraform.io/hashicorp/aws", "schema_version": 0, "values": { "kms_key_id": "alias/aws/apigateway", "name": "transfer_apigw_log_group-uk-default", "retention_in_days": 30, "skip_destroy": false, "tags": null }, "sensitive_values": { "tags_all": {} } } ], "address": "module.api_gateway_uk" } <SNIP> }
排查结论
CKV2_AWS_4规则要求所有and条件同时满足,逐一核对后发现问题出在第一个条件:
- 条件1:aws_api_gateway_stage必须关联aws_api_gateway_method_settings
Checkov通过rest_api_id+stage_name的组合识别两者的关联,但你的Terraform计划输出中,aws_api_gateway_method_settings资源缺失rest_api_id字段,导致Checkov无法确认两者属于同一个API网关实例,因此判定该条件不满足。
其余条件均符合要求:
- 条件2:两个method_settings的
logging_level分别为ERROR和INFO,符合规则要求; - 条件3:两个method_settings的
metrics_enabled均为true,符合规则要求; - 条件4:目标资源类型为
aws_api_gateway_stage,符合过滤要求。
修复建议
- 确保Terraform代码中
aws_api_gateway_method_settings的rest_api_id直接引用资源属性(而非字符串插值),避免Terraform在计划输出中省略该字段; - 升级Checkov版本:旧版本可能存在资源关联识别的bug,新版本大概率已修复;
- 升级Terraform到较新的稳定版本,确保计划输出完整包含所有资源属性。
内容的提问来源于stack exchange,提问作者jon
相关产品推荐
相关产品推荐

