Hướng dẫn từng bước tạo CI/CD pipeline sử dụng công cụ Code series của AWS

Có một thực tế là: rất nhiều bạn biết rằng có thể sử dụng bộ Code series của AWS để tạo CI/CD pipeline, nhưng lúc triển khai lại gặp nhiều vấn đề không biết phải làm thế nào. Vậy thì bạn hãy đọc bài này. Lưu ý: Code ở bài này mình lấy code sample của AWS

1. Setup môi trường phát triển

Nhiệm vụ 1: Tạo môi trường AWS Cloud9 và tải xuống ứng dụng

Lưu ý: Với bài tập này, sẽ ưu tiên sử dụng region us-west-2 (Ohio)

  • Chọn Services, tìm kiếm Cloud9.

  • Chọn Create environment.

  • Mục Name: điền trivia-app, chọn Next step

  • Giữ như mặc định ở mục Environment settings và chọn Next step.

  • Chọn Create environment.

  • Launch environment và tải về source code bằng cách chạy trong Cloud9 terminal:

wget https://aws-tc-largeobjects.s3.us-west-2.amazonaws.com/DEV-AWS-MO-DevOps-C1/downloads/trivia-app.zip -O ~/trivia-app.zip
unzip -o ~/trivia-app.zip

Hoặc tải file zip ở đây: https://drive.google.com/file/d/1q9xj-6B5cTDLeU5olxObqOrs2CfPLBSP/view?usp=sharing

Nhiệm vụ 2: Tạo backend infrastructure

Trong cloud9 terminal:

cd trivia-app
sam build
sam deploy --guided

AWS SAM settings:

Stack Name [sam-app]: trivia-app
AWS Region [us-west-2]: <Press Enter or Return>
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: <Press Enter or Return>
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: <Press Enter or Return>
Save arguments to configuration file [Y/n]: <Press Enter or Return>
SAM configuration file [samconfig.toml]: <Press Enter or Return>
SAM configuration environment [default]: <Press Enter or Return>

Sau khi setup, bạn sẽ thấy một dòng confirm như sau:

Successfully created/updated stack - trivia-app in us-west-2

2. Từ mục Outputs trả về, copy Websocket value, trông nó như sau:

wss://xxxxxxxxxx.execute-api.us-west-2.amazonaws.com/Prod

Nhiệm vụ 3: Test front-end ở Cloud9

  • Update file trivia-app/front-end-react/src/config.js với Websocket endpoint bạn copy được ở bước trước.

  • Chạy các lệnh sau:

nvm install lts/gallium
nvm alias default lts/gallium
cd front-end-react/
npm install
npm run start
  • Trong Cloud9, chọn Tools \> Preview > Preview Running Application.
  • Dừng việc preview ứng dụng bằng cách nhấn Ctrl + C

Nhiệm vụ 4: Deploy front-end lên S3 bucket

  • Tạo và sync lên s3 (lưu ý với câu lệnh sync thì s3 bucket phải enable ACL):
aws s3 mb s3://<your_initials><numbers>-trivia-app-bucket/
npm run build
aws s3 sync --acl public-read build s3://<your_initials><numbers>-trivia-app-bucket/

Nhiệm vụ 5: Đẩy app lên source control tool

  • Lên AWS console, tìm kiếm CodeCommit, và chọn Create repository

  • Điền tên repo là trivia-app rồi nhấn Create

  • Quay lại Cloud9 chạy các lệnh sau:

git config --global user.name "<REPLACE_WITH_YOUR_NAME>"
git config --global user.email <REPLACE_WITH_YOUR_EMAIL>

cd ~/environment/trivia-app/
git init
git checkout -b main
git add .
git commit -m "initial commit"
git remote add origin codecommit://trivia-app
git push origin main

2. Test app ở dưới local

Nhiệm vụ 1: Chạy unit tests

  • Trong cloud9:
cd ~/environment/trivia-app

pip3 install -U -r back-end-python/gameactions/requirements.txt
pip3 install -U -r back-end-python/tests/requirements.txt
./local_build.sh

Bạn sẽ thấy pylint thể hiện static analysis:

------------------------------------
Your code has been rated at 10.00/10

Và pytest chạy unit tests:

back-end-python/tests/unit/test_handler.py .........

Kết quả cuối cùng bạn sẽ nhận được 1 file report: /trivia-app/htmlcov

Nhiệm vụ 2: Chạy integration test

Chạy lệnh sau trong Cloud9:

AWS_SAM_STACK_NAME=trivia-app pytest -s back-end-python/tests/integration/test_api_gateway.py

Kết quả, bạn sẽ nhận được kết quả: 1 passed

Nhiệm vụ 3: Update code và unit tests

  • Mở file trivia-app/back-end-python/gameactions/app.py

  • Kéo xuống tìm function tên là trivia_calculate_scores

  • Update the code. Thay thế score += 10 thành score += 20 và lưu lại.

  • Chạy thử câu lệnh ./local_build.sh để kiểm tra. Bạn sẽ thấy lúc lại test tên là test_trivia_calculate_scores_correct bị fail:

============== FAILURES =======================
_______ test_trivia_calculate_scores_correct __________

Để hết fail, bạn sẽ phải sửa cả unit test để match với code.

  • Mở file trivia-app/back-end-python/tests/unit/test_handler.py

  • Tìm kiếm hàm test_trivia_calculate_scores_correct

  • Tại TABLE.update_item.assert_called_with của hàm, tìm kiếm field AttributeUpdates và thực hiện update Value từ 10 thành 20

AttributeUpdates={'score': {'Value': 20, 'Action': 'PUT'}}
  • Bạn sẽ cần update cả app.MANAGEMENT.post_to_connection.assert_has_calls (tests API Gateway Websocket calls). Thay thế giá trị của score từ 10 thành 20:
mock.call(Data='{"action": "playerlist", "players": [{"connectionId": "connection-1", "playerName": "AliceBlue", "score": 20, "currentPlayer": true}]}', ConnectionId='connection-1'),

Nhiệm vụ 4: Commit source control

Trong Cloud9, chạy các lệnh sau:

git add *
git commit -m "Scores now increment by 20"
git push origin main

3. Sử dụng AWS CodeBuild

Nhiệm vụ 1: Tạo buildspec file

  • Trong thư mục trivia-app ở Cloud9, chọn tạo New file

  • Rename thành buildspecs/unittests.yaml. Khi được hỏi Confirm move to a new folder thì hãy nhấn Yes.

  • Mở file vừa tạo và dán đoạn code sau:

version: 0.2


phases:
  install:
    commands:
      - pip3 install -U -r back-end-python/gameactions/requirements.txt
      - pip3 install -U -r back-end-python/tests/requirements.txt

  build:
    commands:
      - pylint --fail-under=8 back-end-python/gameactions/app.py
      - pytest back-end-python/tests/unit --junit-xml=unittests.xml --cov-report=xml --cov=gameactions --cov-branch

reports:
  UnitTests:
    files:
      - 'unittests.xml'
  NewCoverage: #
    files:
      - 'coverage.xml'
    file-format: COBERTURAXML
  • Lưu lại

  • Commit lên AWS CodeCommit:

git add *
git commit -m "adding a unittests buildspec"
git push origin main

Nhiệm vụ 2: Run unit tests ở Codebuild

  • Trên AWS Console, tìm kiếm CodeCommit > Repositories > trivia-app

  • Chọn mục Build ở phần navigation pane, và chọn Build projects.

  • Chọn Create build project, các setting như sau:


    Project name: trivia-unittests
    Repository: trivia-app
    Branch: main
    Operating system: Ubuntu
    Runtime(s): Standard
    Image: aws/codebuild/standard:5.0
    Build specifications: Keep Use a buildspec file selected
    Buildspec name - optional: buildspecs/unittests.yaml
  • Chọn Create build project.

  • Chọn Start build.

  • Để xem chi tiết log, chọn Tail logs.

  • Khi build báo Succeeded, close log window

  • Mở tab Reports và xem các Test reports.

4. Tạo pipeline

Nhiệm vụ 1: Tạo pipeline

  • Mở AWS Console, tìm kiếm CodePipeline

  • Chọn Create pipeline

  • Đặt tên pipeline là trivia-pipeline và nhấn Next.

  • Ở bước Add source stage, thiết lập như sau:


    Source provider: AWS CodeCommit
    Repository name: trivia-app
    Branch name: main
  • Chọn Next.

  • Tại bước Add build stage, thiết lập như sau:


    Build provider: AWS CodeBuild
    Project name: trivia-unittests
  • Chọn Next

  • Trong bước Add deploy stage, chọn Skip deploy stage

  • Ở bước Review, chọn Create pipeline. Bạn sẽ thấy thông báo Success.

Nhiệm vụ 2: Tạo feature branch

  • Chạy lệnh ở Cloud9:
cd ~/environment/trivia-app
git checkout -b feature-bonus-scores

Nhiệm vụ 3: Edit code

  • Mở file trivia-app/back-end-python/gameactions/app.py

  • Ở function trivia_calculate_scores, tìm đoạn code set last_answer

  • Ngay dưới dòng tiếp theo, điền thêm đoạn code xử lý bonus như sau:

last_answer = connection["lastAnswer"] if "lastAnswer" in connection else ""
bonus = question["bonus"] if "bonus" in question else 0
  • Bạn sẽ cần sửa code ở phần tính score:
Trước:
if last_question_id == question["id"] and last_answer == question["answer"]:
    score += 20

Sau:
if last_question_id == question["id"] and last_answer == question["answer"]:
        score += 20 + bonus
  • Lưu file lại

  • Mở file trivia-app/back-end-python/tests/unit/test_handler.py và replace SCORES_EVENT bằng 1 event mới bao gồm cả điểm bonus như sau:

SCORES_EVENT = {
"gameid" : "01234567012301230123012345678901",
"questions" : [
    { "id" : "q-1111", "question" : "Good question?", "answer" : "Yes", "bonus": 20},
],
"iterator" : { "questionpos" : 0 }
}
  • Lưu lại file

  • Tìm phần test_trivia_calculate_scores_correct và thay đổi assert statements thành Score là 40:

app.TABLE.update_item.assert_called_with(
    Key={'gameId': '01234567012301230123012345678901', 'connectionId': 'connection-1'},
    AttributeUpdates={'score': {'Value': 40, 'Action': 'PUT'}}
)

app.MANAGEMENT.post_to_connection.assert_has_calls([
    mock.call(Data='{"action": "playerlist", "players": [{"connectionId": "connection-1", "playerName": "AliceBlue", "score": 40, "currentPlayer": true}]}', ConnectionId='connection-1'),
    mock.call(Data='{"action": "gameover"}', ConnectionId='connection-1')
    ])
  • Lưu lại file, và kiểm tra unit test bằng cách chạy lệnh trong Cloud9:
./local_build.sh

Lúc này bạn sẽ thấy test passed.

Nhiệm vụ 4: Commit thay đổi và merge nhánh feature vào main

  • Chạy lệnh trong Cloud 9:
git status

git add *
git commit -m "new bonus score feature"
git push origin feature-bonus-scores
  • Quay lại màn hình AWS CodeCommit, mở repo trivia-app, và chọn Create pull request trong phần navigation panel

Destination: main, Source: feature-bonus-scores.

  • Chọn Compare, và kéo xuống dưới kiểm tra các thay đổi

  • Trong Details > Title, nhập: New feature: Bonus scoring, chọn Create pull request.

  • Chọn Merge.

  • Tick chọn 2 lựa chọn: Fast forward mergeDelete source branch feature-bonus-scores after merging?, sau đó Merge pull request.

  • Vào màn hình AWS CodePipeline và chọn trivia-pipline, bạn có thể review Build section:

  • Chạy lệnh trong Cloud9:
git checkout main
git pull origin main
git log

Vậy là đến đây bạn đã hoàn thành 1 pipeline build và test cho app của mình.

Lúc này bạn có thể xóa các resource đã tạo ra và thực hiện lab mới, deploy code vào EC2 instance.

5. Set up CodeDeploy

Nhiệm vụ 1: Set up IAM

  • Chọn IAM trong AWS Console

  • Tạo một Role với các setup như sau:


    Select type of trusted entity: Keep AWS service selected
    Choose a use case: CodeDeploy
    Select your use case: CodeDeploy
  • Giữ nguyên các setup khác
  • Đặt tên role là CodeDeployServiceRole và chọn Create role.

  • Tạo 1 role khác với các setting như sau:


    Select type of trusted entity: Again, keep AWS service selected
    Choose a use case: EC2
  • Attach cho role này policy AmazonS3FullAccessAmazonSSMManagedInstanceCore

  • Đặt tên role là EC2S3FullAccess và tạo Create role

Nhiệm vụ 2: Set up EC2 instance

  • Mở AWS Console, tìm kiếm EC2

  • Trong mục Instance, chọn Launch instances

  • AMI chọn Amazon Linux 2 AMI (HVM), SSD Volume Type, type t2.micro

  • Chọn Next: Configure Instance Details.

  • Trong phần Configure Instance Details, setup như sau:


    Auto-assign Public IP: Enable
    IAM role: EC2S3FullAccess
  • Chọn Next: Add Storage, giữ nguyên default phần này, chọn Next: Add Tags.

  • Trong phần Add Tag, setting như sau:


    Key: Name
    Value: TEST-environment
  • Chọn Next: Configure Security Group, và configure như sau:
    Type: HTTP
    Source: Anywhere
  • Chọn Review and Launch và chọn Launch.

  • Bạn không cần key pair, nên sẽ chọn Proceed without a key pair khi được hỏi key pair

Nhiệm vụ 3: Cài đặt CodeDeploy agent

  • Chọn instance vừa tạo, và chọn Connect

  • Trong terminal của instance, chạy lệnh:

sudo yum update -y
sudo yum install ruby -y
sudo yum install wget -y
  • Cài đặt agent:
cd ~
wget https://aws-codedeploy-us-west-2.s3.us-west-2.amazonaws.com/latest/install
chmod +x ./install

sudo service codedeploy-agent status

6. Deploy AWS CodeDeploy Revisions

Nhiệm vụ 1: Tạo S3 bucket, và upload zip file

  • Mở AWS Console, chọn S3, chọn Create bucket

  • Đặt tên bucket theo ý bạn, có thể đặt dạng: devops-exercise2-<your_initials>-<random_number>

  • Nhớ chọn region bucket cùng region bạn đã tạo CodeDeploy

  • Sau khi tạo bucket, upload file sau lên bucket:

https://aws-tc-largeobjects.s3.us-west-2.amazonaws.com/DEV-AWS-MO-DevOps-C2/downloads/Blog.zip

Nhiệm vụ 2: Tạo và cài đặt CodeDeploy application:

  • Mở AWS Console, chọn CodeDeploy

  • Chọn Applications trong navigation pane

  • Chọn Create application và configure như sau:

Application name: TestApplication
Compute platform: EC2/On-premises
  • Chọn Create application.
  • Chọn Create deployment group với các configure như sau:

    Deployment group name: TestDeploymentGroup
    Service role: CodeDeployServiceRole
    Deployment type: Keep In-place selected
    Environment configuration: Amazon EC2 instances
        Key: Name
        Value: TEST-environment
    Agent configuration with AWS Systems Manager > Install AWS CodeDeploy Agent: Never
    Deployment settings: Keep CodeDeployDefault.AllAtOnce selected
    Load balancer: Clear Enable load balancing
  • Chọn Create deployment với các configure như sau:

    Deployment group: Keep TestDeploymentGroup selected
    Revision location: Use the S3 bucket and Blog.zip file that you created previously (example URL format: s3://devops-exercise2-<your_initials>-<random_number>/Blog.zip)
    Revision file type: .zip
    Deployment description: Feel free to add a description
  • Trong phần Deployment lifecycle events, chọn Instance ID

  • Chọn TEST-environment instance

  • Copy Public IPv4 address hoặc Public IPv4 DNS address và dán lên trình duyệt để xem kết quả.

Nhiệm vụ 3: Upload new revisions

  • Giải nén file Blog.zip bạn đã download về máy.

  • Mở file index.html và thay đổi:

- Tìm kiếm  background-color: #0000FF và chuyển thành background-color: #FFC0CB;
- Tìm kiếm Version 1 và chuyển thành Version 2
  • Lưu lại và lại nén thành file Blog.zip

  • Vào AWS Console, tìm kiếm S3, xóa file Blog.zip cũ đi và upload phiên bản mới lên

  • Vào AWS Console, tìm kiếm CodeDeploy

  • Trong navigation pane, chọn Deploy > Application, và chọn TestApplication

  • Chọn TestDeploymentGroup, chọn Create deployment, và configure như sau:


    Revision location: Again, use the S3 location that you used for the previous deployment (example format: s3://devops-exercise2-<your_initials>-<random_number>/Blog.zip)
    Revision file type: .zip
    Deployment description: Deploys version 2 of the application to the TEST environment
  • Tại phần Deployment lifecycle events, chọn Instance ID

  • Chọn TEST-environment

  • Copy Public IPv4 address hoặc Public IPv4 DNS address và dán lên trình duyệt để xem kết quả.

7. Monitor các thay đổi với pipeline

Nhiệm vụ 1: Set up Cloudformation template

  • Tải cloudformation template tại link sau:

https://aws-tc-largeobjects.s3.us-west-2.amazonaws.com/DEV-AWS-MO-DevOps-C3/downloads/final_pipeline.yaml

  • Vào AWS, tìm kiếm CloudFormation

  • Chọn Create stack, upload stack đã download ở bước trước

  • Trong phần Specify stack details, configure như sau:


    Stack name: final-pipeline
    CodePipelineName: final-pipeline
  • Để mặc định các option khác. Tại phần Review final-pipeline, chọn I acknowledge that AWS CloudFormation might create IAM resources with custom names và chọn Create stack.

Nhiệm vụ 2: Tạo SNS topics

  • Vào AWS Console, chọn SNS

  • Chọn Topics > Create topic

  • Trong phần Details, configure như sau:


    Type: Standard
    Name: pipeline-topic

Giữ các configure khác như mặc định, và chọn Create topic.

  • Trong tab subscription, tạo Create subscription và configure trong phần Details như sau:

    Protocol: Email
    Endpoint: Enter your email address

Bạn sẽ nhận được email confirm subscription, hãy click link confirm để xác nhận nhận thông báo

Nhiệm vụ 3: Tạo EventBridge rule

  • Mở AWS Console, tìm EventBridge.

  • Tạo Rule với configure như sau:


    Name: pipeline-rule
    Define pattern: Event pattern
    Event matching pattern: Pre-defined pattern by service
    Service provider: AWS
    Service name: CodePipeline
    EventType: CodePipeline Pipeline Execution State Change
    Target: SNS topic
    Topic: pipeline-topic
  • Nhấn Create để tạo rule

Nhiệm vụ 4: Chạy Codepipeline

  • Mở Codepipeline, chọn pipeline tên là final-pipeline

  • Nhấn Release change để trigger 1 on demand pipeline run.

Lúc này, bạn sẽ có email thông báo về pipeline state change, hãy check mail để xem kết quả. Dạng thông báo kiểu như sau:

"state":"STARTED","version":1.0}}

"state":"SUCCEEDED","version":1.0}}

Bài lab tới đây là kết thúc. Hãy nhớ dọn dẹp tài nguyên đã tạo ra nhé!