RizTech Academy logo
RizTech Academy
Deployment PipelinesLesson 1 of 530 min

Designing a deployment pipeline

You know CI/CD from the DevOps Foundation — the pipeline from commit to running software, with a gate on failure. This module applies it to AWS: building images, storing them in ECR, deploying to EKS, rolling back, and handling secrets. This first lesson is designing the pipeline as a whole — the stages, the environments, and the AWS-specific shape — so the lessons that follow slot into a clear picture. It builds directly on the Foundation's CI/CD module.

The pipeline, end to end on AWS

A deployment pipeline for an AWS workload has the same shape as any CI/CD pipeline (the Foundation), with AWS-specific stages:

  1. Trigger — a push to a branch or a pull request.
  2. Build and test — install, run the tests, and build the container image (the Foundation's CI). A failure here stops the pipeline (the gate).
  3. Build and push the image to ECR — tag the image (by commit SHA — the Foundation) and push it to Amazon ECR, your private container registry (the next lesson), so the cluster can pull it.
  4. Deploy to a lower environment (staging) — update the workload on EKS to the new image (the deploying lesson), and verify it.
  5. Deploy to production — after staging is verified, deploy to production, gated by a manual approval.
  6. Verify and be ready to roll back — confirm the deploy succeeded, and have a fast rollback ready (the rollback lesson).

So on AWS the pipeline is: test → build image → push to ECR → deploy to staging → (approve) → deploy to production → verify. Each stage gates the next; nothing reaches production untested and unapproved. This is the Foundation's pipeline, made concrete for containers on AWS.

Keyless access: OIDC, not stored keys

The most important AWS-specific pipeline concern is how the pipeline authenticates to AWS — and the answer, from the foundations module, is not a stored access key. A pipeline needs permission to push to ECR and deploy to EKS, and storing a long-lived AWS key as a CI secret is exactly the leak risk you are avoiding.

Instead, the pipeline uses OIDC federation (the access-patterns lesson): GitHub Actions presents a signed token, AWS trusts GitHub as an identity provider, and the workflow assumes an IAM role to get temporary credentials — no stored key.

permissions:
  id-token: write        # allow the workflow to request an OIDC token
  contents: read
# ...
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-deploy
          aws-region: eu-west-1
      # the job now has temporary AWS credentials, scoped to what the deploy role allows

The deploy role is least privilege (the IAM lesson): it can push to the specific ECR repository and update the specific EKS deployment — not administer the account. So even if the pipeline is compromised, the blast radius is bounded. Keyless, least-privilege pipeline access is the foundation of a secure AWS pipeline, and every stage below assumes it.

Environments and gates

The pipeline enforces the safe-promotion discipline from the Terraform-environments lesson, for application deploys:

  • Deploy to staging automatically after tests pass — so every merged change reaches a production-like environment and is verified there.
  • Gate production with a manual approval — using GitHub environments (the Foundation's deploy lesson), production deploy requires a human to approve, so a person confirms the release. This is the difference between continuous delivery (approved) and deployment (automatic); most teams gate production.
  • Separate the deploy roles per environment — the pipeline assumes a staging deploy role for staging and a production deploy role for production, each least-privilege and scoped to its environment. So the staging stage cannot touch production, even by mistake — the isolation is enforced by IAM, not discipline.

This gives you a pipeline that tests everything, deploys to staging automatically, and reaches production only through a reviewed, approved, separately-permissioned path.

Application deploys vs infrastructure deploys

A design clarification worth making: there are really two kinds of pipeline on AWS, and they are usually separate:

  • The application pipeline — builds and deploys your code (the container image to EKS/ECS). This runs often (every merge), and is what this module focuses on.
  • The infrastructure pipeline — applies your Terraform (the Terraform module): terraform plan on a PR, terraform apply on merge, gated for production. This runs when infrastructure changes, less often.

Keeping them separate is sensible: application deploys are frequent and fast; infrastructure changes are rarer and higher-stakes (a bad terraform apply can affect the whole environment). They use the same principles — keyless OIDC access, plan/review, staging before production, production gated — but as distinct pipelines with distinct permissions. Knowing there are two, with different cadences and blast radii, keeps you from tangling "deploy my app" with "change the cluster."

The overall design to hold: a keyless (OIDC), least-privilege pipeline that tests, builds and pushes an image to ECR, deploys to staging automatically and to production behind an approval gate, with rollback ready and infrastructure changes on a separate pipeline. The rest of the module fills in each stage.

Check your work

Pipeline shape on AWS: trigger → build + test (gate) → build + push image to ECR → deploy to staging (verify) → deploy to production (manual approval) → verify + rollback-ready. Foundation's pipeline, made concrete for AWS containers; each stage gates the next.

Keyless access (key AWS concern): don't store an AWS key as a CI secret; use OIDC — the workflow assumes an IAM deploy role (configure-aws-credentials with role-to-assume, id-token: write) for temporary, least-privilege credentials (push to the specific ECR repo, update the specific EKS deployment — not admin). Bounds blast radius if compromised.

Environments/gates: deploy to staging automatically; gate production with a manual approval (GitHub environments); separate deploy roles per environment (staging role can't touch prod — IAM-enforced, not discipline).

Two pipelines: the application pipeline (image → EKS/ECS, frequent — this module) vs the infrastructure pipeline (Terraform plan/apply, rarer, higher-stakes). Keep them separate — same principles, distinct permissions and cadences.

Practice

  1. Lay out the stages of an AWS deployment pipeline from trigger to production, and what gates each.
  2. Explain how the pipeline authenticates to AWS without a stored key, and why that matters.
  3. Explain how the deploy role should be scoped (least privilege) and what that bounds if the pipeline is compromised.
  4. Explain how staging and production are gated and separated, and why separate roles per environment matter.
  5. Distinguish the application pipeline from the infrastructure pipeline and why they are kept separate.
  6. Describe what "continuous delivery vs deployment" means for the production stage of this pipeline.

Official documentation

Next: building and storing images in ECR.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship