devHọc Dev
Bài học

Tuần 8 - Ngày 3: CI/CD và DevOps trên AWS

Tuần 8 – Ngày 3

Mục tiêu học tập

  • Nắm chuỗi Developer Tools (CodeBuild/CodeDeploy/CodePipeline) và vai trò CodeConnections với Git provider bên ngoài
  • Phân biệt các deployment strategy (rolling, blue/green, canary) theo trade-off
  • Biết pattern multi-account pipeline và IaC selection ở mức Professional

Tổng quan CI/CD

CI/CDPIPELINESOURCEBUILDTESTDEPLOYMONITORGitHubCodeBuildCodeBuildCodeDeployCloudWatchGitLab+Tests+Scans+PipelinesX-RayBitbucket(quaCodeConnections)CodePipelineorchestrates

AWS Developer Tools

1. Source control: GitHub/GitLab/Bitbucket qua CodeConnections

Deprecation note (quan trọng cho đề 2026): AWS CodeCommit ngừng nhận khách hàng mới từ 25/07/2024. AWS khuyến nghị dùng GitHub, GitLab hoặc Bitbucket kết nối vào CodePipeline/CodeBuild qua AWS CodeConnections (tên cũ: CodeStar Connections). Scenario "new workload cần Git repo" trên đề hiện hành sẽ KHÔNG lấy CodeCommit làm đáp án — tương tự cặp SMS → MGN trong Common Traps.

Lachnchính(newworkloads):GitHub/GitLab/Bitbucket+CodeConnectionsOAuth/app-basedconnection,qunlýbngIAMTriggerCodePipelinetheopush/PRKhôngcnqunlýcredentialstrongpipelineCodeCommit(legacyaccountđãdùngttrưc):Fullymanagedsourcecontrol,encryptedIntegrateswithIAMPullrequests,branches,triggersVnđưcsupportchokháchhànghinhuBestPractices:-Branchprotectionrules-CodereviewviaPRs-IntegratewithCodeGuruReviewer

2. AWS CodeBuild

CODEBUILDManagedbuildservice:CompilessourcecodeRunstestsProducesartifactsScalesautomaticallyBuildEnvironments:Managedimages(AmazonLinux,Ubuntu,Windows)CustomDockerimagesGPU-enabledbuildsbuildspec.yml:phases:install,pre_build,build,post_buildartifacts:outputfilescache:speedupbuilds

buildspec.yml Example:

version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 18
  pre_build:
    commands:
      - npm install
  build:
    commands:
      - npm run build
      - npm test
  post_build:
    commands:
      - echo "Build completed"
artifacts:
  files:
    - '**/*'
  base-directory: dist
cache:
  paths:
    - node_modules/**/*

3. AWS CodeDeploy

CODEDEPLOYDeploymentTargets:EC2/On-premisesECS(Blue/Green)Lambda(Trafficshifting)DeploymentStrategies:In-place(EC2)Blue/Green(EC2,ECS)Canary(Lambda:10%,wait,100%)Linear(Lambda:10%everyXminutes)All-at-onceDeploymentConfiguration:-Minimumhealthyhosts-Rollbacksettings-Lifecyclehooks

appspec.yml (EC2):

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html
hooks:
  BeforeInstall:
    - location: scripts/before_install.sh
  AfterInstall:
    - location: scripts/after_install.sh
  ApplicationStart:
    - location: scripts/start.sh
  ValidateService:
    - location: scripts/validate.sh

4. AWS CodePipeline

CODEPIPELINEOrchestrationservice:VisualworkflowdesignerStage-basedexecutionParallelactionsManualapprovalgatesPipelineStructure:SourceBuildTestDeployIntegrations:-GitHub,GitLab,Bitbucket-Jenkins-CloudFormation,CDK-ECS,EKS,Lambda,S3

Deployment Strategies Deep Dive

1. Rolling Deployment

ROLLINGDEPLOYMENTStep1:[v1][v1][v1][v1]Allrunningv1Step2:[v2][v1][v1][v1]FirstbatchupdatedStep3:[v2][v2][v1][v1]SecondbatchupdatedStep4:[v2][v2][v2][v2]Allrunningv2Pros:NoextrainfrastructureCons:Mixedversionsduringdeployment

2. Blue/Green Deployment

BLUE/GREENDEPLOYMENTBLUE(Current)GREEN(New)v1v1v2v2[LoadBalancer]SwitchtrafficStep1:DeploytoGreenStep2:TestGreenStep3:SwitchtrafficBlueGreenStep4:KeepBlueforrollbackPros:Instantrollback,nodowntimeCons:Doubleinfrastructurecostduringdeploy

3. Canary Deployment

CANARYDEPLOYMENTStep1:10%traffictov2,90%tov1[v1][v1][v1][v1][v1][v1][v1][v1][v1]90%[v2]10%Step2:Monitormetrics,errorsStep3:IfOK,graduallyincreaseto100%Step4:Ifissues,rollbackimmediatelyPros:EarlydetectionofissuesCons:Complexrouting,monitoringrequired

Infrastructure as Code

AWS CloudFormation

CLOUDFORMATIONTemplateStackResourcesKeyConcepts:Templates(YAML/JSON)Stacks(resourcecollection)StackSets(multi-account/region)ChangeSets(previewchanges)DriftDetectionBestPractices:UsenestedstacksformodularityParameterizetemplatesUseMappingsforregion-specificvaluesEnableterminationprotection

AWS CDK (Cloud Development Kit)

Defineinfrastructureusingprogramminglanguages:TypeScriptPythonJavaC#GoCDKCloudFormationtemplateResourcesBenefits:-Typesafety-IDEsupport-Reusableconstructs-Testingcapabilities

Terraform on AWS

Multi-cloudIaCtool:HCL(HashiCorpConfigurationLanguage)Statemanagement(local,S3,TerraformCloud)ProviderecosystemModulesforreusabilityAWSProviderfeatures:-AllAWSservicessupported-Importexistingresources-Driftdetection

CodeGuru

CodeGuru Reviewer

AI-poweredcodereview:SecurityvulnerabilitiesPerformanceissuesBestpracticesAWSSDKusageIntegrateswithPRs

CodeGuru Profiler

Applicationperformance:CPUutilizationanalysisMemoryprofilingHeapusageLatencyidentificationCostrecommendations

Exam Scenarios

Scenario 1: Zero-Downtime Deployment

Requirement:DeployupdateswithoutdowntimeSolution:ECSwithBlue/GreenviaCodeDeployALBfortrafficshiftingHealthchecksbeforeswitchAutomaticrollbackonfailure

Scenario 2: Multi-Account Pipeline

Requirement:DeploytoDev,Staging,ProdaccountsSolution:CodePipelineincentralaccountCross-accountIAMrolesManualapprovalbeforeProdCloudFormationStackSets

Scenario 3: Container CI/CD

Requirement:BuildanddeploycontainersSolution:GitHub(CodeConnections)CodeBuild(buildimage)PushtoECRCodeDeploytoECSBlue/GreendeploymentAutomatedrollback

Quick Reference

CI/CDTOOLSELECTIONNeedServiceSourcecontrolGitHub/GitLab/Bitbucket+CodeConnections(CodeCommit:legacyonly,đóngkháchmi07/2024)Build/TestCodeBuildDeployEC2CodeDeployDeployECSCodeDeploy(Blue/Green)DeployLambdaCodeDeploy(Canary/Linear)DeployK8sArgoCD,FluxOrchestratepipelineCodePipelineIaCCloudFormation,CDK,TerraformMulti-accountdeployStackSets,CodePipelineCodereviewCodeGuruReviewerPerformanceanalysisCodeGuruProfiler

CloudFormation Custom Resources & Resource Import

Custom Resources — chạy logic CloudFormation không hỗ trợ

Khi stack cần làm việc mà CloudFormation không có resource type tương ứng, dùng Custom Resource: một resource "ảo" mà lifecycle (Create/Update/Delete) được xử lý bởi code của bạn — Lambda-backed (phổ biến nhất) hoặc SNS-backed (gửi event tới topic, thường cho hệ thống on-premises/bên ngoài xử lý).

CUSTOMRESOURCEFLOWCFNStack(Create/Update/Deleteevent)Lambda(SUCCESS/FAILEDresponse)pre-signedS3URL(cfn-response)Stackchresponsekhônggi=treotitimeout(gi!)

Cơ chế:

  • Template khai báo Custom::<Tên> với thuộc tính bắt buộc ServiceToken trỏ tới Lambda ARN (hoặc SNS topic ARN).
  • Khi stack Create/Update/Delete, CFN invoke Lambda với event chứa RequestType (Create/Update/Delete), ResourceProperties, và ResponseURL — một pre-signed S3 URL.
  • Lambda PHẢI gửi response (SUCCESS/FAILED) về ResponseURL — dùng module cfn-response (có sẵn khi viết inline code) hoặc thư viện crhelper. Quên gửi response = stack treo ở CREATE_IN_PROGRESS/DELETE_IN_PROGRESS cho tới timeout (mặc định có thể vài giờ) — lỗi kinh điển.

Use case kinh điển trên đề:

  1. Empty S3 bucket trước khi delete stack — CFN không xoá được bucket còn object; custom resource nhận event Delete → xoá hết object (kể cả version) → bucket xoá được. (Từ 2023 AWS::S3::Bucket không có thuộc tính auto-empty; custom resource vẫn là đáp án chuẩn.)
  2. Gọi API bên thứ ba trong lúc provision (đăng ký license, tạo record ở SaaS, lookup AMI ID mới nhất...).
  3. Provision resource CFN chưa hỗ trợ (service mới, tính năng mới chưa có resource type).

Snippet YAML (Lambda-backed, empty bucket on delete):

Resources:
  MyBucket:
    Type: AWS::S3::Bucket

  EmptyBucketOnDelete:
    Type: Custom::EmptyBucket
    Properties:
      ServiceToken: !GetAtt EmptyBucketFunction.Arn   # Lambda ARN — bắt buộc
      BucketName: !Ref MyBucket
# Trong Lambda handler (rút gọn)
import cfnresponse
def handler(event, context):
    if event['RequestType'] == 'Delete':
        empty_bucket(event['ResourceProperties']['BucketName'])
    cfnresponse.send(event, context, cfnresponse.SUCCESS, {})  # BẮT BUỘC

Lưu ý Professional: với nhu cầu tái sử dụng nhiều account/nhiều team, cân nhắc nâng cấp custom resource thành CloudFormation Registry private resource type / hook — nhưng khi đề chỉ hỏi "one-off logic trong stack", custom resource là đáp án gọn nhất.

Resource Import — đưa resource tạo thủ công vào stack

Vấn đề: hạ tầng legacy tạo tay (console/CLI) nằm ngoài IaC — muốn quản lý bằng CloudFormation mà không tạo lại (không downtime, không đổi ARN).

Giải pháp: Resource Import (cloudformation import, console: Stack actions → Import resources into stack):

ManuallycreatedTemplatemôtresourceStackqunlýS3bucketimport(khpcuhìnhthctế,bucketnhưmi(ngoàiIaC)cóDeletionPolicy)resourcekhác
  • Template phải mô tả resource với identifier thực tế (vd BucketName) và mọi resource được import BẮT BUỘC có DeletionPolicy (thường Retain) — đây là điều kiện cứng của import operation.
  • Resource type phải hỗ trợ import (đa số resource phổ biến đều hỗ trợ).
  • Import vào stack mới hoặc stack đang có đều được; import không thay đổi resource — chỉ gắn vào stack.
  • Best practice sau import: chạy Drift Detection ngay để xác nhận template khớp 100% cấu hình thực tế — template viết tay dễ thiếu thuộc tính, drift detection lộ ra chênh lệch trước khi update stack gây thay đổi ngoài ý muốn.

Use case: chuẩn hoá hạ tầng legacy vào IaC theo lộ trình (governance, review qua change set) mà không cần migration/tạo lại resource.

Exam keywords

Keyword trên đềĐáp án
"Delete stack fails because S3 bucket is not empty"Lambda-backed custom resource empty bucket khi nhận event Delete
"Provision resource/call API CloudFormation doesn't support"Custom resource (ServiceToken → Lambda/SNS)
"Bring existing resources under CloudFormation management without recreating"Resource Import (+ DeletionPolicy bắt buộc, drift detection sau import)
"Stack stuck in CREATE_IN_PROGRESS with custom resource"Lambda quên gửi cfn-response về pre-signed URL

EC2 Image Builder

Bài toán: tổ chức cần golden image (AMI/container image đã hardened, cài sẵn agent, patch mới nhất) build lại định kỳ và phân phối cho nhiều region, nhiều account — làm tay bằng Packer/script + Lambda + EventBridge là nhiều moving part. EC2 Image Builder là managed service làm trọn pipeline này.

EC2IMAGEBUILDERPIPELINESOURCEBUILDTESTDISTRIBUTEBaseBuildTestMulti-imagecomponentscomponentsregion(AMI/(install(smoke/copy+ECR)agents,securitysharepatch,harden)tests)accountsSchedule:cron/khibaseimagecóversionmi(vdhàngthángsauPatchTuesday)

Thành phần chính:

  • Components: bước build (cài software, hardening, patch) và test (validate image trước khi distribute) — viết bằng YAML document, AWS có sẵn nhiều managed component (vd update-linux, STIG hardening, Inspector test).
  • Image recipe (AMI) / container recipe (Docker image cho ECR): base image + danh sách components + version.
  • Infrastructure configuration: instance type, subnet, IAM instance profile dùng để build/test.
  • Distribution configuration: copy AMI sang nhiều region, share cross-account (launch permission cho account/OU, hoặc qua AWS RAM / AWS Organizations), gắn license configuration, output alias ECR cho container.
  • Pipeline + schedule: chạy theo cron (vd hàng tháng khi có patch) hoặc khi dependency có bản mới (semantic versioning trên base image/component) — golden image luôn mới mà không cần chạm tay.

Điểm Professional cần nhớ:

  • Build instance cần Systems Manager Agent — Image Builder điều khiển build qua SSM (base image AWS đã có sẵn SSM Agent; Image Builder tự cài nếu thiếu).
  • Miễn phí — chỉ trả tiền tài nguyên bên dưới (EC2 build instance, EBS, S3 log, data transfer/copy AMI).
  • Build cả AMI và container image (output ECR).
  • Kết hợp: pipeline output AMI mới → EventBridge/SNS notification → update Launch Template version cho ASG, hoặc dùng làm base cho CodePipeline.

Exam keyword: "automate golden AMI creation and distribution across accounts/regions with least operational overhead" → EC2 Image Builder (KHÔNG phải tự viết Packer + Lambda + Step Functions — nhiều operational overhead hơn); "monthly patched AMI shared to all accounts in the organization" → Image Builder pipeline schedule hàng tháng + distribution configuration share qua Organizations/RAM.

Câu hỏi ôn tập

  1. Vì sao "new workload cần Git repo" trên đề 2026 không chọn CodeCommit?

    Xem đáp án

    CodeCommit đóng với khách hàng mới từ 25/07/2024 — account chưa từng dùng không tạo repo được. Đáp án hiện hành: GitHub/GitLab/Bitbucket + AWS CodeConnections (tên cũ CodeStar Connections) làm source stage cho CodePipeline — connection quản lý bằng IAM, không lưu credentials trong pipeline. CodeCommit chỉ còn hợp lệ cho khách hàng hiện hữu (legacy). Cùng dạng bẫy "deprecated service" như SMS → MGN.

  2. Blue/Green khác Canary ở trade-off nào?

    Xem đáp án

    Blue/Green: chuyển 100% traffic một lần sau khi test Green — rollback tức thì (switch ngược), nhưng tốn gấp đôi infrastructure trong lúc deploy và lỗi (nếu lọt qua test) ảnh hưởng toàn bộ user. Canary: đưa 10% traffic vào version mới, monitor rồi tăng dần — phát hiện lỗi sớm với blast radius nhỏ, nhưng cần routing + monitoring phức tạp hơn và deploy lâu hơn. Lambda dùng canary/linear qua alias traffic shifting; ECS blue/green qua CodeDeploy + ALB.

  3. Multi-account pipeline (dev → staging → prod) cần những mảnh ghép nào?

    Xem đáp án

    (1) CodePipeline ở account trung tâm (tooling/shared services), (2) cross-account IAM roles cho deploy action assume vào từng account đích, (3) artifact bucket + KMS key cho phép account đích đọc (bucket policy + key policy), (4) manual approval gate trước prod, (5) CloudFormation StackSets nếu deploy hạ tầng chuẩn hoá nhiều account. Bẫy hay gặp: quên grant KMS key cross-account → deploy fail dù role đúng.

  4. CodeDeploy hỗ trợ những compute target nào và chiến lược tương ứng?

    Xem đáp án

    (1) EC2/on-premises: in-place (theo deployment config: OneAtATime, HalfAtATime, AllAtOnce) hoặc blue/green với ASG mới; hooks trong appspec.yml. (2) ECS: blue/green qua ALB target groups (task set mới, test listener, switch). (3) Lambda: canary (10% rồi 100%) hoặc linear (10% mỗi X phút) qua alias — kèm alarms + hooks (BeforeAllowTraffic/AfterAllowTraffic) để auto-rollback. Chọn theo compute của đề bài — không có "CodeDeploy cho S3 static site" (đó là pipeline + S3 deploy action).

  5. Delete stack fail vì S3 bucket còn object — giải quyết thế nào bằng CloudFormation? Nếu muốn đưa một bucket tạo tay vào stack thì sao?

    Xem đáp án

    Bucket not empty: CloudFormation không xoá được bucket còn object → dùng Lambda-backed custom resource (Custom::EmptyBucket với ServiceToken trỏ Lambda ARN); Lambda nhận event Delete, xoá hết object (kể cả version) rồi bắt buộc gửi response (cfn-response) về pre-signed S3 URL — quên gửi = stack treo tới timeout. Bucket tạo tay: dùng Resource Import (cloudformation import) — template mô tả bucket đúng cấu hình thực tế và phải có DeletionPolicy; import không tạo lại/không đổi resource, sau import chạy drift detection để xác nhận template khớp thực tế.

  6. Yêu cầu "golden AMI patch hàng tháng, phân phối mọi region và mọi account trong Organization, least operational overhead" — chọn gì và vì sao không tự dựng?

    Xem đáp án

    EC2 Image Builder: pipeline managed build → test → distribute; image recipe (base image + build/test components), schedule cron hàng tháng (hoặc trigger khi base image có version mới), distribution configuration copy AMI multi-region + share cross-account qua AWS RAM/Organizations. Build qua SSM Agent, service miễn phí (chỉ trả EC2/EBS/S3 lúc build). Tự dựng Packer + Lambda + EventBridge + script copy/share AMI cũng ra kết quả nhưng nhiều operational overhead hơn — sai keyword của đề. Image Builder cũng build được container image ra ECR.

Bài tập thực hành

  1. Pipeline GitHub → CodeBuild → S3: tạo CodeConnections connection tới GitHub repo cá nhân, dựng CodePipeline 3 stage (Source → Build → Deploy S3 static site); push commit và xem pipeline tự chạy.

  2. Lambda canary deployment: deploy Lambda có alias live, cấu hình CodeDeploy Canary10Percent5Minutes kèm CloudWatch alarm error rate; deploy version lỗi có chủ đích và quan sát auto-rollback.

  3. Blue/Green ECS: với service ECS từ bài tuần 5, tạo CodeDeploy application blue/green qua ALB 2 target groups; deploy image mới và thử rollback thủ công trước khi hết thời gian chờ terminate.


Tài liệu tham khảo chính thức


Tiếp theo: Cost Management