Link Search Menu Expand Document

AWS CodePipeline

CodePipeline là dịch vụ AWS cho phép chúng ta xây dựng qui trình khiển khai ứng dụng một cách liên tục và tự động. Với cách thức cấu hình đơn giản, CodePipeline có khả năng mô hình hoá trực quan các bước cần thiết để biên dịch, kiểm thử và triển khai các phiên bản cập nhật cho một ứng dụng hoặc dịch vụ.

Pipeline Sample Ví dụ qui trình triển khai phần mềm dựa trên CodePipeline

Để thực hiện thiết lập một qui trình triển khai ứng dụng dựa trên CodePipeline, chúng ta cần hiểu qua một số khái niệm / thuật ngữ cơ bản thường dùng:

  • Pipeline: là một qui trình - workflow mô tả một chuỗi các bước thực hiện từ việc thay đổi source code đến khi tích hợp và triển khai những thay đổi này sang môi trường sản phẩm.

  • Stage: mô tả mỗi bước thực hiện trong Pipeline. Stage thường hoạt động trong một môi trường độc lập, thực hiện những xử lý dựa trên input artifact.

  • Transition: là mốc dịch chuyển giữa việc thực thi của các stages trong một pipeline. Việc kiểm soát transition (enable / disable) cho phép chúng ta thực hiện các xác nhận cần thiết trước khi quyết định tiếp tục việc triển khai.

  • Artifact: được phân chia thành hai loại:

    • Input artifact: được sử dụng để thực thi các hoạt động trong một stage. Ví dụ: source code là input artifact - được biên dịch / kiểm thử bởi các câu lệnh build stage.
    • Output artifact: là kết quả được tạo ra bởi các hoạt động trong một stage. Ví dụ: các lệnh trong build stage tạo ra Test Report, Log, hoặc Docker Image.

Hướng dẫn

Output Artifacts từ một stage có thể được sử dụng làm Input Artifact trong stage tiếp theo. Ví dụ, build stage tạo ra Docker Image, deploy stage sử dụng Docker Image để cài đặt / triển khai trong ECS Cluster.

Tuỳ theo mô hình triển khai của ECS, Rolling v.s Blue/Green Updates, chúng ta sẽ có những cách tiếp cận khác nhau để thiết lập dịch vụ AWS CodeBuild. Do vậy, phần thực hành tiếp theo sẽ chia thành hai phần:

  1. CodePipeline & ECS Rolling Updates
  2. CodePipeline & ECS Blue/Green Updates
  3. Kết luận

CodePipeline & ECS Rolling Updates

Bước 1: Chuẩn bị môi trường

Để sử dụng CodePipeline & ECS Rolling Updates cho dịch vụ RemindersManagement, thực hiện các chuẩn bị sau:

  • Quản lý source code của RemindersManagement dựa trên AWS CodeCommit

  • Khai báo và cấu hình ECS Cluster & Service dựa trên cơ chế Rolling Updates

  • Sử dụng AWS CodeBuild để tích hợp các thay đổi từ source code, biên dịch, kiểm thử và tạo Docker Image lưu trên Elastic Container Registry.

  • Khi thực hiện quá trình triển khai, CodePipeline cần sử dụng input artifact - imagedefinition.json định nghĩa container image và tag, do đó chúng ta cần cập nhật thêm nội dung của buildspec.yml trong CodeBuild:

version: 0.2

phases:
  install:
    runtime-versions:
        dotnet: 3.1  
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=729365137003.dkr.ecr.ap-southeast-2.amazonaws.com/remindersmgtservice
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Running unit tests
      - dotnet test -c Release ./Services/RemindersManagement/RemindersManagement.UnitTests/RemindersManagement.UnitTests.csproj --logger trx --results-directory ./TestResults /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=../../../TestResults/
      - echo Building the Docker image...
      - echo Building for repository $REPOSITORY_URI
      - docker build -t $REPOSITORY_URI:latest ./Services/RemindersManagement/RemindersManagement.API
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - printf '[{"name":"remindersmgtservice","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json
    - TestResults/*
  discard-paths: yes

reports:
  GeneralTestsReport:
      file-format: VisualStudioTrx
      files:
          - '**/*'
      base-directory: './TestResults'
  CoverageTestsReport:
      file-format: CoberturaXml
      files:
          - '**/*'
      base-directory: './TestResults'      

Những thay đổi trong buildspec.yml file:

  • Trong post_build commands, sử dụng printf để tạo file imagedefinition.json
  • Bổ sung artifacts khai báo output arifacts, bao gồm file imagedefinition.json

Commit và push file lên AWS CodeCommit.

Bước 2: Tạo CodePipeline

  • Sử dụng AWS Console, di chuyển đến dịch vụ CodePipeline, click button Create pipeline để tạo Pipeline mới:

Pipeline Mainscreen AWS CodePipeline

  • Trên màn hình Pipeline settings, khai báo các cấu hình của Pipeline sau:
    • Pipeline name: FriendRemindersPipeline
    • Service role: Lựa chọn New service role
    • Role name: codepipeline-FriendRemindersBuild-service-role
    • Lựa chọn Check trong phần Allow AWS CodePipeline to create a service role...

Pipeline Settings AWS CodePipeline Settings

Click button Next để chuyển sang màn hình kế tiếp.

  • Trên màn hình Add source stage, khai báo Source Code Provider cho Pipeline:
    • Source provider: AWS CodeCommit
    • Repository name: FriendReminders
    • Branch name: master
    • Change detection options: Amazon CloudWatch Events

Pipeline Source Stage AWS CodePipeline Add Source Stage

Click button Next để chuyển sang màn hình kế tiếp.

  • Trên màn hình Build - optional, cấu hình cho quá trình build
    • Build provider: AWS CodeBuild
    • Project name: FriendRemindersBuild
    • Build type: Single build

Pipeline Build Stage AWS CodePipeline Build

  • Trên màn hình Deploy - optional cấu hình cho quá trình deploy:
    • Deploy provider: Amazon ECS
    • Cluster name: friendreminders
    • Service name: remindersmgt
    • Image definitions file - optional: imagedefinitions.json

Pipeline Deploy Stage AWS ECS Deploy Provider

Chú ý

File imagedefinitions.json được tạo ra từ lệnh khai báo trong file buildspec.yml khi thực hiện cấu hình cho CodeBuild FriendRemindersBuild project. Ví dụ nội dung file imagedefinitions.json:

[
  {
    "name":"remindersmgtservice",
    "imageUri":"729365137003.dkr.ecr.ap-southeast-2.amazonaws.com/remindersmgtservice:bbda51e"
  }
]

Click button Next để chuyển sang màn hình kế tiếp.

  • Trên màn hình Review, kiểm tra một lần nữa các thông tin đã cấu hình trước đó và click button Create pipeline để xác nhận thực hiện việc tạo Pipeline cho RemindersManagement service.

Pipeline Review Stage AWS CodePipeline Review

Khi Pipeline tạo ra thành công, AWS tự động chuyển qua màn hình mới và thực hiện quá trình biên dịch và triển khai cho RemindersManagement:

Pipeline Create and Start AWS CodePipeline Starting

Pipeline Create and Completed AWS CodePipeline Completed

Bước 3: Để xác nhận hoạt động CodePipeline:

  • Thay đổi source code của RemindersManagement và push lên AWS CodeCommit
  • FriendRemindersPipeline được triển khai tự động và thực thi thành công
  • Truy cập địa chỉ DNS Load Balancer của ECS Cluster friendreminders
  • Xác nhận APIs được thực thi với những kết quả cập nhật từ source code

ECS Load Balancer ECS Application Load Balancer

ECS Load Balancer Swagger UI RemindersManagement


CodePipeline & ECS Blue/Green Updates

Chú ý

Phần thực hành này sử dụng lại một tên gọi trong bài thực hành trước liên quan đến Pipeline, Role, Policy, do đó chúng ta có thể xoá những thành phần đã tạo ra trong bài thực hành trước, hoặc sử dụng tên gọi khác trong bài thực hành này.

Trong trường hợp ECS sử dụng mô hình triển khai Blue/Green Updates, các bước thiết lập cấu hình CodePipeline cũng được thực hiện một cách tương tự, ngoại trừ một số điểm khác biệt liệt kê theo từng bước sau đây:

Bước 1: Chuẩn bị môi trường

  • Quản lý source code của RemindersManagement dựa trên AWS CodeCommit

  • Khai báo và cấu hình ECS Cluster & Service dựa trên cơ chế Blue/Green Updates

  • Sử dụng AWS CodeBuild để tích hợp các thay đổi từ source code, biên dịch, kiểm thử và tạo Docker Image lưu trên Elastic Container Registry.

  • Trong solution folder FriendReminders, tạo các file sau:

taskdef.json - cung cấp thông tin ECS Task Definition

{
  "executionRoleArn": "arn:aws:iam::729365137003:role/ECSRemindersMgtTask",
  "containerDefinitions": [
      {
          "name": "remindersmgtservice",
          "image": "729365137003.dkr.ecr.ap-southeast-2.amazonaws.com/remindersmgtservice:latest",
          "essential": true,
          "portMappings": [
              {
                  "protocol": "tcp",
                  "containerPort": 8000
              }
          ]
      }
  ],
  "requiresCompatibilities": [
      "FARGATE"
  ],
  "networkMode": "awsvpc",
  "cpu": "256",
  "memory": "512",
  "family": "remindersmgtfargate"
}

appspec.yaml - khai báo các chỉ thị CodeDeploy cần thực hiện khi triển khai.

version: 1.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-southeast-2:729365137003:task-definition/remindersmgtfargate:latest"
        LoadBalancerInfo:
          ContainerName: "remindersmgtservice"
          ContainerPort: "8000"
        PlatformVersion: "1.3.0"
  • Cập nhật input artifact trong buildspec.yml:
version: 0.2

phases:
  install:
    runtime-versions:
        dotnet: 3.1  
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=729365137003.dkr.ecr.ap-southeast-2.amazonaws.com/remindersmgtservice
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Running unit tests
      - dotnet test -c Release ./Services/RemindersManagement/RemindersManagement.UnitTests/RemindersManagement.UnitTests.csproj --logger trx --results-directory ./TestResults /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=../../../TestResults/
      - echo Building the Docker image...
      - echo Building for repository $REPOSITORY_URI
      - docker build -t $REPOSITORY_URI:latest ./Services/RemindersManagement/RemindersManagement.API
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on the `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - printf '[{"name":"remindersmgtservice","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json
    - appspec.yaml
    - taskdef.json
    - TestResults/*
  discard-paths: no

reports:
  GeneralTestsReport:
      file-format: VisualStudioTrx
      files:
          - '**/*'
      base-directory: './TestResults'
  CoverageTestsReport:
      file-format: CoberturaXml
      files:
          - '**/*'
      base-directory: './TestResults'      

Bước 2: Xác nhận CodeDeploy Application

Khi sử dụng ECS với cơ chế triển khai Blue/Green Updates, AWS tự động tạo ra các thành phần CodeDeploy Application và Deployment groups được sử dụng khi cấu hình CodePipeline. Chúng ta sẽ sử dụng AWS Console để xác nhận sự tồn tại của những thành phần này:

Sử dụng AWS Console, di chuyển đến màn hình CodeDeploy -> Applications:

Deploy Application AWS Deploy Application

Click link AppECS-friendreminders-remindersmgt để hiển thị Deploy Group:

Deploy Group AWS Deploy Groups

Bước 3: Tạo CodePipeline

  • Sử dụng AWS Console, di chuyển đến dịch vụ CodePipeline, click button Create pipeline để tạo Pipeline mới:

Pipeline Mainscreen AWS CodePipeline

  • Trên màn hình Pipeline settings, khai báo các cấu hình của Pipeline sau:
    • Pipeline name: FriendRemindersPipeline
    • Service role: Lựa chọn New service role
    • Role name: codepipeline-FriendRemindersBuild-service-role
    • Lựa chọn Check trong phần Allow AWS CodePipeline to create a service role...

Pipeline Settings AWS CodePipeline Settings

Click button Next để chuyển sang màn hình kế tiếp.

  • Trên màn hình Add source stage, khai báo Source Code Provider cho Pipeline:
    • Source provider: AWS CodeCommit
    • Repository name: FriendReminders
    • Branch name: master
    • Change detection options: Amazon CloudWatch Events

Pipeline Source Stage AWS CodePipeline Add Source Stage

Click button Next để chuyển sang màn hình kế tiếp.

  • Trên màn hình Build - optional, cấu hình cho quá trình build
    • Build provider: AWS CodeBuild
    • Project name: FriendRemindersBuild
    • Build type: Single build

Pipeline Build Stage AWS CodePipeline Build

  • Trên màn hình Deploy - optional cấu hình cho quá trình deploy:
    • Deploy provider: Amazon ECS (Blue/Green)
    • AWS CodeDeploy application name: AppECS-friendreminders-remindersmgt
    • AWS CodeDeploy deployment group: DgpECS-friendreminders-remindersmgt
    • Amazon ECS task definition:
      • BuildArtifact: taskdef.json
    • AWS CodeDeploy AppSpec file:
      • BuildArtifact: appspec.yaml

Pipeline Deploy Stage AWS ECS Blue/Green Deploy Provider

Chú ý

Khi cấu hình CodePipeline với ECS Blue/Green Updates, rất nhiều trường hợp gặp sai lầm khi lựa chọn AWS CodeDeploy trong danh sách Deploy Provider. Lựa chọn này chỉ áp dụng khi triển khai ứng dụng trong các EC2 Instances.

Click button Next để chuyển sang màn hình tiếp theo.

  • Trên màn hình Review, kiểm tra một lần nữa các thông tin đã cấu hình trước đó và click button Create pipeline để xác nhận thực hiện việc tạo Pipeline cho RemindersManagement service.

Pipeline Review Stage AWS CodePipeline Review

Khi Pipeline tạo ra thành công, AWS tự động chuyển qua màn hình mới và thực hiện quá trình biên dịch và triển khai cho RemindersManagement:

Pipeline Create and Start AWS CodePipeline Starting

Trong quá trình thực hiện triển khai, có thể click vào link Details trong Deploy phase để xác nhận quá trình chuyển đổi giữa hai môi trường Blue / Green:

Pipeline Create and Start AWS CodePipeline Deploying

Pipeline Create and Start AWS CodeDeploy Blue/Green Switching

Khi hoàn thành quá trình chuyển đổi, chúng ta có thể click button Termina original task set để loại bỏ môi trường cũ (việc loại bỏ môi trường cũ sẽ thực hiện sau 1 tiếng theo mặc định)

Pipeline Create and Start AWS CodeDeploy Switching Blue/Green Completed

Pipeline Create and Start AWS CodeDeploy Blue/Green Terminate Original

Pipeline Create and Start AWS CodePipeline Completed

Bước 3: Để xác nhận hoạt động CodePipeline:

  • Thay đổi source code của RemindersManagement và push lên AWS CodeCommit
  • FriendRemindersPipeline được triển khai tự động và thực thi thành công
  • Truy cập địa chỉ DNS Load Balancer của ECS Cluster friendreminders
  • Xác nhận APIs được thực thi với những kết quả cập nhật từ source code

Kết luận

Trong bài viết này, chúng ta đã thiết lập hoạt động CI/CD cho ứng dụng FriendReminders dựa trên các dịch vụ AWS như CodeCommit, CodeBuild, CodeDeploy và CodePipeline. Để thực hiện được những thiết lập này, chúng ta cũng phải xây dựng sẵn một môi trường thực thi và triển khai ứng dụng dựa trên Elastic Container Service (theo mô hình EC2-based Service hoặc Fargate Service). Với thiết lập này, mỗi khi source code thay đổi trên CodeCommit, quá trình biên dịch, kiểm thử và triển khai sẽ được tự động kích hoạt, giúp việc phát triển ứng dụng thuận lợi hơn. Tuy nhiên, vẫn còn những điểm hạn chế nhất định. Một trong số đó là hoạt động thiết lập CI/CD vẫn còn tương đối phức tạp, có nhiều bước thực hiện thủ công thông qua câu lệnh, gây tốn thời gian và hiệu quả tái sử dụng không cao. Để khắc phục nhược điểm này, trong bài tiếp theo - AWS CodePipeline Revised, chúng ta sẽ tối ưu hoá các bước thiết lập trên thông qua dịch vụ AWS CDK.



Copyright © 2019-2022 Tuan Anh Le.