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

# Demo Basic Buildspec Usage

> Guide to AWS CodeBuild buildspec YAML covering structure, environment variable sources, artifacts and reports, testing integration, and caching strategies for production-ready CI builds

In the previous lesson we created a simple CI/CD pipeline connected to GitHub and implemented a basic deploy phase. This article digs into the CodeBuild buildspec YAML used in that pipeline and shows a complete, production-ready example. You’ll learn:

* The full buildspec structure and common patterns
* Environment variables from inline definitions, Systems Manager Parameter Store, and Secrets Manager
* How to publish primary and secondary artifacts
* Integrating test reports (report groups)
* Effective caching strategies to reduce build time

We’ll use the sample pipeline from the earlier demo (moving the sample app from v0.6.0 → v1.0.0) and inspect the CodeBuild project as our starting point.

![A screenshot of the AWS CodeBuild console showing the project "devops-020-100-build." The page displays configuration details (GitHub source, primary repository, artifacts location, service role) and a Build history panel.](https://mintcdn.com/kodekloud-c4ac6d9a/Kx09awxrzT0QVPGP/images/AWS-Certified-DevOps-Engineer-Professional/Domain-1-SDLC-Automation/Demo-Basic-Buildspec-Usage/aws-codebuild-devops-020-100-build-config.jpg?fit=max\&auto=format\&n=Kx09awxrzT0QVPGP\&q=85\&s=4886e19f9e734dce4ca6de254d32e761)

Complete example buildspec.yml (overview)

Read the example first for an overview. The sections after break down the key elements in detail.

```yaml theme={null}
# ABOUTME: Advanced CodeBuild buildspec for Demo 020-100 sample application.
# ABOUTME: Demonstrates all four phases, env var types, reports, artifacts, and caching.
version: 0.2

env:
  shell: bash
  variables:
    BUILD_ENVIRONMENT: "demo"
    PYTHONPATH: "./src"
    ENABLE_COVERAGE: "true"
  parameter-store:
    NOTIFICATION_TOPIC: "/devops-course/devops-020-100/notification-topic"
    BUILD_ENV_CONFIG: "/devops-course/devops-020-100/build-environment"
  secrets-manager:
    DOCKER_USERNAME: "devops-020-100/docker-hub:username"
    DOCKER_PASSWORD: "devops-020-100/docker-hub:password"
  exported-variables:
    - BUILD_ENVIRONMENT
    - CODEBUILD_BUILD_NUMBER

phases:
  install:
    runtime-versions:
      python: 3.11
      nodejs: 18
    commands:
      - echo "=== INSTALL PHASE ==="
      - echo "Installing build dependencies..."
      - pip install --upgrade pip
      - pip install -r requirements.txt
    finally:
      - echo "Install phase complete"

  pre_build:
    on-failure: CONTINUE
    commands:
      - echo "=== PRE_BUILD PHASE ==="
      - echo "Running code quality checks..."
      - flake8 src/ --count --select=E9,F63,F7,F82 --show-source
      - echo "Validating configuration..."
      - python -c "import yaml; yaml.safe_load(open('config.yml'))"
      - 'echo "Environment: $BUILD_ENVIRONMENT"'
      - 'echo "Notification Topic: $NOTIFICATION_TOPIC"'
      - echo "Pre-build validation complete"

  build:
    commands:
      - echo "=== BUILD PHASE ==="
      - 'echo "Build number: $CODEBUILD_BUILD_NUMBER"'
      - 'echo "Commit: $CODEBUILD_RESOLVED_SOURCE_VERSION"'
      - echo "Build started on $(date)"
      - mkdir -p dist reports
      - pytest tests/ --cov=src --cov-report=xml:reports/coverage.xml --junitxml=reports/test-results.xml
      - python setup.py sdist bdist_wheel
      - echo "Build completed on $(date)"

  post_build:
    commands:
      - echo "=== POST_BUILD PHASE ==="
      - 'echo "Build status: $CODEBUILD_BUILD_SUCCEEDING"'
      - |
        if [ "$CODEBUILD_BUILD_SUCCEEDING" = "1" ]; then
          echo "Build successful - preparing artifacts"
        else
          echo "Build failed - check logs for errors"
        fi
      - |
        echo "{\"build\":\"$CODEBUILD_BUILD_NUMBER\",\"commit\":\"$CODEBUILD_RESOLVED_SOURCE_VERSION\"}" > dist/metadata.json

reports:
  pytest-reports:
    files:
      - "test-results.xml"
    base-directory: "reports"
    file-format: JUNITXML
  coverage-reports:
    files:
      - "coverage.xml"
    base-directory: "reports"
    file-format: COBERTURAXML

artifacts:
  files:
    - "dist/**/*"
    - "dist/metadata.json"
  name: "myapp-${CODEBUILD_BUILD_NUMBER}"
  discard-paths: no
  base-directory: "."
  secondary-artifacts:
    test-reports:
      files:
        - "reports/test-results.xml"
        - "reports/coverage.xml"
        - "htmlcov/**/*"
      name: "test-reports"

cache:
  paths:
    - "/root/.cache/pip/**/*"
    - "node_modules/**/*"
```

Repository root and buildspec location

Place the buildspec.yml at the repository root so CodeBuild automatically discovers it when configured to use the source root. The sample repository used in this demo stores the buildspec at the top-level.

![A GitHub repository page in dark mode for a project named "020-100-sample-app," showing a file list (src, tests, .gitignore, README.md, etc.). The README header "Sample Application for Demo 020-100" and the repository sidebar (About, Releases, Contributors) are also visible.](https://mintcdn.com/kodekloud-c4ac6d9a/Kx09awxrzT0QVPGP/images/AWS-Certified-DevOps-Engineer-Professional/Domain-1-SDLC-Automation/Demo-Basic-Buildspec-Usage/github-repo-020-100-sample-app-dark.jpg?fit=max\&auto=format\&n=Kx09awxrzT0QVPGP\&q=85\&s=f5180292ac6ec86f28137553c77efba9)

Buildspec anatomy — top-level keys

Use `version: 0.2` to access reports, cache, exported variables, and improved phase semantics. The primary top-level keys you’ll see and use are:

| Key | Purpose | Example / Notes |
| - | - | - |
| `version` | Buildspec format version | `0.2` |
| `env` | Environment variables, secret references, shell selection | `shell: bash`, `variables`, `parameter-store`, `secrets-manager`, `exported-variables` |
| `phases` | Ordered build steps (`install`, `pre_build`, `build`, `post_build`) | Each phase supports `commands`. `install` supports `runtime-versions`. |
| `reports` | Test and coverage report groups for CodeBuild | `file-format: JUNITXML`, `base-directory` |
| `artifacts` | Primary and secondary artifact configuration (S3 uploads) | `files`, `base-directory`, `discard-paths`, `secondary-artifacts` |
| `cache` | Paths to cache across builds (local) | `paths: - "/root/.cache/pip/**/*"` |

Environment (`env`) keys explained

* `shell`: Choose shell (e.g., `bash`) to select the execution environment for build commands.
* `variables`: Plain-text inline environment variables available to phases.
* `parameter-store`: Systems Manager Parameter Store keys or paths; CodeBuild will decrypt and add them to the env. Learn more: [https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)
* `secrets-manager`: Secrets Manager references. Format supports `secret-id` or `secret-id:key` to fetch JSON fields. See: [https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)
* `exported-variables`: List variables to export for downstream CodePipeline actions.

Phases and execution order

CodeBuild runs phases in this exact order: install → pre\_build → build → post\_build. A condensed view of common phase responsibilities:

| Phase | Typical tasks | Notes |
| - | - | - |
| install | Install dependencies, configure runtimes | Supports `runtime-versions` & `finally` |
| pre\_build | Linting, config validation, fetching dynamic config | `on-failure` controls continuation on errors |
| build | Main compilation, run unit tests, package artifacts | Time-consuming tasks happen here |
| post\_build | Publish artifacts, create metadata, notify systems | Often used for uploading metadata and exports |

Important: `install.finally` always runs regardless of earlier failures (similar to try/finally). Use `on-failure` when you want a phase to continue even if one of its commands fails.

Set `on-failure: CONTINUE` when you want later phases to execute even if the current phase returns a non-zero exit code. The default `ABORT` stops the build when a phase fails. Check the AWS CodeBuild docs for current retry and failure behaviors: [https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html)

Environment variable sources in practice

* Inline variables (fast, visible in console): defined under `env.variables`. Example: `BUILD_ENVIRONMENT: "demo"`.
* Systems Manager Parameter Store: defined under `env.parameter-store`, pass parameter names or paths. Ensure the CodeBuild service role has `ssm:GetParameters`.
* Secrets Manager: defined under `env.secrets-manager`. You can reference `secret-id` or `secret-id:key` to extract a field from a JSON secret. Ensure the CodeBuild role has Secrets Manager read/decrypt permissions.

Tip: Grant minimal IAM permissions to the CodeBuild service role: `ssm:GetParameters` for Parameter Store entries and `secretsmanager:GetSecretValue` for Secrets Manager entries. Missing permissions will cause environment variable decryption to fail at the start of the build.

Built-in CodeBuild environment variables

CodeBuild injects several built-in variables with the `CODEBUILD_` prefix. Commonly used ones include:

* `CODEBUILD_BUILD_NUMBER` — incremental build number
* `CODEBUILD_RESOLVED_SOURCE_VERSION` — commit SHA or source version
* `CODEBUILD_BUILD_SUCCEEDING` — `1` when the build is successful

Use `env.exported-variables` to make any of these available to downstream pipeline actions.

Inspecting env resolution in logs

When the build starts, CodeBuild logs environment resolution and decryption. Example log excerpt:

```text theme={null}
[Container] 2026/03/02 19:09:24.919694 Phase is DOWNLOAD_SOURCE
[Container] 2026/03/02 19:09:24.921427 CODEBUILD_SRC_DIR=/codebuild/output/src/.../020-100-sample-app
[Container] 2026/03/02 19:09:24.923086 Selecting shell bash as specified in buildspec.
[Container] 2026/03/02 19:09:24.933395 Decrypting parameter store environment variables
[Container] 2026/03/02 19:09:25.244285 Adding prefix devops-020-100-build for report group name coverage-reports
```

You can also view resolved environment variables for an individual run from the CodeBuild console.

![Screenshot of the AWS CodeBuild console showing a build project’s details and the Environment variables tab. The page lists variables like BUILD\_ENVIRONMENT, NOTIFICATION\_TOPIC, and DOCKER\_USERNAME with the left-hand navigation menu visible.](https://mintcdn.com/kodekloud-c4ac6d9a/Kx09awxrzT0QVPGP/images/AWS-Certified-DevOps-Engineer-Professional/Domain-1-SDLC-Automation/Demo-Basic-Buildspec-Usage/aws-codebuild-environment-variables-screenshot.jpg?fit=max\&auto=format\&n=Kx09awxrzT0QVPGP\&q=85\&s=896f43e367ff9c616f2817125fb066f1)

Running tests and integrating reports

Best practice is to write JUnit-style and coverage reports into a `reports/` directory and configure the `reports` block in buildspec. CodeBuild captures these and surfaces them under Report groups in the console.

* pytest example flags used in the buildspec:
  * `--junitxml=reports/test-results.xml` (JUnit-style test report)
  * `--cov-report=xml:reports/coverage.xml` (coverage XML)
* Configure `reports` in buildspec with `base-directory` and `file-format`, for example `JUNITXML` or `COBERTURAXML`.

Artifacts — primary and secondary

Primary artifacts typically contain the packaged application (Wheels, tarballs, Docker context, etc.). Secondary artifacts are useful for storing test reports or other separate outputs.

Key artifact options:

* `files`: Glob patterns that specify which files to bundle into the artifact (e.g., `dist/**/*`).
* `base-directory`: Folder that acts as the root for artifacts.
* `discard-paths`: `no` preserves directory structure inside the artifact; `yes` flattens it.
* `name`: Artifact name supports variable interpolation, e.g., `"myapp-${CODEBUILD_BUILD_NUMBER}"`.
* `secondary-artifacts`: Define additional named artifacts (e.g., test reports).

Artifact configuration and console views are shown here:

![A screenshot of the AWS CodeBuild console showing a build project's Artifacts and Cache configuration, including S3 artifact upload locations, artifact identifiers (like "test-reports"), and encryption settings. The left sidebar displays CodeBuild navigation items such as Build project, Build history, and Report groups.](https://mintcdn.com/kodekloud-c4ac6d9a/Kx09awxrzT0QVPGP/images/AWS-Certified-DevOps-Engineer-Professional/Domain-1-SDLC-Automation/Demo-Basic-Buildspec-Usage/codebuild-artifacts-cache-s3-encryption.jpg?fit=max\&auto=format\&n=Kx09awxrzT0QVPGP\&q=85\&s=7c3a6e91efd59dac90b456e0f509fb7f)

Build caching strategies

Caching dependency directories dramatically reduces build time for repeated runs. CodeBuild supports local caching via the `cache.paths` block inside the buildspec and S3-based caching configured on the project.

Typical cache entries:

* Python pip cache: `/root/.cache/pip/**/*`
* Node dependencies: `node_modules/**/*`

In this demo, caching these paths reduced repeat build time from \~90s to \~35s.

Viewing a build run and results

After a build completes you can inspect:

* Full build logs (console or download)
* Report groups (test and coverage reports in the console)
* Exported environment variables accessible to downstream pipeline actions
* Artifacts stored in S3 (downloadable bundles or expanded files)

Example of environment and compute configuration as displayed in the CodeBuild console:

![A screenshot of the AWS CodeBuild console on the "Environment variables" tab showing a list of environment variables (e.g., BUILD\_ENVIRONMENT = demo, NOTIFICATION\_TOPIC, DOCKER\_USERNAME) and their types. The left sidebar shows Developer Tools > CodeBuild navigation items.](https://mintcdn.com/kodekloud-c4ac6d9a/Kx09awxrzT0QVPGP/images/AWS-Certified-DevOps-Engineer-Professional/Domain-1-SDLC-Automation/Demo-Basic-Buildspec-Usage/aws-codebuild-environment-variables-console.jpg?fit=max\&auto=format\&n=Kx09awxrzT0QVPGP\&q=85\&s=02207267d37d9a9b455bac4ed69dade0)

![A screenshot of the AWS CodeBuild console displaying a build project's Environment and Artifacts settings, showing the build image, compute type (EC2), compute resources (2 vCPUs, 4 GiB), service role ARN, and timeouts. The left sidebar shows the Developer Tools navigation for CodeBuild.](https://mintcdn.com/kodekloud-c4ac6d9a/Kx09awxrzT0QVPGP/images/AWS-Certified-DevOps-Engineer-Professional/Domain-1-SDLC-Automation/Demo-Basic-Buildspec-Usage/aws-codebuild-console-environment-artifacts.jpg?fit=max\&auto=format\&n=Kx09awxrzT0QVPGP\&q=85\&s=a091d53a314a7ccad249c7f6474a0d8f)

Summary checklist

* Use `version: 0.2` to leverage `reports`, `cache`, `exported-variables`, and improved phases.
* Choose env sources appropriately: inline variables, SSM Parameter Store, and Secrets Manager. Ensure the CodeBuild role has `ssm:GetParameters` and `secretsmanager:GetSecretValue` as needed.
* Keep phase structure: `install` → `pre_build` → `build` → `post_build`. Use `install.finally` for guaranteed cleanup and `on-failure` to control continuation.
* Integrate test reporting using `reports` with `JUNITXML` and coverage formats; store outputs under a `reports/` base-directory.
* Configure primary and secondary artifacts intentionally and use `discard-paths` according to how you want the archive structured.
* Enable caching for dependency directories to speed up iterative builds — consider S3 caching for longer-lived caches.

Next steps

If you want, I can:

* extract a minimal buildspec tailored for a single runtime (e.g., Node.js-only),
* convert this buildspec for Docker image builds,
* or produce a variant that uses S3 caching instead of local container caching.

Which variant would you like to see?

> **[Watch Video](https://learn.kodekloud.com/user/courses/aws-certified-devops-engineer-professional/module/199ecdf9-a58f-4c2d-b9c9-eac36de111cd/lesson/6fd097dc-dbb5-4994-a6d6-8853b3d1f227)**

> **[Practice Lab](https://learn.kodekloud.com/user/courses/aws-certified-devops-engineer-professional/module/199ecdf9-a58f-4c2d-b9c9-eac36de111cd/lesson/7725a2ce-b290-4fb7-b2ca-da560b117b3d)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.