> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Codebuild project logging enabled remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate “Logging should be enabled for CodeBuild project environment” using the AWS Management Console:

        1. **Sign in and open CodeBuild**
           * Go to **AWS Management Console** → search for **CodeBuild** → open **AWS CodeBuild**.

        2. **Select the project**
           * In the left pane, click **Build projects**.
           * Click the **name** of the project you want to fix.

        3. **Edit the project**
           * On the project details page, click **Edit** (top right).
           * Scroll down to the **Logs** or **Build logs** section.

        4. **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.

        5. **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>/`).

        6. **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:CreateLogGroup`
               * `logs:CreateLogStream`
               * `logs:PutLogEvents`
             * For S3 logs:
               * `s3:PutObject` (for the chosen bucket/prefix)
           * If missing, attach or update a policy to include these actions for the relevant Log Group and S3 bucket.

        7. **Save the project**
           * Go back to the **Edit build project** page.
           * Scroll to the bottom and click **Update build project** (or **Save**).

        8. **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.
      </Accordion>

      <Accordion title="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).

        ```bash theme={null}
        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`:

        ```bash theme={null}
        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`:

        ```bash theme={null}
        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

        ```bash theme={null}
        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

        ```bash theme={null}
        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:

        * `name`
        * `description` (if present)
        * `source`
        * `artifacts`
        * `environment`
        * `serviceRole`
        * `timeoutInMinutes` (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:

        ```bash theme={null}
        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`.

        ```bash theme={null}
        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.:

        ```bash theme={null}
        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

        ```bash theme={null}
        aws codebuild batch-get-projects \
          --names MY-CODEBUILD-PROJECT \
          --query 'projects[0].logsConfig' \
          --output json
        ```

        You should see:

        ```json theme={null}
        {
          "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.
      </Accordion>

      <Accordion title="Using Python">
        To remediate “Logging should be enabled for CodeBuild project environment” with Python, you need to:

        1. Identify the project(s)
        2. Enable at least one logging destination (CloudWatch Logs or S3) in `logsConfig`
        3. Update the CodeBuild project via `boto3`

        Below is a minimal, end‑to‑end example.

        ***

        ### 1. Prerequisites

        * `boto3` installed:
          ```bash theme={null}
          pip install boto3
          ```
        * AWS credentials configured (env vars, `~/.aws/credentials`, or an attached IAM role).
        * IAM permissions for:
          * `codebuild:BatchGetProjects`
          * `codebuild:UpdateProject`
          * `logs: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

        ```python theme={null}
        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:

        ```python theme={null}
        "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.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        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.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
