Terraform aws_codebuild_project Deep Dive for AWS CodeBuild Automation

AWS CodeBuild is a fully managed continuous integration service that provisions a fresh container for each build and tears it down when the build completes. You do not manage build servers. The Terraform resource aws_codebuild_project is the primary way to define CodeBuild projects declaratively, and the reference implementations show a range of patterns from minimal projects to multi-stage pipelines and CodeBuild Runner workarounds.

Introduction

The aws_codebuild_project resource manages a CodeBuild Project resource. A minimal configuration to get started requires the name argument. Every production CodeBuild project typically needs an IAM service role, a source configuration, an environment definition, and an artifacts configuration. The Terraform examples in the reference material demonstrate Plan and Apply separation for Terraform deployments, basic app builds from GitHub, and a module that creates a CodeBuild Runner project using webhooks and CodeConnections.

Core Resource Shape

The resource aws_codebuild_project creates a CodeBuild project in AWS. The minimal configuration is:

hcl resource "aws_codebuild_project" "example" { name = "my-codebuild-project" }

That minimal block is valid for provisioning the resource, but operational projects add description, service role, build timeout, environment, source, artifacts, logs configuration, and tags.

Every CodeBuild project needs an IAM service role, a source configuration, an environment definition, and an artifacts configuration. A basic example that builds from a GitHub repository is:

```hcl
resource "awscodebuildproject" "main" {
name = "my-app-build"
description = "Build and test my-app"
buildtimeout = 15
service
role = awsiamrole.codebuild.arn

artifacts {
type = "NO_ARTIFACTS"
}

environment {
computetype = "BUILDGENERAL1MEDIUM"
image = "aws/codebuild/amazonlinux-x86
64-standard:5.0"
type = "LINUXCONTAINER"
image
pullcredentialstype = "CODEBUILD"
}

source {
type = "GITHUB"
location = "https://github.com/my-org/my-app.git"
gitclonedepth = 1
buildspec = "buildspec.yml"
}

logsconfig {
cloudwatch
logs {
groupname = "/codebuild/my-app"
stream
name = "build"
}
}

tags = {
Environment = "production"
}
}
```

Environment variables are supported inside the environment block. An example shows APP_ENV with value production and DB_PASSWORD with value production/database/password and type SECRETS_MANAGER to pull from Secrets Manager at build time.

Terraform Plan and Apply Pattern with CodePipeline

A common pattern uses two CodeBuild projects, one for Plan and one for Apply, both feeding a CodePipeline.

Terraform Plan Project

The plan project runs terraform plan and produces an artifact for the apply stage.

```hcl
resource "awscodebuildproject" "terraformplan" {
name = "terraform-plan"
description = "Run terraform plan"
service
role = awsiamrole.codebuildrole.arn
build
timeout = 15

artifacts {
type = "CODEPIPELINE"
}

environment {
type = "LINUXCONTAINER"
compute
type = "BUILDGENERAL1SMALL"
image = "aws/codebuild/amazonlinux2-x8664-standard:3.0"
privileged
mode = false
}

logsconfig {
cloudwatch
logs {
group_name = "terraform-plan-logs"
}
}

source {
type = "CODEPIPELINE"
buildspec = < version: 0.2
phases:
install:
runtime-versions:
python: 3.8
commands:
- wget https://releases.hashicorp.com/terraform/1.0.11/terraform1.0.11linuxamd64.zip
- unzip terraform
1.0.11linuxamd64.zip
- mv terraform /usr/local/bin/
prebuild:
commands:
- echo "Starting Terraform plan phase..."
- terraform --version
build:
commands:
- terraform init -input=false
- terraform plan -input=false -out=tfplan
post
build:
commands:
- echo "Completed Terraform plan phase"
artifacts:
files:
- tfplan
- .terraform//*
- '
/*'
EOF
}
}
```

The install phase sets up python and downloads Terraform 1.0.11 for Linux amd64, unzips it, and moves the binary to /usr/local/bin/. The pre build phase echoes a start message and outputs terraform version. The build phase runs terraform init -input=false and terraform plan -input=false -out=tfplan. The post build phase echoes completion.

Terraform Apply Project

The apply project consumes the plan artifact and executes terraform apply.

```hcl
resource "awscodebuildproject" "terraformapply" {
name = "terraform-apply"
description = "Run terraform apply"
service
role = awsiamrole.codebuildrole.arn
build
timeout = 15

artifacts {
type = "CODEPIPELINE"
}

environment {
type = "LINUXCONTAINER"
compute
type = "BUILDGENERAL1SMALL"
image = "aws/codebuild/amazonlinux2-x8664-standard:3.0"
privileged
mode = false
}

logsconfig {
cloudwatch
logs {
group_name = "terraform-apply-logs"
}
}

source {
type = "CODEPIPELINE"
buildspec = < version: 0.2
phases:
install:
runtime-versions:
python: 3.8
commands:
- wget https://releases.hashicorp.com/terraform/1.0.11/terraform1.0.11linuxamd64.zip
- unzip terraform
1.0.11linuxamd64.zip
- mv terraform /usr/local/bin/
prebuild:
commands:
- echo "Starting Terraform apply phase..."
- terraform --version
build:
commands:
- terraform init -input=false
- terraform apply -input=false tfplan
post
build:
commands:
- echo "Completed Terraform apply phase"
artifacts:
files:
- '*/'
EOF
}
}
```

Both CodeBuild projects are nearly identical, just with plan or apply specific logs, locations etc, and the only command difference is terraform plan vs terraform apply. The Artifacts section passes the tfplan file from the plan stage over to the apply stage. The pipeline assembly uses an aws_codepipeline resource with a Source stage pulling from GitHub and a Plan stage running Terraform Plan.

CodeBuild Runner Project Module

A separate use case provisions an AWS CodeBuild Runner project with an attached webhook. Currently AWS does not support creating Runner Projects via API or CLI. The module is a workaround.

Terraform creates a default project and, by applying certain webhooks, it converts the project into a Runner project. This module is useful for teams that want to run GitHub Actions on AWS-managed on-demand compute.

Prerequisites:

  • A GitHub App "AWS Connector for GitHub" successfully installed and configured in your AWS account.
  • CodeConnection itself can be provisioned via Terraform but requires manual authorization from AWS. The module will fail if the connection is not authorized.

Capabilities:

  • Provisions a CodeBuild Runner project using GitHub as the source via CodeConnections
  • Adds default filter groups to capture key events indirectly creates a runner project without official support
  • Supports additional user-supplied filter groups
  • Automatically configures scope_configuration when applicable i.e., webhook access at repo level vs org level
  • Defaults to Lambda compute with 2 GB memory, Linux OS, and Node.js runtime

Examples referenced include:

  • Access level - Repo | Compute - EC2 | Mode - Container
  • Access level - Org | Compute - Lambda (4 GB) | Mode - Container
  • Repo-level access with additional webhook filter

The default filter group is the core logic that triggers creation of a runner project.

End-to-End Build and Artifact Workflow

A Terraform script to create AWS Codebuild project can provision a wider system:

  • AWS Codebuild project
  • Roles
  • ECR repository for storing docker images
  • S3 bucket for storing the build artifacts
  • SSM parameter store to store the Docker Hub password

Code build project steps:

  • Compiles the java project using maven
  • Build the docker image
  • Push the docker image to ECR repository
  • Publish the artifacts to s3 bucket

This pattern shows CodeBuild used for container build and artifact publishing rather than just Terraform.

Configuration Comparison

Aspect Minimal Project Basic App Build Terraform Plan/Apply
name my-codebuild-project my-app-build terraform-plan / terraform-apply
build_timeout not set 15 minutes 15
service_role not set awsiamrole.codebuild.arn awsiamrole.codebuild_role.arn
artifacts type not set NO_ARTIFACTS CODEPIPELINE
environment compute_type not set BUILDGENERAL1MEDIUM BUILDGENERAL1SMALL
environment image not set aws/codebuild/amazonlinux-x86_64-standard:5.0 aws/codebuild/amazonlinux2-x86_64-standard:3.0
source type not set GITHUB CODEPIPELINE
logs not set cloudwatch_logs group /codebuild/my-app cloudwatch_logs group terraform-plan-logs / terraform-apply-logs

Practical Notes

  • CodeBuild spins up a fresh container for each build and tears it down when done, so you do not manage build servers.
  • The nice thing about CodeBuild is you don't manage any build servers.
  • Buildspec version 0.2 is used in the Terraform examples with phases install, prebuild, build, postbuild.
  • Install phase typically sets runtime versions and installs tools like Terraform via wget and unzip.
  • Pre build phase echoes status and validates tool versions.
  • Build phase initializes Terraform and runs plan or apply.
  • Post build phase outputs completion messages.
  • Artifacts configuration controls what files are passed between pipeline stages.

Conclusion

The aws_codebuild_project resource supports a wide spectrum of automation from minimal project creation to complex multi-stage Terraform pipelines and Runner project workarounds. The reference material shows a minimal name-only configuration, a production app build with GitHub source, CloudWatch logs, Secrets Manager environment variables, and tags, and a Plan-Apply pair for Terraform deployments with CODEPIPELINE artifacts and shared environment settings. The CodeBuild Runner module demonstrates how Terraform can emulate unsupported features by combining CodeConnections, webhooks, and filter groups, with defaults of Lambda compute 2 GB memory Linux Node.js runtime and options for EC2 compute and Lambda 4 GB. The end-to-end script example expands the pattern to include roles, ECR, S3, and SSM for Java Maven builds and Docker image publishing. Using these patterns you can define declarative, reproducible CodeBuild automation with Terraform while keeping artifact flow, logging, and security consistent across projects.

Sources

  1. awsfundamentals.com
  2. dev.to
  3. github.com
  4. docs.devopspilot.com
  5. oneuptime.com

Related Posts