Continuous Delivery to AWS, Azure, Google Cloud, and Kubernetes: Core Concepts and Mental Model
Model deployment as promotion of a verified artifact through an explicit environment, identity, target, rollout, health, and rollback chain.
Learning objectives
- Explain why continuous delivery promotes an already verified artifact instead of rebuilding source inside a deployment job.
- Separate GitHub environment authorization, cloud identity, provider/cluster target, rollout state, health state and rollback state.
- Trace the same provider-neutral delivery contract through AWS, Azure, Google Cloud and Kubernetes adapters.
- Identify which evidence proves source identity, artifact identity, deployment identity and external health independently.
- Inspect deployment-relevant state read-only before granting write authority or changing a target.
1. The delivery problem starts after release evidence exists
Chapter 25 ended with a release chain that linked an exact source SHA to exact artifact bytes. Continuous delivery begins from that verified subject. The deployment job should not silently run another build and hope the new bytes are equivalent. Its task is to authorize, authenticate, promote, observe and—if necessary—recover the same artifact identity.
Cloud providers and Kubernetes expose different APIs, but the GitHub Actions integration problem is remarkably consistent: prove the artifact, prove the job identity, prove the intended target, perform a bounded rollout, then prove target health. A green workflow job is not itself proof that users are receiving the intended revision.
2. Mental model: verified subject → governed identity → target rollout → health
Read the model as a chain of gates. The artifact digest enters delivery as immutable evidence. The deployment job references an environment, which may impose approval and branch/tag rules. Only that job receives the federated or narrowly scoped target credential. The adapter then calls the provider or Kubernetes API, receives a deployment/revision handle, waits for rollout, and verifies health before recording success.
flowchart TD A[Verified artifact + digest] --> B[Deployment job] B --> C[GitHub environment / approval] C --> D[OIDC or narrow target credential] D --> E[Provider API or Kubernetes API] E --> F[Deployment / rollout revision] F --> G[Health verification] G --> H[Deployment evidence + target state] G --> I[Failure evidence] I --> J[Rollback to known-good identity]
Every arrow crosses a state boundary. Artifact verification does not authorize deployment. Environment approval does not authenticate to AWS, Azure or Google Cloud. OIDC token minting does not grant a cloud role unless the provider trust policy accepts the claims. A successful API response does not prove the rollout is healthy.
3. Define the state before changing it
| Layer | Record before/after | What it proves |
|---|---|---|
| Event/revision | event, ref, source SHA, workflow path/SHA, run ID and attempt | Which GitHub revision requested delivery. |
| Artifact | name/version, SHA-256 or OCI digest, provenance/attestation result | Which exact bytes are eligible for promotion. |
| Environment | environment name/URL, protection rules, approval state, concurrency group | Which governed deployment boundary the job requested. |
| Identity |
id-token: write only where needed;
issuer/audience/subject; provider role/service account
|
Which workflow identity the provider is allowed to exchange for temporary credentials. |
| Target | AWS account/region/service, Azure subscription/resource, GCP project/resource, or Kubernetes context/namespace | Where the mutation is supposed to occur. |
| Rollout | provider deployment ID/revision or Kubernetes deployment revision | Which target-side change was requested. |
| Health | provider health status, endpoint response, Kubernetes ready replicas/probes | Whether the new target state actually serves correctly. |
| Recovery | previous known-good digest/revision and rollback handle | How to reverse the target without rebuilding. |
4. Inspection first: prove identity and target without mutation
Before a deploy step, print bounded non-secret metadata and use
read-only identity commands. For Kubernetes,
kubectl config current-context,
kubectl cluster-info, namespace inspection and the
current Deployment image are target proofs. For cloud sandboxes,
aws sts get-caller-identity,
az account show and
gcloud config get-value project are examples of
read-only account/project confirmation after authentication.
set -euo pipefail
printf 'run=%s attempt=%s sha=%s ref=%s
' "$GITHUB_RUN_ID" "$GITHUB_RUN_ATTEMPT" "$GITHUB_SHA" "$GITHUB_REF"
sha256sum dist/release-subject.bin
kubectl config current-context
kubectl cluster-info
kubectl get namespace lab-delivery -o name 2>/dev/null || true
Do not inspect identity by printing credentials or raw OIDC tokens. Prove who the provider thinks you are with non-secret identity APIs and record bounded OIDC claims only when the lab intentionally uses a synthetic token/claim fixture.
5. One contract, four adapters
| Adapter | Authentication boundary | Typical deployment call | Independent verification |
|---|---|---|---|
| AWS | GitHub OIDC → IAM role via STS | AWS service API/CLI such as ECS/EKS/Lambda tooling | account/ARN, region, deployment/task revision, service health |
| Azure | GitHub OIDC → Entra federated credential → Azure token | Azure CLI/API or service-specific deployment action | subscription/tenant, resource ID, deployment state, endpoint health |
| Google Cloud | GitHub OIDC → Workload Identity Federation → service identity | gcloud/API or GKE/Cloud Run tooling | project/account, resource revision, traffic/health state |
| Kubernetes | kubeconfig/executive credential or cloud-federated cluster identity |
kubectl apply/set image or GitOps handoff
|
context/cluster UID, namespace, rollout revision, ready replicas/probe |
6. OIDC grants token minting, not provider authorization
The deployment job normally needs id-token: write only
when it will federate to a provider. That permission lets the job
request a GitHub OIDC token; it does not give AWS, Azure or Google
Cloud rights by itself. The provider trust relationship must accept
the actual issuer, audience and subject/claims, then the resulting
role or service account still needs its own least-privilege resource
permissions.
As of September 10, 2026, repositories created after July 15, 2026 use the immutable default OIDC subject form with owner and repository IDs; older repositories keep the legacy name-only form unless migrated. An environment-scoped job also changes the subject context. Production trust policies must therefore match the actual current token format, not a copied tutorial string.
7. Environment approval is a governance gate, not deployment success
A job that references environment: production may wait
for required reviewers, branch/tag restrictions, wait timers or
custom protection rules depending on repository visibility and plan.
Environment secrets are not available until the job is allowed to
start under the environment rules. Once approved, the provider can
still reject OIDC, the rollout can still fail, and the application
can still be unhealthy.
Use target-specific concurrency such as
deploy-production rather than one global group that
serializes unrelated staging and production systems. Concurrency
controls overlap; it does not prove the previous deployment
completed successfully or that the new artifact is safe.
8. Evidence must link GitHub state to external state
| Evidence | Example | Do not confuse with |
|---|---|---|
| Source evidence |
GITHUB_SHA, workflow revision, run/attempt
|
artifact digest |
| Artifact evidence | SHA-256/OCI digest + provenance | environment approval |
| Authorization evidence | environment approval/protection state | cloud identity |
| Identity evidence | provider principal/account/project returned by read-only API | resource authorization |
| Deployment evidence | provider deployment ID or Kubernetes revision | health |
| Health evidence | ready replicas, service endpoint, provider health | job conclusion |
| Rollback evidence | previous digest/revision restored and health rechecked | deleting the failed run |
9. Common wrong model: “deploy latest from main”
A workflow that checks out main, rebuilds, logs into a
cloud account with a permanent admin key and deploys
image:latest collapses four independent identities into
mutable aliases. A later commit, tag move, base-image update or
registry retag can change the bytes without changing the workflow
text. Recovery then becomes guesswork.
The production pattern is the opposite: immutable artifact identity in, bounded target identity, short-lived deployment identity, exact rollout record out. Human-friendly aliases may exist for discovery, but the evidence packet retains the digest and target-side revision.
10. DevOps connection: promotion preserves evidence across boundaries
Delivery is not “CI plus credentials.” It is the operational handoff between verified software and a stateful external system. The same discipline used for source SHA, pinned actions, artifacts and attestations now extends to cloud account/project/subscription/cluster identity, rollout revisions and health. This is what makes a deployment independently auditable and safely repeatable.
11. Lesson summary
Continuous delivery should preserve one artifact identity while changing only authorized target state. Environments govern entry, OIDC or narrow credentials establish caller identity, provider/cluster APIs create rollout state, and health/rollback evidence closes the loop.
Knowledge check
Does id-token: write grant permission to change an
AWS resource?
No. It only permits requesting a GitHub OIDC token. AWS trust and IAM permissions determine whether the external mutation is allowed.
Why is environment approval not proof of successful deployment?
Approval authorizes the job to proceed; provider authentication, API mutation, rollout and health are later independent states.
What should a deployment job receive from the release stage?
An exact verified artifact identity such as a SHA-256 or OCI digest, plus provenance/version metadata—not an instruction to rebuild from a mutable branch.
Which Kubernetes command is a useful read-only guard before mutation?
kubectl config current-context together with
cluster/namespace identity inspection, because it helps prove
the target before applying changes.
Why retain a provider deployment ID or Kubernetes revision after success?
It links the GitHub run to target-side state and supplies an observable rollback/audit handle.
Official references and version notes
- GitHub OIDC overview — Why short-lived federation is preferred to long-lived cloud secrets.
- OIDC reference — Current claims, immutable subject format, audiences, reusable-workflow behavior and token-request permissions.
- OIDC in AWS — Current AWS trust conditions and official authentication action pattern.
- OIDC in Azure — Current Microsoft Entra workload identity federation pattern.
- OIDC in Google Cloud — Current Workload Identity Federation integration.
- Managing environments — Environment protection, deployment branches/tags, secrets and target governance.
- Deployments and environments — Conceptual distinction between deployment records, environment gates and external target health.
- kind quick start — Pinned local Kubernetes cluster tool used by the free lab.
- kind local registry — Current localhost registry/network model when digest-addressable local images are needed.
- Kubernetes Deployments — Rollout, revision and rollback model.
- kubectl rollout — Status, history, undo and restart operations.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.