React App Deployment with AWS CodePipeline
A fully automated CI/CD pipeline using AWS-native tooling — CodePipeline, CodeBuild, and S3 — to build and deploy a React application on every GitHub push. The pipeline lives entirely inside AWS, demonstrating the alternative to GitHub Actions for teams operating within an AWS-centric delivery workflow.
Implemented a fully AWS-native CI/CD pipeline — CodePipeline + CodeBuild + S3 — with zero dependency on external CI tooling, demonstrating a clean alternative to GitHub Actions
Automated the full build-and-deploy cycle on every GitHub push, reducing manual release steps to zero
Documented the architectural trade-offs between AWS-native and GitHub Actions pipelines, making the project a reference comparison for two distinct delivery approaches
Manual deployments are slow and error-prone. Organisations using AWS tooling exclusively need a delivery pipeline that lives entirely within AWS — not one that depends on GitHub-hosted runners or external CI services.
AWS CodePipeline detects every GitHub push via webhook and triggers an automated 3-stage pipeline. CodeBuild installs dependencies and builds the React app. The build output is deployed directly to S3 — no manual steps, no server to manage.
Clean, reproducible install from package-lock.json. Faster than npm install and guarantees the same versions every run.
React production build via react-scripts. Outputs optimised static files to the build/ directory.
Confirmation step. Could be extended to send notifications or run post-build validation.
Tells CodePipeline to deploy only the build/ output — not the source code, not node_modules.
GitHub Actions keeps the pipeline inside GitHub — the YAML lives in the repo and the runner is GitHub-hosted. CodePipeline keeps everything inside AWS — the pipeline is configured in the AWS console, CodeBuild runs the build in an AWS-managed container, and the deployment is handled by AWS directly. Organisations already deep in the AWS ecosystem often prefer CodePipeline because it integrates natively with CodeBuild, CodeDeploy, and the rest of the AWS developer tooling suite.
CodeBuild looks for buildspec.yml at the root of the source directory by default. The file defines all build phases — install, pre_build, build, post_build — and the artifacts section tells CodePipeline exactly which files to pass to the deploy stage.
npm ci installs exactly what is in package-lock.json without resolving. It is faster than npm install on CI because it skips the resolution step, and it is fully reproducible — the same versions every time regardless of when the build runs.
Create React App outputs its production build to a build/ directory, not dist/. This is a common source of confusion because many other tools (Vite, Rollup, webpack) default to dist/. Setting the wrong base-directory in buildspec.yml means CodePipeline deploys nothing — or worse, deploys source files instead of the compiled output.
The artifacts base-directory must match the build tool's output exactly. Create React App outputs to build/, not dist/. Getting this wrong means CodePipeline either deploys nothing or deploys the wrong files silently.
eslintrc.js config files that reference external packages will fail the CodeBuild if those packages are not installed. The safest approach is to rely on react-scripts' built-in ESLint config and remove any custom eslintrc files.
CodeBuild automatically retries failed builds once. This is useful for transient failures but can mask the real error — always read the build logs rather than waiting for the retry to potentially succeed.
S3 bucket policy errors with spaces in the ARN (arn:aws:s3:::bucket-name /*) fail silently — the policy saves successfully but GetObject requests return 403. Always validate the ARN has no spaces before the /*.
Project 03 solves the same delivery problem using GitHub Actions and IAM OIDC instead of CodePipeline.