How CodePipeline stages, CodeBuild, CodeDeploy and GitHub Actions fit together for a backend on AWS, when each piece earns its keep, and how to keep tests in CI while application infrastructure comes from code.
AWS CI/CD is the path from a commit to a running backend: build, test, then deploy into ECS, Lambda or EC2. The AWS-native stack is CodePipeline for orchestration, CodeBuild for builds and tests, and CodeDeploy for rollouts. A large share of teams instead keep the workflow in GitHub Actions and only use AWS for the deploy target.
This guide maps those pieces, when each fits, and where Encore (infrastructure from code) removes the application-infra half of the pipeline while leaving test CI where it already works.
CodePipeline models a release as ordered stages. A source stage pulls from CodeCommit, S3 or a GitHub connection. Later stages run build, test or deploy actions. Executions can run in SUPERSEDED, QUEUED or PARALLEL mode, and a locked stage processes one execution at a time, as described in the pipeline execution guide.
CodeBuild is the managed build service. You point it at a buildspec, pick a compute image, and it scales build capacity for you. You pay for build minutes. Teams use it as a CodePipeline action or as a standalone project triggered from GitHub.
CodeDeploy updates running compute. On EC2 or on-premises it can do in-place or blue/green deployments. On Lambda and ECS every deployment is blue/green, with canary, linear or all-at-once traffic shifting. The AppSpec file tells CodeDeploy which Lambda version or ECS task set to move traffic to.
A minimal AWS-native path for an ECS service is: GitHub or CodeCommit → CodeBuild (image to ECR) → CodeDeploy or an ECS deploy action → Fargate tasks behind a load balancer. Terraform or CDK usually owns the pipeline, roles, cluster and task definition next to that flow.
For a backend team already on GitHub, the workflow file becomes the pipeline. A typical pattern is: run tests on every pull request, then on merge assume an IAM role with OIDC, build a container, push to ECR and update an ECS service or Lambda function. Long-lived access keys never enter the repo.
GitHub Actions fits when you want matrix builds, reusable workflows and review of the pipeline as code in the same PR as the app. CodePipeline fits when compliance or ops wants the release graph inside AWS, next to CloudWatch alarms and approval actions that call IAM principals in the account. CodeBuild still shows up in both worlds as the place that compiles Go or Node with a consistent image.
A common split for product backends in 2026 is GitHub Actions for CI, AWS for the runtime, and Terraform or CDK for the queues, databases, IAM roles and deploy stages around each service.
The first service needs a build project, a task definition, a target group, an execution role and a deploy stage, and the second service copies most of that. Every new queue or bucket adds policy statements the deploy role must carry, and local development drifts from what the pipeline creates. AI coding agents can emit more of that YAML, but the review cost stays on the team: the infra still lives outside the handlers that need it.
Encore combines an open source infrastructure SDK for TypeScript and Go with a platform that provisions and deploys into your own AWS or GCP account. You declare services, APIs, queues, cron jobs and secrets in application code. A push to the branch configured for an environment runs build, test, infrastructure provisioning and deploy, as covered in the deploying docs.

Run in your terminal to get started locally.
A checkout service with an API, a queue worker and a nightly cleanup job is ordinary TypeScript. There is no task definition, CodeDeploy AppSpec or deploy-stage Terraform next to it:
// checkout/encore.service.ts
import { Service } from "encore.dev/service";
export default new Service("checkout");
// checkout/checkout.ts
import { api } from "encore.dev/api";
import { Topic, Subscription } from "encore.dev/pubsub";
import { CronJob } from "encore.dev/cron";
import log from "encore.dev/log";
interface OrderPaid {
orderId: string;
}
export const orderPaid = new Topic<OrderPaid>("order-paid", {
deliveryGuarantee: "at-least-once",
});
export const pay = api(
{ expose: true, method: "POST", path: "/checkout/pay" },
async ({ orderId }: { orderId: string }): Promise<{ ok: boolean }> => {
await orderPaid.publish({ orderId });
return { ok: true };
},
);
const _ = new Subscription(orderPaid, "fulfill-order", {
handler: async (e) => {
log.info("fulfilling order", { orderId: e.orderId });
},
});
export const expireAbandoned = api({}, async (): Promise<void> => {
log.info("expiring abandoned checkouts");
});
const cleanupJob = new CronJob("checkout-cleanup", {
title: "Expire abandoned checkouts",
every: "1h",
endpoint: expireAbandoned,
});
encore run starts the API and delivers Pub/Sub locally, as covered in the TypeScript Pub/Sub docs. Cron jobs do not run locally; call expireAbandoned by hand when you need to test it, per the cron docs. On deploy to AWS, Encore creates the Fargate services, the SNS topic and SQS queue with a dead-letter queue, schedules the cron trigger, and provisions an IAM role for the service. Secrets the code needs are set with encore secret set --type prod and land in AWS Secrets Manager, per the secrets docs.
That replaces the application-level pipeline: task definitions, deploy stages and the Terraform that wires queues and roles to each service, while test decisions stay with you. Keep GitHub Actions or CodeBuild for lint, unit tests and any checks you want before merge. Point those workflows at the repo as usual; Encore's deploy still runs on the configured branch push after review.
An AI coding agent adding a second subscription edits the same file, and the next push provisions the new queue consumer in the account.
Best fit: Teams who want git-push deploys of TypeScript or Go backends into their own AWS account, with PR checks kept in GitHub Actions or CodeBuild.
Pick Encore when the expensive part of CI/CD is no longer the test runner, but the growing deploy and infra pipeline around every service. Keep CodePipeline or Actions when you need a custom promotion path across accounts that Encore does not model.
AWS CI/CD usually means a pipeline that builds, tests and deploys on every change. On AWS that often uses CodePipeline to orchestrate stages, CodeBuild to compile and run tests, and CodeDeploy or an ECS/Lambda action to roll out. Another common setup runs GitHub Actions for build and test, then deploys into AWS with OIDC.
Use CodePipeline when you want the release workflow to live next to other AWS resources and IAM. Use GitHub Actions when the source of truth is already GitHub and you want reusable workflows, matrix builds and marketplace actions. Both can call CodeBuild, and both can deploy to ECS, Lambda or EC2.
CodeBuild is the build and test runner: it starts a managed build environment, runs your buildspec and produces artifacts. CodeDeploy is the rollout service: it updates EC2 instances, ECS services or Lambda versions with in-place or blue/green traffic shifts.
With Encore, connect your AWS account, push to the branch that triggers an environment, and Encore builds, provisions application infrastructure such as Fargate services, load balancer targets, queues and secrets, and deploys. Keep unit and integration tests in GitHub Actions or CodeBuild if you want a separate CI gate before merge.
Deploy to your cloud on AWS and Google Cloud
without managing infrastructure
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.