CI/CD with AWS CodePipeline

Build a pipeline that auto-deploys your web app on every GitHub push.

Introduction

30 Second Summary

Imagine pushing a code change and then manually building, packaging, and deploying it to your server. Every handoff is a chance for something to slip through the cracks or get forgotten entirely.

In this project, you will build a fully automated CI/CD pipeline using AWS CodePipeline that detects your code pushes, builds your application, and deploys it to a live server. No manual steps required.

What You'll Build

Push a one-line code change to GitHub and watch it flow through three automated stages, landing on a live web server within minutes.

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

  • A hands-free deployment flow where you push code to GitHub and see it appear on your live web app within minutes. No clicking through consoles to trigger builds or copy artifacts.
  • Real-time pipeline visibility showing each stage (Source, Build, Deploy) progress from grey to blue to green in the CodePipeline console.
  • Secret Mission: A manual approval gate with SNS notifications that pauses your pipeline before deployment until you explicitly sign off.

Are there any prerequisites?

This project is Day 6 of the 6 Day DevOps Challenge. You need a working setup from Days 1-5, including your EC2 dev instance, GitHub repo, CodeBuild project, CodeDeploy application, and S3 artifact bucket.

Before We Start

Before we dive in, let's lock in what you're about to build and why it matters. You've spent five days building individual DevOps tools. Now you'll connect them into a single automated pipeline.

Verify Your Existing Resources

Your CI/CD pipeline will depend on every resource from Days 1-5 working together in harmony. CodePipeline connects your GitHub repo, CodeBuild project, and CodeDeploy deployment group into one automated flow.

A single misconfigured or stopped resource will cause a cryptic failure later. Let's catch any problems now, before we wire everything together.

In this step, get ready to:
  • Confirm your EC2 instances are running.
  • Run a test build in CodeBuild to verify it succeeds.
  • Verify your GitHub connection is active.
Confirm your deployment infrastructure is running

Your pipeline will deploy code to your deployment EC2 instance and your development instance is where you push code from. Both need to be running.

  • Sign in to the AWS Management Console with your IAM Admin user.
  • Make sure your region is set to us-east-1 (N. Virginia) in the top-right corner of the console.
  • In the search bar at the top, type EC2 and select EC2 from the results.
  • In the left navigation pane, click Instances.
  • Locate your deployment EC2 instance (launched by your CloudFormation stack, with the tag role: webserver).
  • Confirm its Instance state column shows Running.
  • Locate your development EC2 instance (named nextwork-devops-yourname).
  • Confirm it is also in a Running state.

You should see both instances with a green "Running" status in the Instance state column.

Instance is stopped?

If either instance shows Stopped, select it by checking the box, then click Instance state > Start instance. Wait a minute or two for it to transition to Running.

If your development instance was stopped, reconnect to it via VS Code Remote - SSH once it is running again.

help me reconnect to my development EC2 instance via VS Code Remote - SSH

Confirm CodeBuild can still build your project

CodeBuild is the service that compiles your source code and produces a deployable artifact. Let's run a test build to make sure it still works end-to-end.

  • In the AWS console search bar, type CodeBuild and select CodeBuild from the results.
  • In the left navigation pane, click Build projects.
  • Click on your nextwork-devops-cicd project name.
  • Click Start build to trigger a manual build with default settings.

Before you check the results, what do you expect will happen? If your source code and buildspec are unchanged from Day 4, the build should complete successfully.

  • Wait for the build to finish. This typically takes 2-5 minutes. Refresh the page if you see In Progress.
  • Confirm the Build Status shows Succeeded.

You should see Succeeded displayed in the Build Status section, confirming your project builds correctly.

  • Now confirm the artifact was uploaded. Navigate to your S3 artifact bucket (search S3 in the console search bar, then open your build artifact bucket).
  • Verify you see a build artifact file from this most recent build.

Build failed?

Click on the failed build run to view the error details in the build logs. A common cause is your CodeBuild service role missing permissions to access your source repository through the CodeConnection.

If you see a permissions error related to your connection, navigate to IAM > Roles, find your CodeBuild service role, and attach the AWSCodeStarConnectionsFullAccess policy. Then retry the build.

help me debug my CodeBuild failure

Confirm your GitHub connection is active

CodePipeline uses your GitHub connection to detect new code pushes. If this connection is inactive, the pipeline will never trigger.

  • In the AWS console search bar, type CodePipeline and select CodePipeline from the results.
  • In the left navigation pane, expand Settings and click Connections.
  • Locate your GitHub connection in the list.
  • Confirm its Status column shows Available.

You should see your connection listed with a green Available status. This confirms GitHub is properly linked to your AWS account.

Connection shows Pending or Error?

If the status is not Available, click on the connection name and choose Update pending connection. Follow the prompts to re-authorize with GitHub. You may need to sign into GitHub and confirm the app installation.

help me fix my GitHub connection in AWS Developer Tools

Why verify before building the pipeline?

CodePipeline orchestrates CodeBuild, CodeDeploy, and your GitHub connection together. If any one piece is broken, the pipeline will fail at that stage with a generic error that does not point you back to the root cause.

Verifying each piece individually now means you can confidently blame the pipeline configuration (not a pre-existing resource issue) if something goes wrong in the next step.

All three checks passed. Your infrastructure is healthy and ready for automation. Next up, you'll create your CI/CD pipeline and watch all these pieces work together hands-free.

Create Your Pipeline

In Step 1, you confirmed that every piece of your DevOps toolchain is healthy and ready. Now it is time to connect them into a single automated workflow.

Right now, building and deploying are separate manual actions. You have to trigger CodeBuild by hand, wait for it to finish, then kick off CodeDeploy separately. CodePipeline wires all three stages together so a single code push triggers the entire flow automatically. This is where all your Day 1-5 work pays off.

In this step, get ready to:
  • Create a CodePipeline pipeline with Source, Build, and Deploy stages.
  • Connect the pipeline to your existing GitHub repository, CodeBuild project, and CodeDeploy application.
  • Watch the pipeline execute its first run and confirm all three stages succeed.
Set up the pipeline and Source stage
  • Open the CodePipeline console by navigating to http://console.aws.amazon.com/codesuite/codepipeline/home in your browser.
  • Click Create pipeline.
  • On the Step 1: Choose creation option page, under Creation options, select Build custom pipeline.
  • Click Next.
  • On the Step 2: Choose pipeline settings page, in Pipeline name, enter nextwork-devops-cicd.
  • Under Service role, select New service role.
  • Leave the settings under Advanced settings at their defaults.
  • Click Next.

What is the service role?

CodePipeline needs permissions to pull code from GitHub, trigger CodeBuild, and start CodeDeploy deployments on your behalf.

By selecting New service role, you let AWS create an IAM role with the right permissions automatically.

Now you will configure where CodePipeline pulls your source code from.

  • On the Step 3: Add source stage page, select GitHub (via GitHub App) as the Source provider.
  • Under Connection, select your existing GitHub connection.
  • Under Repository name, select your nextwork-web-project repository.
  • Under Default branch, select master.
  • Confirm that Webhook events is checked under Detect changes.
  • Leave Output artifact format as CodePipeline default.
  • Click Next.

What does webhook-based detection do?

With Webhook events enabled, GitHub sends a notification to CodePipeline every time you push code to the master branch. This means the pipeline starts within seconds of a push, with no polling delay.

Configure the Build and Deploy stages
  • On the Step 4: Add build stage page, select AWS CodeBuild as the Build provider.
  • Under Project name, select your existing nextwork-devops-cicd CodeBuild project.
  • Click Next.
  • On the Step 5: Add test stage page, click Skip test stage.
  • Confirm by clicking Skip in the warning dialog.

Why skip the test stage?

This project focuses on the core CI/CD flow: source, build, and deploy. Adding automated tests is a great next step, but right now the goal is to get the end-to-end pipeline working first.

  • Click Next.
  • On the Step 6: Add deploy stage page, select AWS CodeDeploy as the Deploy provider.
  • Under Application name, select your existing nextwork-devops-cicd application.
  • Under Deployment group, select your existing deployment group.
  • Click Next.
  • On the Step 7: Review page, review all your stage configurations.
  • Click Create pipeline.
Watch the first pipeline execution

After clicking Create pipeline, CodePipeline takes you directly to a pipeline view. Before you look at the diagram, what do you expect to see?

Will the pipeline sit idle and wait for a push, or will something happen right away?

The pipeline immediately starts its first execution. Watch the pipeline diagram as stages transition from grey to blue (in progress) to green (succeeded).

  • Wait for all three stages (Source, Build, Deploy) to turn green.
  • If a stage turns red, click on the failed stage to view error details.

Build stage failing?

A common issue is the CodeBuild service role missing the permission to use your GitHub connection. If the Build stage fails with a connection-related error, fix it by following these steps:

  • Open the IAM console.
  • Find your CodeBuild service role (the one used by your nextwork-devops-cicd build project).
  • Attach the AWSCodeStarConnectionsFullAccess policy to that role.
  • Return to the CodePipeline console and click Retry stage on the failed Build stage.

Help me troubleshoot my Build stage failure

Once all three stages show green, your pipeline is fully functional. Every piece you built across Days 1-5 is now connected into a single automated delivery workflow.

Your pipeline is live and proven. Next up, you will push a real code change and watch the entire flow trigger automatically, from commit to live deployment.

Test Continuous Delivery with a Code Change

Your pipeline is live. In the previous step, you created it and watched all three stages turn green on the first execution. But that initial run was triggered by the pipeline's creation itself.

The real test of continuous delivery is whether your pipeline reacts automatically to a new code push. Let's push a change to GitHub and see if it flows through Source, Build, and Deploy without you lifting a finger.

In this step, get ready to:
  • Make a code change and push it to GitHub.
  • Watch the pipeline detect and process the change automatically.
  • Verify the updated code is live on your deployment instance.
Make a code change and push it

To prove the pipeline works end-to-end, you need a real code change that produces a visible result on the deployed web app.

  • In VS Code (connected to your development EC2 instance), open the file src/main/webapp/index.jsp.
  • Find the <body> section of the file.
  • Add the following line inside the <body> section:
<p>Deployed automatically by CodePipeline!</p>
  • Save the file.

Now commit and push the change to trigger the pipeline.

  • Stage, commit, and push your change by running these commands in the VS Code terminal:
git add .
git commit -m "Test CodePipeline automatic deployment"
git push origin master

What do these commands do?

  • git add . stages all changed files for the next commit.
  • git commit -m "..." saves a snapshot of your changes with a descriptive message.
  • git push origin master uploads your commit to the master branch on GitHub. This is the event that triggers your pipeline's webhook.
  • Confirm the push succeeds. You should see output ending with a line like master -> master.

Push rejected or authentication failed?

  • If you see a permission error, make sure your Git credentials are configured on the development EC2 instance. You set these up in a previous day of the challenge.
  • If the push is rejected because of a non-fast-forward, run git pull origin master first, then try pushing again.
  • Help me debug my git push failure.
Watch the pipeline react automatically

The webhook you configured during pipeline creation tells CodePipeline to start a new execution whenever it detects a push to your master branch.

  • Switch back to the CodePipeline console in your browser.
  • Click on your nextwork-devops-cicd pipeline if you are not already viewing it.
  • Within a minute or two, you should see a new execution start in the Source stage. The stage turns blue (in progress).
  • Click View details on the Source action to see the commit message from your push.
  • Watch the Build stage turn blue as CodeBuild compiles your updated code.
  • Watch the Deploy stage turn blue as CodeDeploy pushes the new artifact to your EC2 instance.
  • Wait for all three stages to turn green (Succeeded).

What do the stage colours mean?

  • Grey: no executions yet.
  • Blue: in progress.
  • Green: succeeded.
  • Red: failed.

Pipeline not starting automatically?

  • Give it up to two minutes. Webhook delivery is not always instant.
  • If nothing starts after two minutes, confirm your push actually reached GitHub by checking the commit on your repository page.
  • Verify your GitHub connection still shows Available under Developer Tools > Settings > Connections.
  • Help me figure out why my pipeline did not start after I pushed code.
Verify the live deployment

All three stages are green. Your updated code has been built and deployed. Now confirm the change is actually live on your web app.

  • In the CodePipeline console, click on the Deploy stage.
  • Click the CodeDeploy link in the details panel to open the deployment.
  • In CodeDeploy, scroll down to Deployment lifecycle events and click the Instance ID.
  • On the EC2 instance summary page, copy the Public IPv4 DNS value.

Before you open this URL, what do you expect to see on the page? Think about what line you added to the file.

  • Paste the DNS into a new browser tab and press Enter.

You should see your web app with the new line: "Deployed automatically by CodePipeline!" visible on the page. You pushed code to GitHub and it appeared on a live server without a single manual deployment step.

Page not showing the update?

  • Try a hard refresh in your browser (Cmd+Shift+R on macOS, Ctrl+Shift+R on Windows) to clear cached content.
  • Make sure all three pipeline stages show green. If the Deploy stage is red, click into it for error details.
  • Confirm you are using the deployment EC2 instance's DNS (the one from the CloudFormation stack), not the development instance's DNS.
  • Help me troubleshoot my CodeDeploy deployment.

Your pipeline just proved it can deliver changes continuously. Every future push to master will flow through the same automated path. Next up, you will add a safety gate that pauses the pipeline before deployment, giving a human the final say.

Secret mission

Add a Manual Approval Gate

Your pipeline just deployed a change to production with zero human oversight. In a real team, that is terrifying. Can you add a safety gate that pauses the pipeline and notifies an approver before code reaches your live server?

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. Your CodePipeline is a V2 type that charges per action execution minute, but you get 100 free minutes per month and manual approval actions are not charged.

Cost warning

While the pipeline itself has no idle cost (V2 only charges when actions execute), your EC2 instances will continue to accrue charges if left running. If you are done with this project, stop or terminate your EC2 instances to avoid ongoing compute charges.

Resources you used:

  • CodePipeline pipeline (nextwork-devops-cicd) with four stages: Source, Build, Review, Deploy.
  • CodePipeline service role (IAM role auto-created during pipeline setup).
  • Pipeline artifact S3 bucket (auto-created by CodePipeline to store artifacts between stages).
  • Deployment EC2 instance (created by CloudFormation in a prior project).
  • Development EC2 instance (nextwork-devops-yourname).

Keep everything running

No action needed. Choose this if you are still actively building or plan to push more code changes and watch the pipeline react.

  • Your pipeline stays active and triggers on every push to master.
  • Within free tier limits (100 action execution minutes per month), pipeline executions cost nothing.
  • Your EC2 instances will continue to accrue charges while running. Stop them when you are not actively working.

Pause - I'll come back to this later

Shut down running processes to free up costs while keeping your pipeline and configuration intact.

  • Open the EC2 console and stop both your deployment instance and your development instance. Stopped instances do not incur compute charges.
  • The pipeline itself has no idle cost. V2 pipelines only charge per action execution minute, so a paused pipeline with stopped instances costs nothing.
  • When you return, start your EC2 instances again and push a new commit to trigger the pipeline.

Delete - I don't want to use this again

Remove all project resources created in this project and start fresh. Follow each step below in order.

  • Delete the CodePipeline pipeline: open the CodePipeline console, choose your pipeline name (nextwork-devops-cicd), click Edit, then click Delete. Type delete in the confirmation field and click Delete.
  • Delete the pipeline artifact S3 bucket: open the S3 console, choose General purpose buckets in the left navigation pane, select the pipeline artifact bucket, click Empty, enter the bucket name to confirm, and click Empty. Then select the same bucket again, click Delete, enter the bucket name, and click Delete bucket.
  • Delete the CodePipeline service role: open the IAM console, choose Roles in the navigation pane, select the checkbox next to the CodePipeline service role, click Delete at the top of the page, enter the role name to confirm, and click Delete.
  • For resources from Days 1-5 (EC2 instances, CodeBuild project, CodeDeploy application, CloudFormation stack, GitHub connection, SNS topic), refer to the cleanup checklist from those projects.

That's a Wrap!

That's a Wrap!

Nice work! You've just built a fully automated CI/CD pipeline using AWS CodePipeline that orchestrates your entire delivery workflow from code push to live deployment.

You've learned how to:

  • Built a fully automated CI/CD pipeline using AWS CodePipeline that orchestrates Source (GitHub), Build (CodeBuild), and Deploy (CodeDeploy) stages.
  • Tested continuous delivery by pushing a code change and watching it deploy automatically to a live EC2 instance.
  • Proved you can design, build, and operate an end-to-end automated delivery workflow using AWS developer tools.
  • Configured a manual approval gate between Build and Deploy that pauses the pipeline and sends an SNS notification until an approver signs off.

Ready to quiz yourself?