ЁЯПл The SchoolтА║ЁЯН▒ DockerтА║ЁЯУо рдзрдбрд╛ 12 тАФ CI рддреЗ cloud: courier рдкреНрд░рддреА рдареЗрд╡рддреЛ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯУо рдзрдбрд╛ 12 тАФ CI рддреЗ cloud: courier рдкреНрд░рддреА рдареЗрд╡рддреЛ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 12 тАФ рд╢реЗрд╡рдЯрдЪрд╛ рдзрдбрд╛! ┬╖ рдорд╛рдЧреЗ: lesson-11-push-pull-lifecycle

ЁЯФЧ рдкреБрдвреЗ: Kubernetes рд╣реА image ECR рд╡рд░реВрди pull рдХрд░рддреЗ тАФ Kubernetes рд╢рд╛рд│реЗрдЪрд╛ рдзрдбрд╛ 01 рдиреЗрдордХрд╛ рдЗрдереВрди рд╕реБрд░реВ рд╣реЛрддреЛ рдЬрд┐рдереЗ рд╣рд╛ рд╕рдВрдкрддреЛ.


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рд╕рдЧрд│реЗ 12 рдзрдбреЗ тАФ рд╕рдВрдкреВрд░реНрдг рдХреЛрд░реНрд╕. рд╢реЗрд╡рдЯрдЪрд╛ рднрд╛рдЧ: рдзрдбреЗ 1тАУ11 рдкреНрд░рддреНрдпреЗрдХ push рд╡рд░ рдХрд░рдгрд╛рд▒реНрдпрд╛ robot рдХрдбреЗ рд╕реЛрдкрд╡рдгреЗ, рд╕реЛрдмрдд scan report, рдЖрдгрд┐ рдЙрд░рд▓реЗрд▓реНрдпрд╛ trilogy рдХрдбреЗ baton рджреЗрдгреЗ.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рдХрд╛рд▓ рддреБрдореНрд╣реА рд╣рд╛рддрд╛рдиреЗ рдХрд╛рдп рдХреЗрд▓реЗ рддреЗ рдкрд╛рд╣рд╛: build ЁЯН▒ тЖТ рдкреВрд░реНрдг рдкрддреНрддреНрдпрд╛рдЪреЗ рд▓реЗрдмрд▓ ЁЯП╖я╕П тЖТ рджрд┐рд╡рд╕рд╛рдЪрд╛ рдкрд╛рд╕ ЁЯОл тЖТ push ЁЯУж. рдЪрд╛рд░ commands, рдкреНрд░рддреНрдпреЗрдХ deploy рд▓рд╛, рдХрд╛рдпрдо? рдирд╛рд╣реА. рд╣реЗ рдХрд╛рдо courier robot ЁЯУо (CI) рдЪреЗ рдЖрд╣реЗ:

рдкреНрд░рддреНрдпреЗрдХ git push рд╡рд░ robot:

  1. рдЧреГрд╣рдкрд╛рда рддрдкрд╛рд╕рддреЛ тЬЕ тАФ tests рдЪрд╛рд▓рд╡рддреЛ. рдЦрд░рд╛рдм рдХреЛрдб рдХрдзреАрдЪ рдбрдмреНрдпрд╛рдд рдЬрд╛рдд рдирд╛рд╣реА.
  2. рдбрдмрд╛ рднрд╛рдЬрддреЛ ЁЯН▒ тАФ docker build, рдзрдбрд╛ 02 рдореБрд│реЗ cache-рдЬрд▓рдж.
  3. рддреНрдпрд╛рд╡рд░ commit рдЪреНрдпрд╛ рдард╢рд╛рдЪреЗ рд▓реЗрдмрд▓ рд▓рд╛рд╡рддреЛ ЁЯП╖я╕П тАФ tag рдореНрд╣рдгрдЬреЗрдЪ git SHA (hello-school:abc123), рдореНрд╣рдгрдЬреЗ рдХрдкреНрдкреНрдпрд╛рд╡рд░рдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рдбрдмрд╛ "рд╣рд╛ рдХреЛрдгрддрд╛ рдХреЛрдб рдЖрд╣реЗ?" рдпрд╛рдЪреЗ рдЙрддреНрддрд░ рдирд╛рд╡рд╛рдиреЗрдЪ рджреЗрддреЛ. (рдЖрдгрд┐ IMMUTABLE tags рдореБрд│реЗ рддреНрдпрд╛рдмрджреНрджрд▓ рдХреЛрдгреАрд╣реА рдХрдзреАрдЪ рдЦреЛрдЯреЗ рдмреЛрд▓реВ рд╢рдХрдд рдирд╛рд╣реА.)
  4. рд╕реНрд╡рддрдГрдЪрд╛ рджрд┐рд╡рд╕рд╛рдЪрд╛ рдкрд╛рд╕ рдШреЗрдКрди рдбрдмрд╛ рдареЗрд╡рддреЛ ЁЯОлЁЯУж тАФ рдкреНрд░рддреНрдпреЗрдХ run рд▓рд╛ рддрд╛рдЬрд╛ ECR login, push, рдЭрд╛рд▓реЗ.
  5. рдмрдБрдХ рдбрдмреНрдпрд╛рдЪрд╛ X-ray рдХрд╛рдврддреЗ ЁЯЫбя╕П тАФ scan-on-push рддреБрдордЪреНрдпрд╛ рдерд░рд╛рдВрддрд▓реНрдпрд╛ рдорд╛рд╣реАрдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ vulnerabilities (CVEs) рдЪреА рдпрд╛рджреА рдХрд░рддреЗ. рд▓рд╣рд╛рди alpine images (рдзрдбрд╛ 07/08) рд╣рд╛ report рдЖрдирдВрджрджрд╛рдпрдХрдкрдгреЗ рдЫреЛрдЯрд╛ рдареЗрд╡рддрд╛рдд.

k8s рдХреЛрд░реНрд╕рдЪреА CircleCI pipeline рддрд┐рдЪреНрдпрд╛ рджреЛрди services рд╕рд╛рдареА рдиреЗрдордХреЗ рд╣реЗрдЪ рдХрд░рддреЗ тАФ рддреА file рддреБрдореНрд╣реА рдЖрддрд╛ рд╕рд╣рдЬ рд╡рд╛рдЪреВ рд╢рдХрддрд╛. ЁЯОУ

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    dev["ЁЯзСтАНЁЯТ╗ git push"]
    subgraph ci["ЁЯУо CI - the courier robot"]
        t["тЬЕ test"] --> b["ЁЯН▒ build"] --> tag["ЁЯП╖я╕П tag = commit SHA"] --> p["ЁЯОл login + push"]
    end
    subgraph ecr["ЁЯПж ECR"]
        box["ЁЯУж hello-school:abc123"]
        scan["ЁЯЫбя╕П scan on push"]
    end
    k8s["тШ╕я╕П k8s course:<br/>Deployments RUN it"]
    argo["ЁЯдЦ ArgoCD course:<br/>git deploys it, forever"]
    dev -->|"1"| ci -->|"2"| ecr
    ecr -->|"3 pulled by cluster"| k8s
    ecr -.->|"4 address committed to git"| argo

тЭУ рдХрд╛рдп (GitHub Actions рдЪреЗ рдЦрд░реЗ рдЙрджрд╛рд╣рд░рдг)

# .github/workflows/ship.yml тАФ illustrative; store AWS creds as CI secrets
on: { push: { branches: [main] } }
jobs:
  ship:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t app app/                     # ЁЯН▒ (tests would run first)
      - uses: aws-actions/configure-aws-credentials@v4
        with: { aws-region: ap-south-1,
                role-to-assume: arn:aws:iam::ACCOUNT:role/ci-ecr-push }  # ЁЯкк no long-lived keys
      - run: |
          REPO=ACCOUNT.dkr.ecr.ap-south-1.amazonaws.com/hello-school
          aws ecr get-login-password | docker login --username AWS --password-stdin "$REPO"  # ЁЯОл
          docker tag app "$REPO:${GITHUB_SHA::7}"          # ЁЯП╖я╕П tag = commit
          docker push "$REPO:${GITHUB_SHA::7}"             # ЁЯУж

ЁЯза рдХрд│рд╕рд╛рдзреНрдпрд╛рдп тАФ рд╕рдВрдкреВрд░реНрдг pipeline рдПрдХрд╛ рдЪрд┐рддреНрд░рд╛рдд

Developer
    тФВ  git push
    тЦ╝
CI  тФАтФА test тФАтФА docker build тФАтФА scan тФАтФА tag (commit SHA) тФАтФА push
                                                            тФВ
                                                            тЦ╝
                                                          ECR
                                                            тФВ  image pull (IAM role)
                                                            тЦ╝
                                                      Kubernetes
                                                            тФВ  desired state from git
                                                            тЦ╝
                                                        ArgoCD

Docker artifact рдмрдирд╡рддреЗ. ECR artifact рд╕рд╛рдард╡рддреЗ. Kubernetes artifact рдЪрд╛рд▓рд╡рддреЗ. ArgoCD deployment рд╕рд╛рдВрднрд╛рд│рддреЗ.

ЁЯОУ рдкрджрд╡реА рдкрд░реАрдХреНрд╖рд╛ тАФ рд╣реЗ рд╕рдордЬрд╛рд╡рддрд╛ рдпреЗрддреЗ рдХрд╛?

рдПрдХ developer рдХреЛрдб Git рд╡рд░ push рдХрд░рддреЗ. CI Docker image build рдХрд░рддреЗ, рддреА scan рдХрд░рддреЗ рдЖрдгрд┐ ECR рд╡рд░ push рдХрд░рддреЗ. рдирдВрддрд░ Kubernetes рддреА image pull рдХрд░реВрди рдЪрд╛рд▓рд╡рддреЗ. ArgoCD Kubernetes рдЪреА configuration Git рд╢реА рдЬреБрд│рддреЗ рдпрд╛рдЪреА рдЦрд╛рддреНрд░реА рдХрд░рддреЗ.

  1. Source code рдХреБрдареЗ рдЖрд╣реЗ?
  2. Image рдХреЛрдг рдмрдирд╡рддреЗ?
  3. Image рдЪреНрдпрд╛ рдЖрдд рдХрд╛рдп рдЖрд╣реЗ?
  4. Image рдХреБрдареЗ рд╕рд╛рдард╡рд▓реА рдЬрд╛рддреЗ?
  5. рдиреЗрдордХреА image рдХрд╢рд╛рдиреЗ рдУрд│рдЦрд▓реА рдЬрд╛рддреЗ?
  6. ECR рд╡рд░ push рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рдХреЛрдгрд╛рд▓рд╛ рдЖрд╣реЗ?
  7. ECR рд╡рд░реВрди pull рдХрд░рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рдХреЛрдгрд╛рд▓рд╛ рдЖрд╣реЗ?
  8. Container рдкреНрд░рддреНрдпрдХреНрд╖рд╛рдд рдХреЛрдг рдЪрд╛рд▓рд╡рддреЗ?
  9. Image tag рдмрджрд▓рд▓рд╛ рддрд░ рдХрд╛рдп рд╣реЛрддреЗ?
  10. ArgoCD рдХреБрдареЗ рдмрд╕рддреЗ?

рдкреНрд░рддреНрдпреЗрдХ рдЙрддреНрддрд░ рдПрдХрд╛ рд╡рд╛рдХреНрдпрд╛рдд рджреЗрддрд╛ рдЖрд▓реЗ, рддрд░ рддреБрдордЪреА рд╣реА рд╢рд╛рд│рд╛ рдкреВрд░реНрдг рдЭрд╛рд▓реА.

ЁЯдФ рдХрд╛

рд╣рд╛рддрд╛рдиреЗ рдкрд╛рдард╡рдгреНрдпрд╛рд▓рд╛ рд╣рд╛рддрд╛рдиреЗ deploy рдХрд░рдгреНрдпрд╛рд╕рд╛рд░рдЦрд╛рдЪ рдЖрдЬрд╛рд░ рдЖрд╣реЗ (ArgoCD рдХреЛрд░реНрд╕, рдзрдбрд╛ 01): рддреЗ рдорд╛рдгрд╕рд╛рдЪреНрдпрд╛ рд▓рдХреНрд╖рд╛рдд рд░рд╛рд╣рдгреНрдпрд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЗ. Robot рдкреНрд░рддреНрдпреЗрдХ image tested, labeled, scanned рдЖрдгрд┐ рдЬрд╛рдЧреЗрд╡рд░ рдареЗрд╡рд▓реЗрд▓реА рдХрд░рддреЛ тАФ рдЕрдЧрджреА рддрд╢реАрдЪ, рдХрд╛рдпрдо. рддреБрдордЪреЗ рдХрд╛рдо рдлрдХреНрдд рдХреЛрдб рд▓рд┐рд╣рд┐рдгреЗ рдЖрдгрд┐ scan reports рд╡рд╛рдЪрдгреЗ рдПрд╡рдвреЗрдЪ рдЙрд░рддреЗ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

# read a real scan report from your lesson-11 push:
aws ecr describe-image-scan-findings --repository-name hello-school \
  --image-id imageTag=v1 --query 'imageScanFindings.findingSeverityCounts'
# alpine base тЖТ usually a very short list ЁЯк╢

# cleanup when done playing (stop the pennies):
# terraform -chdir=ecr destroy     # or:
# aws ecr delete-repository --repository-name hello-school --force

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯОУ Trilogy тАФ рддреБрдореНрд╣реА рдЖрддрд╛ рдХреБрдареЗ рдЖрд╣рд╛рдд

рддреБрдореНрд╣реА 3 рдкреИрдХреА рдХреЛрд░реНрд╕ 1 рдкреВрд░реНрдг рдХреЗрд▓рд╛: рддреБрдордЪрд╛ рдХреЛрдб рдЖрдкреЛрдЖрдк tested, рдЫреЛрдЯреА, labeled, scanned image рдмрдиреВрди рдЦрд╛рдЬрдЧреА registry рдордзреНрдпреЗ рдмрд╕рддреЛ. рдкреБрдвреЗ:

  1. тШ╕я╕П Learn Kubernetes School тАФ cluster рддреБрдордЪреНрдпрд╛ images рдЪрд╛рд▓рд╡рддреЛ: pods, services, autoscaling, rollouts.
  2. ЁЯдЦ Learn ArgoCD School тАФ git рддреНрдпрд╛ deploy рдХрд░рддреЗ: рдХрд╛рд│рдЬреА рдШреЗрдгрд╛рд░рд╛ robot, self-heal, 10 рд╕реЗрдХрдВрджрд╛рдВрдЪреЗ rollbacks.

рдкреЕрдХ рдХрд░рд╛. рдЪрд╛рд▓рд╡рд╛. рдХрд╛рдпрдо рдкрд╛рдард╡рдд рд░рд╛рд╣рд╛. ЁЯН▒тШ╕я╕ПЁЯдЦ

git checkout main

ЁЯУо Lesson 12 тАФ CI to cloud: the courier files the copies

ЁЯУН You are here: Lesson 12 of 12 тАФ the final lesson! ┬╖ Previous: lesson-11-push-pull-lifecycle

ЁЯФЧ Next: Kubernetes pulls this image from ECR тАФ the Kubernetes school's lesson 01 starts exactly where this one ends.


ЁЯУж What's in this branch

All 12 lessons тАФ the complete course. The finale: handing lessons 1тАУ11 to a robot that does them on every push, plus the scan report, plus the baton pass to the rest of the trilogy.

ЁЯзТ Explain like I'm 5

Look at what you did by hand yesterday: build ЁЯН▒ тЖТ label with the full address ЁЯП╖я╕П тЖТ get the day pass ЁЯОл тЖТ push ЁЯУж. Four commands, every deploy, forever? No. That's a job for the courier robot ЁЯУо (CI):

On every git push, the robot:

  1. Checks the homework тЬЕ тАФ runs the tests. Bad code never gets boxed.
  2. Bakes the box ЁЯН▒ тАФ docker build, cache-fast thanks to lesson 02.
  3. Labels it with the commit's fingerprint ЁЯП╖я╕П тАФ the tag IS the git SHA (hello-school:abc123), so every box on the shelf answers "which code is this?" by name. (And IMMUTABLE tags mean nobody can ever lie about it.)
  4. Gets its own day pass and files the box ЁЯОлЁЯУж тАФ fresh ECR login each run, push, done.
  5. The bank X-rays the box ЁЯЫбя╕П тАФ scan-on-push lists known vulnerabilities (CVEs) in your layers. Small alpine images (lesson 07/08) keep this report blissfully short.

This is exactly what the k8s course's CircleCI pipeline does for its two services тАФ you can now read that file fluently. ЁЯОУ

ЁЯЧ║я╕П Diagram

flowchart LR
    dev["ЁЯзСтАНЁЯТ╗ git push"]
    subgraph ci["ЁЯУо CI - the courier robot"]
        t["тЬЕ test"] --> b["ЁЯН▒ build"] --> tag["ЁЯП╖я╕П tag = commit SHA"] --> p["ЁЯОл login + push"]
    end
    subgraph ecr["ЁЯПж ECR"]
        box["ЁЯУж hello-school:abc123"]
        scan["ЁЯЫбя╕П scan on push"]
    end
    k8s["тШ╕я╕П k8s course:<br/>Deployments RUN it"]
    argo["ЁЯдЦ ArgoCD course:<br/>git deploys it, forever"]
    dev -->|"1"| ci -->|"2"| ecr
    ecr -->|"3 pulled by cluster"| k8s
    ecr -.->|"4 address committed to git"| argo

тЭУ What (a real GitHub Actions example)

# .github/workflows/ship.yml тАФ illustrative; store AWS creds as CI secrets
on: { push: { branches: [main] } }
jobs:
  ship:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t app app/                     # ЁЯН▒ (tests would run first)
      - uses: aws-actions/configure-aws-credentials@v4
        with: { aws-region: ap-south-1,
                role-to-assume: arn:aws:iam::ACCOUNT:role/ci-ecr-push }  # ЁЯкк no long-lived keys
      - run: |
          REPO=ACCOUNT.dkr.ecr.ap-south-1.amazonaws.com/hello-school
          aws ecr get-login-password | docker login --username AWS --password-stdin "$REPO"  # ЁЯОл
          docker tag app "$REPO:${GITHUB_SHA::7}"          # ЁЯП╖я╕П tag = commit
          docker push "$REPO:${GITHUB_SHA::7}"             # ЁЯУж

ЁЯза The capstone тАФ the whole pipeline in one picture

Developer
    тФВ  git push
    тЦ╝
CI  тФАтФА test тФАтФА docker build тФАтФА scan тФАтФА tag (commit SHA) тФАтФА push
                                                            тФВ
                                                            тЦ╝
                                                          ECR
                                                            тФВ  image pull (IAM role)
                                                            тЦ╝
                                                      Kubernetes
                                                            тФВ  desired state from git
                                                            тЦ╝
                                                        ArgoCD

Docker builds the artifact. ECR stores the artifact. Kubernetes runs the artifact. ArgoCD manages the deployment.

ЁЯОУ Graduation test тАФ can you explain this?

A developer pushes code to Git. CI builds a Docker image, scans it and pushes it to ECR. Kubernetes later pulls that image and runs it. ArgoCD makes sure the Kubernetes configuration matches Git.

  1. Where is the source code?
  2. What creates the image?
  3. What is inside the image?
  4. Where is the image stored?
  5. What identifies an exact image?
  6. Who is allowed to push to ECR?
  7. Who is allowed to pull from ECR?
  8. Who actually runs the container?
  9. What happens if the image tag changes?
  10. Where does ArgoCD fit?

If every answer comes out in one sentence, you are done with this school.

ЁЯдФ Why

Manual shipping has the same disease as manual deploying (ArgoCD course, lesson 01): it depends on a human remembering. The robot makes every image tested, labeled, scanned, and filed тАФ identically, forever. Your job shrinks to writing code and reading scan reports.

ЁЯзк Try it

# read a real scan report from your lesson-11 push:
aws ecr describe-image-scan-findings --repository-name hello-school \
  --image-id imageTag=v1 --query 'imageScanFindings.findingSeverityCounts'
# alpine base тЖТ usually a very short list ЁЯк╢

# cleanup when done playing (stop the pennies):
# terraform -chdir=ecr destroy     # or:
# aws ecr delete-repository --repository-name hello-school --force

тЪая╕П Common mistakes

ЁЯОУ The trilogy тАФ where you are now

You've completed course 1 of 3: your code becomes a tested, tiny, labeled, scanned image sitting in a private registry, automatically. Next:

  1. тШ╕я╕П Learn Kubernetes School тАФ a cluster RUNS your images: pods, services, autoscaling, rollouts.
  2. ЁЯдЦ Learn ArgoCD School тАФ git DEPLOYS them: the caretaker robot, self-heal, 10-second rollbacks.

Pack it. Run it. Ship it forever. ЁЯН▒тШ╕я╕ПЁЯдЦ

git checkout main
тЖР Previouspush pull lifecycleFinished! Take the quiz тЖТcheck what stuck

This page is the lesson's README from the lesson-12-ci-to-cloud branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.