Logging Should Be Enabled CodeBuild Project Environment
More Info:
This rule ensures that logging is enabled for the environment of an AWS CodeBuild project by checking if at least one log option is enabled. Logging provides valuable insights into build execution, errors, and debugging information. Failing to enable logging can hinder troubleshooting efforts and impact the visibility of build activities.
Risk Level
Medium
Address
Security
Compliance Standards
- APRA CPS 234 (Australia)
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS Critical Security Controls v8
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- Cloudanix Best Practice
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- Reserve Bank of India (RBI) Cyber Security Framework
- Reserve Bank of India (RBI) Master Direction – Information Technology Framework
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- Securities and Exchange Board of India (SEBI) - Cloud Security Adoption Framework
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Using Console
To remediate “Logging should be enabled for CodeBuild project environment” using the AWS Management Console:
-
Sign in and open CodeBuild
- Go to AWS Management Console → search for CodeBuild → open AWS CodeBuild.
-
Select the project
- In the left pane, click Build projects.
- Click the name of the project you want to fix.
-
Edit the project
- On the project details page, click Edit (top right).
- Scroll down to the Logs or Build logs section.
-
Enable CloudWatch Logs
- Under CloudWatch logs, select Enabled.
- Choose a Log group:
- Either pick an existing CloudWatch Log group, or
- Click the option to Create new and give it a name (e.g.,
/aws/codebuild/<project-name>).
- (Optional but recommended) Set a stream name format or accept the default.
-
Enable S3 Logs (optional but recommended)
- Under S3 logs, select Enabled.
- Choose or create an S3 bucket to store logs.
- (Optional) Specify a bucket prefix (e.g.,
codebuild-logs/<project-name>/).
-
Verify service role permissions
- Note the Service role listed in the project configuration (e.g.,
codebuild-<project-name>-service-role). - In a new tab, go to IAM → Roles → open that role.
- Confirm it has permissions like:
- For CloudWatch Logs:
logs:CreateLogGrouplogs:CreateLogStreamlogs:PutLogEvents
- For S3 logs:
s3:PutObject(for the chosen bucket/prefix)
- For CloudWatch Logs:
- If missing, attach or update a policy to include these actions for the relevant Log Group and S3 bucket.
- Note the Service role listed in the project configuration (e.g.,
-
Save the project
- Go back to the Edit build project page.
- Scroll to the bottom and click Update build project (or Save).
-
Validate logging
- Start a new build for that project.
- Go to:
- CloudWatch → Logs → Log groups → open your log group → verify build logs appear.
- S3 → your log bucket → verify log files are being created (if S3 logs enabled).
Once these steps are done, the “logging should be enabled” finding for that CodeBuild project should be remediated.
Using CLI
Below are concise, step-by-step AWS CLI instructions to enable logging for an existing AWS CodeBuild project.
Assumptions:
- You already have a CodeBuild project named
MY-CODEBUILD-PROJECT. - You want to enable CloudWatch Logs (and optionally S3 logs).
1. Get the current project configuration
You need the full current config so you can pass it back into update-project (CodeBuild requires most fields, not just logs).
aws codebuild batch-get-projects \
--names MY-CODEBUILD-PROJECT \
> project.json
Inspect project.json and locate the entry under "projects" → first object. That is the full project definition.
2. (Optional but recommended) Create a CloudWatch Logs log group
Pick a log group name, e.g. /codebuild/MY-CODEBUILD-PROJECT:
aws logs create-log-group \
--log-group-name /codebuild/MY-CODEBUILD-PROJECT
If it already exists, you can ignore any “resource already exists” error.
3. (Optional) Create an S3 bucket for logs
If you also want S3 logs, create / choose a bucket, e.g. my-codebuild-logs-bucket:
aws s3 mb s3://my-codebuild-logs-bucket
4. Build the logsConfig JSON
You will use --logs-config in update-project.
4.1 Example: Enable only CloudWatch Logs
cat > logs-config.json << 'EOF'
{
"cloudWatchLogs": {
"status": "ENABLED",
"groupName": "/codebuild/MY-CODEBUILD-PROJECT",
"streamName": "build-log"
},
"s3Logs": {
"status": "DISABLED"
}
}
EOF
4.2 Example: Enable both CloudWatch Logs and S3 logs
cat > logs-config.json << 'EOF'
{
"cloudWatchLogs": {
"status": "ENABLED",
"groupName": "/codebuild/MY-CODEBUILD-PROJECT",
"streamName": "build-log"
},
"s3Logs": {
"status": "ENABLED",
"location": "my-codebuild-logs-bucket/logs/",
"encryptionDisabled": false
}
}
EOF
5. Extract required fields from the existing project
From project.json, extract each of the following values from the project object:
namedescription(if present)sourceartifactsenvironmentserviceRoletimeoutInMinutes(if present)queuedTimeoutInMinutes(if present)encryptionKey(if present)tags(if present)vpcConfig(if present)badgeEnabled(if present)buildTimeout,queuedTimeout(old fields) as applicable- Any other fields you see that are set (you should generally re-supply them).
You can also pull them programmatically with jq, but the safest is to reuse everything from that object.
Example using jq to extract common fields:
PROJECT_OBJ=$(jq '.projects[0]' project.json)
NAME=$(echo "$PROJECT_OBJ" | jq -r '.name')
DESCRIPTION=$(echo "$PROJECT_OBJ" | jq -r '.description // empty')
SOURCE=$(echo "$PROJECT_OBJ" | jq '.source')
ARTIFACTS=$(echo "$PROJECT_OBJ" | jq '.artifacts')
ENVIRONMENT=$(echo "$PROJECT_OBJ" | jq '.environment')
SERVICE_ROLE=$(echo "$PROJECT_OBJ" | jq -r '.serviceRole')
VPC_CONFIG=$(echo "$PROJECT_OBJ" | jq '.vpcConfig // empty')
TAGS=$(echo "$PROJECT_OBJ" | jq '.tags // empty')
TIMEOUT=$(echo "$PROJECT_OBJ" | jq '.timeoutInMinutes // empty')
QUEUED_TIMEOUT=$(echo "$PROJECT_OBJ" | jq '.queuedTimeoutInMinutes // empty')
ENCRYPTION_KEY=$(echo "$PROJECT_OBJ" | jq -r '.encryptionKey // empty')
6. Run update-project with the new logs config
Here is a generic example that includes the most common parameters and sets logsConfig from logs-config.json.
aws codebuild update-project \
--name "$NAME" \
--description "$DESCRIPTION" \
--source "$SOURCE" \
--artifacts "$ARTIFACTS" \
--environment "$ENVIRONMENT" \
--service-role "$SERVICE_ROLE" \
--timeout-in-minutes $TIMEOUT \
--queued-timeout-in-minutes $QUEUED_TIMEOUT \
--encryption-key "$ENCRYPTION_KEY" \
--logs-config file://logs-config.json \
$( [ "$VPC_CONFIG" != "null" ] && echo --vpc-config "$VPC_CONFIG" ) \
$( [ "$TAGS" != "null" ] && echo --tags "$TAGS" )
If you prefer to do it manually (without jq), just plug the JSON fragments directly, e.g.:
aws codebuild update-project \
--name MY-CODEBUILD-PROJECT \
--source '{
"type": "GITHUB",
"location": "https://github.com/my-org/my-repo",
"buildspec": "buildspec.yml"
}' \
--artifacts '{
"type": "NO_ARTIFACTS"
}' \
--environment '{
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:7.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": []
}' \
--service-role arn:aws:iam::123456789012:role/CodeBuildServiceRole \
--logs-config file://logs-config.json
Make sure all fields match your existing project values; only logsConfig should be changing.
7. Verify logging is enabled
aws codebuild batch-get-projects \
--names MY-CODEBUILD-PROJECT \
--query 'projects[0].logsConfig' \
--output json
You should see:
{
"cloudWatchLogs": {
"status": "ENABLED",
"groupName": "/codebuild/MY-CODEBUILD-PROJECT",
"streamName": "build-log"
},
"s3Logs": {
"status": "DISABLED"
}
}
(or your S3 configuration if you enabled it).
If you share your current project.json (redacted), I can give you an exact aws codebuild update-project command for your environment.
Using Python
To remediate “Logging should be enabled for CodeBuild project environment” with Python, you need to:
- Identify the project(s)
- Enable at least one logging destination (CloudWatch Logs or S3) in
logsConfig - Update the CodeBuild project via
boto3
Below is a minimal, end‑to‑end example.
1. Prerequisites
boto3installed:pip install boto3- AWS credentials configured (env vars,
~/.aws/credentials, or an attached IAM role). - IAM permissions for:
codebuild:BatchGetProjectscodebuild:UpdateProjectlogs:CreateLogGroup(if you need to create the group)logs:DescribeLogGroups
2. Decide logging configuration
Example: enable CloudWatch Logs for a project:
- Log group name:
/aws/codebuild/my-project-logs - Stream name:
codebuild-log-stream
You can also enable S3 logs similarly.
3. Python script to enable CloudWatch Logs
import boto3
from botocore.exceptions import ClientError
codebuild = boto3.client("codebuild")
logs = boto3.client("logs")
def ensure_log_group(log_group_name: str):
"""Create the CloudWatch log group if it does not exist."""
try:
logs.create_log_group(logGroupName=log_group_name)
print(f"Created log group: {log_group_name}")
except ClientError as e:
if e.response["Error"]["Code"] == "ResourceAlreadyExistsException":
pass # OK
else:
raise
def enable_logging_for_project(
project_name: str,
log_group_name: str,
stream_name: str = "codebuild",
):
# 1. Ensure log group exists
ensure_log_group(log_group_name)
# 2. Get current project definition
resp = codebuild.batch_get_projects(names=[project_name])
if not resp["projects"]:
raise ValueError(f"Project {project_name} not found")
project = resp["projects"][0]
# 3. Update logsConfig (keep other properties unchanged)
project_update_params = {
"name": project["name"],
"description": project.get("description"),
"source": project["source"],
"artifacts": project["artifacts"],
"environment": project["environment"],
"serviceRole": project["serviceRole"],
"timeoutInMinutes": project.get("timeoutInMinutes"),
"queuedTimeoutInMinutes": project.get("queuedTimeoutInMinutes"),
"cache": project.get("cache"),
"badgeEnabled": project.get("badgeEnabled"),
"vpcConfig": project.get("vpcConfig"),
"encryptionKey": project.get("encryptionKey"),
"fileSystemLocations": project.get("fileSystemLocations"),
"buildBatchConfig": project.get("buildBatchConfig"),
"concurrentBuildLimit": project.get("concurrentBuildLimit"),
"logsConfig": {
"cloudWatchLogs": {
"status": "ENABLED",
"groupName": log_group_name,
"streamName": stream_name,
},
# Optionally also enable S3 logs:
# "s3Logs": {
# "status": "ENABLED",
# "location": "my-log-bucket/my-folder",
# "encryptionDisabled": False,
# }
},
"secondarySources": project.get("secondarySources"),
"secondarySourceVersions": project.get("secondarySourceVersions"),
"secondaryArtifacts": project.get("secondaryArtifacts"),
"tags": project.get("tags"),
"sourceVersion": project.get("sourceVersion"),
"buildTimeoutInMinutes": project.get("buildTimeoutInMinutes"),
}
# Filter out None values (UpdateProject rejects some nulls)
project_update_params = {
k: v for k, v in project_update_params.items() if v is not None
}
# 4. Call update_project
codebuild.update_project(**project_update_params)
print(f"Enabled CloudWatch Logs for project: {project_name}")
if __name__ == "__main__":
PROJECT_NAME = "my-codebuild-project"
LOG_GROUP_NAME = "/aws/codebuild/my-codebuild-project"
enable_logging_for_project(
project_name=PROJECT_NAME,
log_group_name=LOG_GROUP_NAME,
stream_name="build-logs",
)
4. To enable S3 logging (optional or in addition)
Adjust the logsConfig block:
"logsConfig": {
"cloudWatchLogs": {
"status": "ENABLED",
"groupName": log_group_name,
"streamName": stream_name,
},
"s3Logs": {
"status": "ENABLED",
"location": "my-log-bucket/codebuild-logs",
"encryptionDisabled": False, # keep encryption enabled
},
},
Make sure the CodeBuild service role has permission to write to that S3 bucket.
This script can be run once per project (or loop over all projects) to remediate the “logging disabled” finding programmatically.
Using Terraform
resource "aws_codebuild_project" "this" {
name = "PROJECT_NAME" # replace with your CodeBuild project name
service_role = "CODEBUILD_SERVICE_ROLE_ARN" # replace with the IAM role ARN for this project
# ... other required configuration like source, environment, artifacts, etc.
logs_config {
cloudwatch_logs {
status = "ENABLED"
group_name = "/aws/codebuild/PROJECT_NAME" # replace with desired log group name
stream_name = "PROJECT_NAME" # replace with desired log stream name
}
# NOTE: This matches the CLI behavior and overwrites existing logs configuration.
# If you previously had S3 logs configured and want to keep them, add an s3_logs block here.
}
}
Changing only logs_config is an in-place update and does not force replacement of the CodeBuild project, but it will overwrite any existing logs configuration in the same way as the CLI command (including disabling S3 logs if you do not also configure s3_logs here).
To verify, terraform plan should show an update to aws_codebuild_project.this.logs_config.cloudwatch_logs with status changing to ENABLED (and group_name/stream_name set as specified), with no destroy/create replacement of the project resource.