Build an AWS DevOps CI/CD Pipeline

Automate code deployment from GitHub to a live app on AWS.

Introduction

30 Second Summary

Every time a developer pushes code, professional teams don't manually copy files to their servers. They use automated pipelines that build, test, and deploy changes in minutes.

In this project, you will build a CI/CD pipeline on AWS that automatically deploys a web application every time you push code to GitHub.

What You'll Build

A complete automated pipeline connecting GitHub, AWS CodeBuild, and AWS Elastic Beanstalk through AWS CodePipeline.

By the end of this project, you'll have:

  • A Node.js web application hosted live on AWS Elastic Beanstalk, accessible via a public URL.
  • A buildspec.yml file that tells CodeBuild exactly how to install dependencies and package your app.
  • An AWS CodePipeline with Source, Build, and Deploy stages that runs automatically on every GitHub push.
  • Secret Mission: Add a manual approval stage so deployments require human sign-off before reaching production.

Are there any prerequisites?

No prior experience with AWS or CI/CD is required. This project includes full setup instructions for every tool you'll need, including Node.js, Git, GitHub, and your AWS account.

Create and Push Your Node.js App

Your development tools are installed and your GitHub repo is cloned locally. Now it's time to create the application that your pipeline will automatically build and deploy.

In this step, you'll write a simple Node.js web server, define a build configuration file that tells AWS how to package your app, and push everything to GitHub.

In this step, get ready to:
  • Initialize a Node.js project and create an Express web server.
  • Create a buildspec file that tells AWS CodeBuild how to build your app.
  • Commit and push your code to GitHub.
Initialize your Node.js project

Every Node.js application starts with a package.json file that defines the project's metadata, scripts, and dependencies. You'll initialize one now, then install Express as your web framework.

  • In your terminal, make sure you're inside your my-pipeline-app folder by running:
cd ~/Desktop/my-pipeline-app
  • Initialize a new Node.js project and install Express by running these commands:
npm init -y
npm install express

You should see a node_modules folder and package-lock.json appear in your project directory.

What do these commands do?

npm init -y creates a package.json file with default values, using your folder name as the project name.

npm install express downloads the Express web framework and adds it as a dependency in your package.json.

Seeing permission errors?

Make sure you're inside the my-pipeline-app folder, not its parent directory. Run pwd (macOS/Linux) or cd (Windows) to check your current location.

help me fix npm permission errors in my project folder

The npm init -y command generated a basic package.json, but you need to customize it with the right scripts and metadata for your pipeline.

  • Open package.json in your code editor and replace its entire contents with this code:
{
  "name": "my-pipeline-app",
  "version": "1.0.0",
  "description": "A simple Node.js app deployed via AWS CI/CD pipeline",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Tests passed\" && exit 0"
  },
  "dependencies": {
    "express": "^4.21.2"
  }
}

What do these scripts do?

The start script tells Node.js how to launch your app. Elastic Beanstalk uses this script to run your application in production.

The test script is a placeholder that always passes. Your build pipeline will run this to verify your app is healthy before deploying.

  • Save package.json.

Now you'll create the actual web server that your pipeline will deploy.

  • Create a new file called app.js in your my-pipeline-app folder and add this code:
// Import Express framework
const express = require('express');
const app = express();
const port = 8080;

// Main route - returns a greeting message
app.get('/', (req, res) => {
  res.send('Hello from my CI/CD pipeline!');
});

// Health check endpoint for monitoring
app.get('/health', (req, res) => {
  res.status(200).send('OK');
});

// Start the server on port 8080 (Elastic Beanstalk's default for Node.js)
app.listen(port, () => {
  console.log(`App running on port ${port}`);
});

What does this code do?

This creates a web server with two routes. The / route returns a greeting message that you'll see when visiting your live app.

The /health route returns a simple OK response. Elastic Beanstalk uses health checks to verify your application is running correctly.

Port 8080 is important. Elastic Beanstalk forwards incoming traffic to port 8080 by default for Node.js applications.

  • Save app.js.
  • Test your app by running:
node app.js

You should see App running on port 8080 in your terminal.

  • Press Ctrl+C to stop the server.

Seeing 'Cannot find module express'?

This means node_modules is missing or Express didn't install correctly. Run npm install again from inside the my-pipeline-app folder.

help me fix a missing module error when running node app.js

✔️ Awesome, I've got everything!

Great. Make sure both package.json and app.js are saved before moving on.

ⓧ I'd like to double check the full code

Here's what package.json should look like:

{
  "name": "my-pipeline-app",
  "version": "1.0.0",
  "description": "A simple Node.js app deployed via AWS CI/CD pipeline",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Tests passed\" && exit 0"
  },
  "dependencies": {
    "express": "^4.21.2"
  }
}

Here's what app.js should look like:

const express = require('express');
const app = express();
const port = 8080;

app.get('/', (req, res) => {
  res.send('Hello from my CI/CD pipeline!');
});

app.get('/health', (req, res) => {
  res.status(200).send('OK');
});

app.listen(port, () => {
  console.log(`App running on port ${port}`);
});
Create the buildspec file

AWS CodeBuild needs instructions for how to install dependencies, run tests, and package your app. You define these instructions in a file called buildspec.yml.

  • Create a new file called buildspec.yml in the root of your my-pipeline-app folder (at the same level as app.js) and add this code:
version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 22
    commands:
      - echo Installing dependencies...
      - npm install
  build:
    commands:
      - echo Build started on `date`
      - npm test
  post_build:
    commands:
      - echo Build completed on `date`

artifacts:
  files:
    - '**/*'

What does this buildspec do?

The install phase sets the Node.js runtime to version 22 and runs npm install to download your dependencies fresh on every build.

The build phase runs npm test. If your test script fails, the build stops and your app won't be deployed.

The artifacts section tells CodeBuild to package all files ('**/*') and pass them to the next pipeline stage for deployment.

Why version 0.2?

AWS recommends buildspec version 0.2. Version 0.1 runs each command in a separate shell instance, making it harder to share state between commands.

  • Save buildspec.yml.

YAML formatting issues?

YAML is sensitive to indentation. Make sure you use spaces (not tabs) and that each level is indented by exactly 2 spaces. The phases and artifacts keys should be at the same indentation level.

help me fix YAML indentation errors in my buildspec.yml

✔️ Awesome, I've got everything!

Great. Make sure buildspec.yml is saved at the root of your project folder, alongside app.js and package.json.

ⓧ I'd like to double check the full code

Here's what buildspec.yml should look like:

version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 22
    commands:
      - echo Installing dependencies...
      - npm install
  build:
    commands:
      - echo Build started on `date`
      - npm test
  post_build:
    commands:
      - echo Build completed on `date`

artifacts:
  files:
    - '**/*'
Commit and push to GitHub

Your app code and build instructions are ready. Now you'll push everything to GitHub so that your pipeline can pull the code later.

  • Stage, commit, and push all your files to GitHub by running these commands:
git add .
git commit -m "Initial app with buildspec"
git push origin main

What do these commands do?

git add . stages all new and modified files for commit.

git commit -m "Initial app with buildspec" saves a snapshot of your code with a descriptive message.

git push origin main uploads your local commits to the main branch on GitHub.

You should see output confirming the push succeeded, including the branch name main and a commit hash.

  • Open your my-pipeline-app repository on GitHub in your browser.
  • Verify that you can see app.js, package.json, and buildspec.yml listed in the repository.

Push rejected or authentication failed?

If Git asks for credentials, you may need to set up a personal access token or SSH key for GitHub authentication. GitHub no longer accepts passwords for command-line operations.

If you see a rejection about the remote containing work you don't have locally, run git pull origin main --rebase first, then try the push again.

help me fix git push authentication issues with GitHub

Your app is live on GitHub and ready for the pipeline. Next up, you'll deploy it to AWS Elastic Beanstalk so it has a home on the internet.

Deploy Your App with Elastic Beanstalk

Your code is on GitHub, ready for automation. Before wiring up the full pipeline, you need a live hosting destination for your app.

AWS Elastic Beanstalk handles server provisioning, networking, and deployments for you. You tell it what platform to run (Node.js, Python, etc.) and it creates the infrastructure automatically. In this step, you'll set up a Beanstalk environment that becomes the final stop in your CI/CD pipeline.

In this step, get ready to:
  • Create an Elastic Beanstalk application and select the Node.js 22 platform.
  • Configure a free-tier-eligible single-instance environment.
  • Verify the environment is healthy and note the live URL.
Create the Elastic Beanstalk application

An Elastic Beanstalk application is a container that holds your environments, versions, and configurations. You'll create one now and deploy a sample app to confirm everything works before connecting your pipeline.

  • In the AWS Console, type Elastic Beanstalk in the top search bar and select the service.
  • Click Create application.
  • For Application name, enter my-pipeline-app.
  • For Platform, select Node.js.
  • For Platform branch, select Node.js 22 running on 64bit Amazon Linux 2023.
  • For Application code, choose Sample application.
  • For Configuration presets, choose Single instance.

Why use a sample application first?

You're deploying AWS's built-in sample app instead of your own code for now. This confirms that the environment itself is working correctly before you connect the pipeline. Once CodePipeline is set up, it will automatically replace this sample with your actual app from GitHub.

Configure the environment settings

The environment tier and instance type determine how your app runs and how much it costs. A single-instance web server environment uses one EC2 virtual machine, which stays within the AWS Free Tier.

  • Click Next to proceed to the Configure service access page.
  • For Service Role, select Create and use new service role if this is your first time using Elastic Beanstalk. If you see an existing role, select it.
  • For EC2 instance profile, select an existing instance profile if one appears in the dropdown.

What if the EC2 instance profile dropdown is empty?

If no values appear in the EC2 instance profile dropdown, you need to create an IAM role first. Open the IAM console in a new tab, create a role with the EC2 use case, and attach the AWSElasticBeanstalkWebTier policy. Return to the Elastic Beanstalk tab, refresh the dropdown, and select the new role.

If a value like aws-elasticbeanstalk-ec2-role appears, select it and continue.

  • Click Skip to Review to accept defaults for the optional networking, database, and scaling steps.
  • On the Review page, confirm the environment tier shows Web server environment and the instance type is t3.micro.
  • Click Submit to create the environment.

The environment takes 3-5 minutes to launch. Elastic Beanstalk is provisioning an EC2 instance, configuring security groups, and deploying the sample app behind the scenes.

Grab a coffee while you wait

Environment creation typically takes 3-5 minutes. You can watch the events stream on the environment page to track progress. Look for a green health indicator and the message that the environment launched successfully.

What is a single-instance environment?

A single-instance environment runs your app on one EC2 virtual machine without a load balancer. This keeps costs at $0 under the Free Tier (750 hours/month of t3.micro for eligible accounts). For a learning project, this is all you need.

Verify the environment is healthy
  • Wait until the environment dashboard shows Health: OK with a green checkmark.
  • Click the environment URL displayed near the top of the page (it looks like my-pipeline-app-env.us-east-1.elasticbeanstalk.com).
  • A new browser tab opens showing the Elastic Beanstalk sample application page. This confirms your environment is running correctly.
  • Copy this URL and save it somewhere accessible. You'll use it later to confirm your pipeline deployed successfully.

Environment showing degraded or severe health?

If the health status is not green after 5 minutes, check the Events tab on the environment page for error details. Common causes include missing IAM permissions (the EC2 instance profile was not set) or a region mismatch.

Make sure your region is set to us-east-1 in the top-right corner of the console. If the instance profile was missing, terminate the environment and recreate it after setting up the IAM role.

Having trouble getting a green health check?

Your hosting environment is live and healthy. Next up, you'll create a CodeBuild project that compiles and tests your code every time a change is pushed.

Create the Build Project in CodeBuild

Your Elastic Beanstalk environment is live and waiting for your app. The next piece of the puzzle is teaching AWS how to build your code before deploying it.

AWS CodeBuild is a fully managed build service that compiles your source code, runs tests, and packages the result. In this step, you will create a CodeBuild project that pulls code from your GitHub repository and runs the build instructions in your buildspec.yml file.

In this step, get ready to:
  • Create a CodeBuild build project connected to your GitHub repository.
  • Configure the build environment with the right operating system and runtime image.
  • Run a test build to verify everything works.
Create the CodeBuild project and connect GitHub

A CodeBuild project defines where your source code lives, what build environment to use, and what commands to run. You will point it at your GitHub repo so it can pull the latest code on every build.

  • In the AWS Management Console, type CodeBuild in the top search bar and select CodeBuild.
  • In the left navigation pane, expand Build and click Build projects.
  • Click the Create build project button.
  • Under Project configuration, enter my-pipeline-app-build in the Project name field.
  • Scroll down to the Source section.
  • For Source provider, select GitHub from the dropdown.
  • Click Connect to GitHub and authorize AWS CodeBuild to access your GitHub account.
  • A new browser tab will open asking you to grant access. Click the Authorize button and enter your GitHub password if prompted.
  • Back on the CodeBuild page, select Repository in my GitHub account.
  • Choose your my-pipeline-app repository from the list.

What is a CodeBuild project?

A build project tells CodeBuild everything it needs to run your build. It defines the source (GitHub), the environment (a Docker image with the OS and tools), and where to find the build commands (your buildspec.yml).

By connecting GitHub as the source provider, CodeBuild can pull your latest code automatically whenever a build is triggered.

GitHub authorization not working?

Make sure you are signed into GitHub in the same browser. If the authorization page does not appear, check that pop-ups are not blocked.

Help me connect GitHub to CodeBuild

Configure the build environment

The build environment is the compute instance where CodeBuild runs your commands. You need to pick an operating system and a pre-built image that includes Node.js support.

  • Scroll down to the Environment section.
  • For Environment image, confirm that Managed image is selected.
  • For Operating system, select Amazon Linux.
  • For Runtime(s), select Standard.
  • For Image, select aws/codebuild/amazonlinux2-x86_64-standard:5.0.
  • Under Service role, select New service role and keep the auto-generated role name.
  • Scroll down to the Buildspec section.
  • Select Use a buildspec file. This tells CodeBuild to look for your buildspec.yml in the repository root.
  • Click Create build project at the bottom of the page.

Why this image?

The aws/codebuild/amazonlinux2-x86_64-standard:5.0 image includes Node.js 22 and other common runtimes pre-installed. It matches the runtime-versions section of your buildspec.yml that specifies nodejs: 22.

What is a service role?

The service role is an IAM role that gives CodeBuild permission to access your source code, write logs, and store build artifacts. Selecting New service role creates one automatically with the right permissions.

Run a test build

Now that the project exists, run a build to confirm CodeBuild can pull your code, install dependencies, and pass your tests.

  • On your new build project page, click Start build.
  • The build will start immediately. Wait for it to complete (this typically takes 1-2 minutes).
  • Once the build finishes, check that the Build status shows Succeeded.
  • Click Build logs to see the output. You should see your npm install and npm test commands running successfully.

What should I see in the logs?

The build logs show each phase defined in your buildspec.yml. You should see "Installing dependencies..." followed by npm install output, then "Tests passed" from your npm test script, and finally "Build completed".

Build failed?

Check that your buildspec.yml is in the root of your repository on the main branch. If CodeBuild cannot find the file, the build will fail.

Also verify that you pushed your latest code to GitHub. Run git status locally to check for uncommitted changes.

Help me debug my CodeBuild failure

Your build project is ready. Next up, you will connect all the pieces together into an automated pipeline using AWS CodePipeline.

Create the CI/CD Pipeline with CodePipeline

You now have all three pieces of the puzzle in place. Your source code lives in GitHub, CodeBuild knows how to compile and test it, and Elastic Beanstalk is ready to host it.

The missing piece is the orchestrator that connects them into a single automated workflow. AWS CodePipeline watches your GitHub repository for changes, triggers CodeBuild when a new commit lands, and deploys the result to Elastic Beanstalk automatically.

In this step, get ready to:
  • Create an AWS CodePipeline with Source, Build, and Deploy stages.
  • Connect GitHub, CodeBuild, and Elastic Beanstalk into one automated delivery workflow.
  • Watch the pipeline run automatically on creation.
Create the pipeline and configure settings

The CodePipeline creation wizard walks you through each stage one at a time. You will start by naming the pipeline and choosing its type.

  • In the AWS Management Console search bar at the top, type CodePipeline and select CodePipeline.
  • Click Create pipeline.
  • On the Choose creation option page, under Creation options, select Build custom pipeline.
  • Click Next.
  • In the Pipeline name field, enter my-pipeline-app-pipeline.
  • For Pipeline type, select V1.
  • For Service role, select New service role.
  • Leave the settings under Advanced settings at their defaults.
  • Click Next.

Why choose V1 over V2?

CodePipeline offers two pipeline types. V1 gives you one free active pipeline per month, indefinitely.

V2 charges $0.002 per action execution minute and only includes 100 free minutes per month. For a learning project where you will trigger many builds, V1 keeps costs predictable at $0.

Configure the Source and Build stages

The Source stage tells the pipeline where your code lives. The Build stage tells it how to compile and test that code.

  • For Source provider, select GitHub (via GitHub App).
  • Under Connection, click Connect to GitHub.
  • A pop-up window will appear asking you to install the AWS Connector for GitHub on your account.
  • Follow the prompts to authorize access and install the app.
  • Once connected, select your my-pipeline-app repository.
  • For the branch, select main.
  • For Output artifact format, select CodePipeline default.
  • Click Next.
  • For Build provider, select AWS CodeBuild.
  • In Project name, select my-pipeline-app-build.
  • Click Next.

What is the AWS Connector for GitHub?

The AWS Connector for GitHub is a GitHub App that gives AWS services secure, token-free access to your repositories. You install it once and can reuse the connection across multiple AWS services.

This is more secure than personal access tokens because you can scope access to specific repositories only.

GitHub connection not working?

Make sure pop-ups are not blocked in your browser. The authorization flow opens a new window that needs to communicate back to the AWS Console.

If you installed the connector previously but do not see your repository, check that the connector has access to the my-pipeline-app repo in your GitHub Settings under Applications.

Help me connect GitHub to AWS CodePipeline

Configure the Deploy stage and launch the pipeline

The Deploy stage tells the pipeline where to send your built code. You will point it at the Elastic Beanstalk environment you created earlier.

  • For Deploy provider, select AWS Elastic Beanstalk.
  • In Application name, select my-pipeline-app.
  • In Environment name, select the environment you created earlier.
  • Click Next.
  • On the Review page, double-check that all three stages (Source, Build, Deploy) are listed correctly.
  • Click Create pipeline.

The pipeline immediately starts its first run. You will see all three stages appear with progress indicators.

What happens when the pipeline is created?

CodePipeline automatically pulls your latest code from the main branch, sends it to CodeBuild for testing, then deploys the output to Elastic Beanstalk.

It also creates an S3 bucket behind the scenes to store artifacts (your zipped code) as they move between stages. You do not need to configure this bucket manually.

Pipeline stuck or showing a failure?

If the Source stage fails, confirm that the GitHub connection was installed successfully. Return to Settings then Connections in the CodePipeline console and verify the status shows Available.

If the Build stage fails, click the Details link on the Build stage to view the CodeBuild logs. A common cause is a mismatch between the buildspec file location and the project settings.

If the Deploy stage fails, make sure your Elastic Beanstalk environment is still healthy (green checkmark) before the pipeline runs.

Help me debug my CodePipeline failure

Your automated delivery pipeline is live. Next up, you will test the full cycle by pushing a code change and watching it deploy automatically.

Test the Automated Pipeline

Your pipeline is built and has already kicked off its first run automatically. Now it's time to see the full CI/CD cycle in action.

In this step, you'll confirm your initial deployment is live on the internet. Then you'll make a code change, push it to GitHub, and watch the entire pipeline fire without any manual intervention.

In this step, get ready to:
  • Verify the initial deployment shows your app on the Elastic Beanstalk URL.
  • Push a code change to GitHub and watch the pipeline trigger automatically.
  • Confirm the updated app is live on the internet within minutes.
Verify the initial deployment

The pipeline you created in the previous step ran immediately. It should have pulled your code from GitHub, built it with CodeBuild, and deployed it to Elastic Beanstalk.

  • Return to the CodePipeline console in your browser.
  • Click on your pipeline my-pipeline-app-pipeline to see its stages.
  • Wait for all three stages (Source, Build, Deploy) to show green checkmarks.

How long does this take?

The full pipeline run typically takes 3-5 minutes. The Deploy stage takes the longest because Elastic Beanstalk needs to swap your application code on the running instance.

  • Once all stages are green, open a new browser tab.
  • Paste your Elastic Beanstalk environment URL (the one you noted earlier) into the address bar and press Enter.

You should see the message "Hello from my CI/CD pipeline!" displayed in your browser.

Still seeing the sample app?

If you still see the Elastic Beanstalk sample app instead of your message, the Deploy stage may not have finished yet. Return to the CodePipeline console and confirm all three stages show green checkmarks.

If the Deploy stage shows a red X, click on the Details link on the Deploy stage to see the error. A common cause is a mismatched port. Your app must listen on port 8080.

Help me troubleshoot my pipeline deployment

Push a code change to trigger the pipeline

Seeing your app live is great, but the real power of a CI/CD pipeline is what happens next. You'll change one line of code, push it, and watch the pipeline handle everything else.

  • In your code editor, open app.js from inside your my-pipeline-app folder.
  • Find this line:
res.send('Hello from my CI/CD pipeline!');
  • Replace 'Hello from my CI/CD pipeline!' with 'Hello from my automated pipeline v2!', so the line now looks like this:
res.send('Hello from my automated pipeline v2!');
  • Save app.js.

Now commit and push this change to GitHub so the pipeline can pick it up.

  • Stage, commit, and push the change by running these commands in your terminal:
git add .
git commit -m "Update message to v2"
git push origin main

What do these commands do?

  • git add . stages all changed files for commit.
  • git commit -m "Update message to v2" saves the changes with a descriptive message.
  • git push origin main sends the commit to your GitHub repository on the main branch.

You should see output confirming the push to GitHub was successful.

Push rejected or authentication failed?

If you see an authentication error, your Git credentials may have expired. Try pushing again. GitHub will prompt you to re-authenticate through your browser.

If the push is rejected because the remote contains work you don't have locally, run git pull origin main first, then push again.

Help me fix my git push issue

Watch the pipeline deploy your update

The moment you pushed to GitHub, CodePipeline detected the change and started a new run. This is the automated workflow in action.

  • Return to the CodePipeline console in your browser.
  • Click on my-pipeline-app-pipeline to view the pipeline stages.
  • Watch the Source stage turn blue (in progress), then green (succeeded).
  • Wait for the Build and Deploy stages to complete and show green checkmarks.

What is happening behind the scenes?

CodePipeline detected your push to the main branch through the GitHub App connection. It pulled the latest code, sent it to CodeBuild to run npm install and npm test, then deployed the built artifacts to your Elastic Beanstalk environment.

  • Once all three stages show green, open your Elastic Beanstalk URL in a new browser tab (or refresh the tab from earlier).

You should now see "Hello from my automated pipeline v2!" displayed in your browser. You pushed one commit and your code went from GitHub to a live URL automatically.

Still seeing the old message?

Try a hard refresh in your browser (Cmd+Shift+R on macOS or Ctrl+Shift+R on Windows) to clear the cache.

If the Deploy stage is still in progress in the CodePipeline console, wait for it to turn green before refreshing. The full run takes 3-5 minutes.

Help me see my updated app

✔️ Awesome, I've got everything!

Great. Double check you've saved your file and that your Elastic Beanstalk URL shows the updated message.

ⓧ I'd like to double check the full code

Here is the final state of app.js after your update:

const express = require('express');
const app = express();
const port = 8080;

app.get('/', (req, res) => {
  res.send('Hello from my automated pipeline v2!');
});

app.get('/health', (req, res) => {
  res.status(200).send('OK');
});

app.listen(port, () => {
  console.log(`App running on port ${port}`);
});

Your buildspec.yml and package.json remain unchanged:

version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 22
    commands:
      - echo Installing dependencies...
      - npm install
  build:
    commands:
      - echo Build started on `date`
      - npm test
  post_build:
    commands:
      - echo Build completed on `date`

artifacts:
  files:
    - '**/*'
{
  "name": "my-pipeline-app",
  "version": "1.0.0",
  "description": "A simple Node.js app deployed via AWS CI/CD pipeline",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"Tests passed\" && exit 0"
  },
  "dependencies": {
    "express": "^4.21.2"
  }
}

Secret mission

Add a Manual Approval Stage

Your pipeline deploys every push automatically. But in the real world, teams add approval gates so a human reviews changes before they reach production. Can you add a manual approval stage between Build and Deploy?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

This project uses AWS services that stay within Free Tier limits for most accounts. However, the Elastic Beanstalk environment runs an EC2 instance that will incur charges if your Free Tier expires or you exceed 750 hours per month.

Cost warning

Your Elastic Beanstalk environment runs a t3.micro EC2 instance continuously. For accounts created before July 15, 2025, this is free for 12 months (750 hours/month). For accounts created on or after July 15, 2025, you have 6 months or until your signup credits are used up.

If your Free Tier has expired, this instance costs approximately $8-10/month. Terminate the environment if you are not actively using it.

Resources you used:

  • Elastic Beanstalk environment and application (my-pipeline-app) running in us-east-1.
  • CodePipeline my-pipeline-app-pipeline (V1, 1 free pipeline per month).
  • CodeBuild project my-pipeline-app-build (100 free build minutes per month).
  • S3 bucket for pipeline artifacts (auto-created by CodePipeline).
  • IAM service roles created for CodePipeline and CodeBuild.
  • Local project files in my-pipeline-app on your Desktop.

Keep everything running

No action needed. Choose this if you are still actively building on your pipeline or planning to extend the project soon.

  • Your pipeline will continue to deploy automatically on every push to GitHub.
  • Costs stay at $0 as long as your account is within Free Tier limits (750 EC2 hours/month for accounts under 12 months old, or within signup credits for newer accounts).
  • CodePipeline V1 remains free (1 active pipeline per month). CodeBuild remains free (100 build minutes per month, does not expire).

Pause - I'll come back to this later

Shut down the running EC2 instance to stop ongoing charges, but keep your application configuration so you can recreate the environment later.

  • In the AWS Console, navigate to Elastic Beanstalk.
  • Select your my-pipeline-app environment.
  • Click Actions, then Terminate environment.
  • Confirm the termination. This stops the EC2 instance and removes the environment, but keeps the application definition.
  • Your CodePipeline and CodeBuild project remain configured. When you are ready to resume, recreate the Elastic Beanstalk environment and update your pipeline's deploy stage to point to it.

Delete - I don't want to use this again

Remove all project resources from AWS and your local machine. This ensures $0 charges going forward.

Delete the Elastic Beanstalk environment and application:

  • In the AWS Console, navigate to Elastic Beanstalk.
  • Select your my-pipeline-app environment.
  • Click Actions, then Terminate environment. Confirm and wait for termination to complete.
  • Navigate back to Applications in the Elastic Beanstalk console.
  • Select my-pipeline-app, click Actions, then Delete application. Confirm the deletion.

Delete the CodePipeline:

  • Navigate to the CodePipeline console.
  • Select my-pipeline-app-pipeline.
  • Click Delete pipeline. Type the pipeline name to confirm and click Delete.

Delete the CodeBuild project:

  • Navigate to the CodeBuild console.
  • Select my-pipeline-app-build.
  • Click Delete build project. Confirm the deletion.

Delete the S3 artifact bucket:

  • Navigate to the S3 console.
  • Find the bucket starting with codepipeline-us-east-1- followed by a random number.
  • Select the bucket, click Empty, and confirm. You must empty the bucket before deleting it.
  • Select the bucket again, click Delete, and confirm by typing the bucket name.

Delete the IAM service roles:

  • Navigate to the IAM console and select Roles from the left sidebar.
  • Search for roles containing my-pipeline-app or codepipeline.
  • Select each role created for this project, click Delete, and confirm by typing the role name.

Delete local project files:

  • Delete the local project folder by running this command in your terminal:
rm -rf ~/Desktop/my-pipeline-app

On Windows, use:

Remove-Item -Recurse -Force ~\Desktop\my-pipeline-app

That's a Wrap!

That's a Wrap!

Nice work! You just built a fully automated CI/CD pipeline on AWS that takes your code from a GitHub push all the way to a live web application.

Here's what you learned:

  • Created a Node.js web application with a buildspec.yml that defines how AWS CodeBuild installs dependencies and packages your app for deployment.
  • Deployed your app to AWS Elastic Beanstalk and accessed it at a live URL on the internet.
  • Connected GitHub, CodeBuild, and CodePipeline into an automated delivery workflow that builds, tests, and deploys your app every time you push code.
  • Added a manual approval stage to your pipeline so deployments require human sign-off before reaching production.

Ready to quiz yourself?