Link Search Menu Expand Document

AWS CodeComit

AWS CodeCommit là dịch vụ quản lý phiên bản source code cho các ứng dụng - version control service. Với dịch vụ này, chúng ta có thể lưu trữ và quản lý các tài nguyên phát triển ứng dụng bao gồm source code, tài liệu, binary files một cách an toàn.

Để quản lý source code ứng dụng FriendReminders, chúng ta thực hiện các bước:

  1. Cài đặt và cấu hình AWS CodeCommit
  2. FriendReminders Repository
  3. Tích hợp Repository và AWS SNS / Subscribers
    1. Simple Notification Service
    2. Email Subscriber
    3. AWS Lambda Subscriber

Cài đặt và cấu hình AWS CodeCommit

Tạo AWS user

Sử dụng AWS CLI:

  • Tạo một IAM Group với tên DevOps và IAM User với tên Alex.
  • Bổ sung User Alex vào Group DevOps

Tham khảo Identity and Access Management

Cấp quyền cho user mới để sử dụng AWS CodeCommit service

Quyền sử dụng tài nguyên AWS thường được cung cấp qua việc gán policy cho IAM Group. Trong trường hợp này, chúng ta muốn các user trong group DevOps có quyền sử dụng CodeCommit.

  • AWS định nghĩa sẵn policy AWSCodeCommitPowerUser với đầy đủ quyền sử dụng dịch vụ CodeCommit, do đó chúng ta chỉ cần gắn policy này vào group DevOps qua lệnh:
aws iam attach-group-policy --group-name DevOps  --policy-arn arn:aws:iam::aws:policy/AWSCodeCommitPowerUser
  • Xác nhận group DevOps được gắn policy mới thành công với lệnh:
aws iam list-attached-group-policies --group-name DevOps

Output câu lệnh:

{
    "AttachedPolicies": [
        {
            "PolicyName": "AWSCodeCommitPowerUser",
            "PolicyArn": "arn:aws:iam::aws:policy/AWSCodeCommitPowerUser"
        }
    ]
}
  • Trên AWS Console, có thể xác nhận kết quả khi vào IAM -> Users -> Alex

AWS User Permissions AWS User Permissions

Tạo credential cho user mới

Trong các ví dụ, chúng ta sử dụng git command để đồng bộ source code (push/pull) giữa môi trường Development và CodeCommit repository. Các yêu cầu gửi đi qua giao thức SSH và xác thực dựa trên public/private key.

  • Để tạo ra publish/private key files, trên MacOS sử dụng lệnh:
ssh-keygen

Khai báo tên file của ssh key: codecommit_rsa.

Output của lệnh ssh-keygen:

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/anh/.ssh/id_rsa): /Users/anh/.ssh/codecommit_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in codecommit_rsa.
Your public key has been saved in codecommit_rsa.pub.
The key fingerprint is:
SHA256:AYVqzhToMUocUkRKthtjsD0Wrv1xgXI12Ck9FDnVUvI anh@Anhs-MBP
The key's randomart image is:
+---[RSA 3072]----+
|+B*. =*B+o.      |
|=B=.+oOo.o.      |
|+B*oo+.o..E      |
|o+=++  . .       |
|...=. . S        |
|   .oo           |
|    .            |
|                 |
|                 |
+----[SHA256]-----+

Chú ý: trong câu lệnh trên, folder /Users/anh/.ssh/ được sử dụng làm ví dụ. Tuỳ theo hệ điều hành, đường dẫn của folder có thể thay đổi.

Folder: /Users/anh/.ssh/id_rsa có các files:

  • Private key: codecommit_rsa
  • Public key: codecommit_rsa.pub

Cấu hình git sử dụng credential

  • Để sủ dụng SSH keys cho AWS CodeCommit với user Alex, trong folder .ssh sử dụng lệnh:
aws iam upload-ssh-public-key --user-name Alex --ssh-public-key-body file://codecommit_rsa.pub
  • Trên AWS Console, IAM -> Users -> Alex -> Security Credentials, chúng ta thấy key mới đã thêm vào (APKA2TUMMYZVRRTWVD62)

SSH Key AWS CodeCommit Cấu hình SSH Key trên AWS CodeCommit

  • Trong folder .ssh tạo file mới với tên gọi config cùng nội dung:
Host git-codecommit.*.amazonaws.com
User APKA2TUMMYZVRRTWVD62
IdentityFile ~/.ssh/codecommit_rsa

Chú ý khai báo chính xác các giá trị tương ứng với UserIdentityFile.

  • Giới hạn quyền truy cập đối với file config:
chmod 600 config
  • Xác nhận kết quả cấu hình CodeCommit:
ssh git-codecommit.us-east-2.amazonaws.com

Việc cài đặt thành công khi Terminal hiển thị kết quả thông báo:

The authenticity of host 'git-codecommit.us-east-2.amazonaws.com (52.95.20.253)' can't be established.
RSA key fingerprint is SHA256:3lBlW2g5xn/NA2Ck6dyeJIrQOWvn7n8UEs56fG6ZIzQ.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'git-codecommit.us-east-2.amazonaws.com,52.95.20.253' (RSA) to the list of known hosts.
You have successfully authenticated over SSH. You can use Git to interact with AWS CodeCommit. Interactive shells are not supported.Connection to git-codecommit.us-east-2.amazonaws.com closed by remote host.
Connection to git-codecommit.us-east-2.amazonaws.com closed.

Trong trường hợp có lỗi, chúng ta cần kiểm tra lại nội dung file config, so sánh với thông tin về public SSH key đã upload trên AWS Console, đảm bảo các giá trị được cập nhật chính xác.


FriendReminders Repository

Dựa trên cấu hình CodeCommit từ phần trước, chúng ta sẽ tạo ra một Repository để quản lý source code cho ứng dụng FriendReminders.

  • Câu lệnh tạo repository FriendReminders:
aws codecommit create-repository --repository-name FriendReminders --repository-description "A simple demo of microservice"

Output cho biết thông tin chi tiết của repository:

{
    "repositoryMetadata": {
        "accountId": "729365137003",
        "repositoryId": "41b1cd08-6f8d-4fec-8587-4674b0b7aba6",
        "repositoryName": "FriendReminders",
        "repositoryDescription": "A simple demo of microservice",
        "lastModifiedDate": "2020-08-26T19:42:43.653000+10:00",
        "creationDate": "2020-08-26T19:42:43.653000+10:00",
        "cloneUrlHttp": "https://git-codecommit.ap-southeast-2.amazonaws.com/v1/repos/FriendReminders",
        "cloneUrlSsh": "ssh://git-codecommit.ap-southeast-2.amazonaws.com/v1/repos/FriendReminders",
        "Arn": "arn:aws:codecommit:ap-southeast-2:729365137003:FriendReminders"
    }
}

Output cho biết giá trị cloneUrlSsh của repository:

ssh://git-codecommit.ap-southeast-2.amazonaws.com/v1/repos/FriendReminders
  • Dựa trên giá trị này, thực hiện copy repository về môi trường Development:
git clone ssh://git-codecommit.ap-southeast-2.amazonaws.com/v1/repos/FriendReminders

Output:

Cloning into 'FriendReminders'...
The authenticity of host 'git-codecommit.ap-southeast-2.amazonaws.com (103.8.175.151)' can't be established.
RSA key fingerprint is SHA256:nYp+gHas80HY3DqbP4yanCDFhqDVjseefVbHEXqH2Ec.
Are you sure you want to continue connecting (yes/no/[fingerprint])? y
Please type 'yes', 'no' or the fingerprint: yes
Warning: Permanently added 'git-codecommit.ap-southeast-2.amazonaws.com,103.8.175.151' (RSA) to the list of known hosts.
warning: You appear to have cloned an empty repository.

Câu lệnh tạo folder FriendReminders nơi sử dụng để lưu trữ source code của ứng dụng FriendReminders.


Tích hợp Repository và AWS SNS / Subscribers

Sau khi lưu trữ source code trên CodeCommit Repository, chúng ta có thể tích hợp với các dịch vụ AWS khác để mở rộng thêm nhiều chức năng. Trong phần này, chúng ta sẽ kết hợp dịch vụ AWS Simple Notification Service (SNS) và CodeCommit Repository. Mỗi khi source code trên main branch trong Repository thay đổi, message tự động gửi đến một SNS Topic. Thành phần này đóng vai trò trung gian giữa publishersubcribers. Trong trường hợp này, CodeCommit là một publisher gửi message đến SNS Topic thông báo source code thay đổi. Những subcribers trên SNS Topic sẽ nhận được message và thực hiện những xử lý tương ứng.

CICD Integration Tích hợp AWS CodeCommit với SNS và Lambda function

Trong thiết kế trên SNS Topic có hai subcribers:

  • Email Notification: gửi email thông báo source code trên main branch đã thay đổi
  • Lambda: SNS kích hoạt việc thực thi của AWS Lambda, yêu cầu thực hiện CodeBuild

Dựa trên yêu cầu từ AWS Lambda, CodeBuild service thực hiện quá trình biên dịch, kiểm thử và tạo ra Docker Image chứa bản cập nhật mới của ứng dụng. Sau đó, Docker Image sẽ được đẩy lên Docker Register Repository, từ đó triển khai ra các môi trường khác nhau dựa trên CodeDeploy service.

Trong nội dung của phần thực hành này, chúng ta chỉ tập trung vào thiết lập liên kết giữa CodeCommit với SNS / Subcribers (Email Notification, Lambda). Logic của hàm Lambda đơn giản là ghi một dummy log xuống CloudWatch Log mỗi khi source code có sự thay đổi.

Simple Notification Service

  • Để tạo SNS Topic, sử dụng lệnh sau trên Terminal:
aws sns create-topic --name PushMainBranchReminderFriendsTopic

Output trả về giá trị định danh Amazon Resource Name (ARN) của Topic tạo ra:

{
    "TopicArn": "arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic"
}
  • Tạo file trigger.json, liên kết SNS Topic và CodeCommit Repository
    • repositoryName: Tên của CodeCommit Repository
    • destinationArn: Địa chỉ ARN của SNS Topic
{
  "repositoryName": "FriendReminders",
  "triggers": [
      {
          "name": "PushMainBranchReminderFriendsTrigger",
          "destinationArn": "arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic",
          "customData": "",
          "branches": [
              "master"
          ],
          "events": [
              "all"
          ]
      }
  ]
}
  • Để kiểm tra cấu hình khai báo, sử dụng lệnh:
aws codecommit test-repository-triggers --cli-input-json file://trigger.json

Output

{
    "successfulExecutions": [
        "PushMainBranchReminderFriendsTrigger"
    ],
    "failedExecutions": []
}
  • Cài đặt Trigger lên AWS CodeCommit Repository
aws codecommit put-repository-triggers --cli-input-json file://trigger.json

Output

{
    "configurationId": "553da9c5-3124-4112-b5c8-1f0dd520d7ae"
}
  • Kiểm tra danh sách Triggers trong Repository FriendReminders:
aws codecommit get-repository-triggers --repository-name FriendReminders

Output

{
    "configurationId": "553da9c5-3124-4112-b5c8-1f0dd520d7ae",
    "triggers": [
        {
            "name": "PushMainBranchReminderFriendsTrigger",
            "destinationArn": "arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic",
            "customData": "",
            "branches": [
                "master"
            ],
            "events": [
                "all"
            ]
        }
    ]
}

Xác nhận Trigger trên AWS Console CodeCommit -> Source -> Repositories -> Settings

CodeCommit Triggers CodeCommit Trigger for SNS


Email Subscriber

  • Thực hiện subscribe địa chỉ Email với SNS Topic:
aws sns subscribe --topic arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic --protocol email --notification-endpoint anhltanz@gmail.com

Output cho biết trạng thái của việc subscription đang là Pending

{
    "SubscriptionArn": "pending confirmation"
}
  • Kiểm tra Inbox email từ AWS và lựa chọn Confirm subscription trong nội dung email:
You have chosen to subscribe to the topic: 
arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic

To confirm this subscription, click or visit the link below (If this was in error no action is necessary): 
Confirm subscription
  • Kiểm tra kết quá quả trình đăng kí:
aws codecommit test-repository-triggers --cli-input-json file://trigger.json

Xác nhận email gửi đến Inbox với nội dung:

Hello,
The following repository in AWS CodeCommit has changed: FriendReminders
The repository was changed by the IAM user: operator
More info: https://console.aws.amazon.com/codesuite/codecommit/repositories/FriendReminders/browse?region=ap-southeast-2
Branches: master

AWS Lambda Subscriber

AWS Lambda là một dịch vụ thường được sử dụng trong mô hình kiến trúc Serverless. Lambda function cho phép chúng ta đóng gói và thực thi các xử lý logic của một ứng dụng và không cần phải quan tâm đến việc cấp phát các tài nguyên tính toán liên quan.

Hoạt động của Lambda function dựa trên kiến trúc hướng sự kiện Event-drive Architecture. Cụ thể hơn, việc thực thi một Lambda function dựa trên trigger từ những sự kiện nhất định.

Trong ví dụ này, chúng ta kết hợp trigger từ “sự kiện” source code trên main branch của CodeCommit Repository được cập nhật, từ đó thực thi Python Lambda function để in ra thông tin dummy log trên màn hình Terminal hoặc CloudWatch.

Các bước thực hiện:

1. Tạo project

  • Tạo một folder lambda-function chứa source code và cấu hình cho Lambda project.

  • Trong folder lambda-function, tạo file lambda_function.py:

import os

def entrypoint(event, context):
    print('Starting a new build ...')
    print('## ENVIRONMENT VARIABLES')
    print(os.environ)
    print('## EVENT')
    print(event)

Trong file lambda_function, chúng ta tạo một handler function entrypoint. Function dựa trên package os để in ra giá trị của event và thông tin của các biến môi trường os.environ được lambda sử dụng.

  • Tạo zip file chứa ``lambda_function.py`:
zip function.zip lambda_function.py
  • Để function có quyền thực thi và ghi log ra CloudWatch, chúng ta cần định nghĩa một service role. Service role cho phép chúng ta khai báo principal (trong trường hợp này là Lamba function) và bổ sung các policy vào service role cho phép principal có quyền sử dụng các tài nguyên khác trên AWS.

Trên môi trường Development, tạo một file trust-policy.json cung cấp các khai báo để tạo service role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Nội dung của trust-policy.json cho phép service principal lambda.amazonaws.com, sử dụng dịch vụ AWS STS (Security Token Service) để có được - assume permission trong các policy attach vào service role.

Trong cùng folder với trust-policy.json, sử dụng lệnh create-role để tạo service role CodeBuildTriggerLambdaRole:

aws iam create-role --role-name CodeBuildTriggerLambdaRole --assume-role-policy-document file://trust-policy.json

Output

{
    "Role": {
        "Path": "/",
        "RoleName": "CodeBuildTriggerLambdaRole",
        "RoleId": "AROA2TUMMYZVVW5UQX7S4",
        "Arn": "arn:aws:iam::729365137003:role/CodeBuildTriggerLambdaRole",
        "CreateDate": "2020-09-04T03:28:52+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "lambda.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}

Trên AWS Console -> IAM, service role CodeBuildTriggerLambdaRole đã tạo ra nhưng chưa bao gồm permission policy nào:

Service Role Output Service Role cho AWS Lambda function

Bổ sung Policy AWSLambdaBasicExecutionRole vào service role CodeBuildTriggerLambdaRole:

aws iam attach-role-policy --role-name CodeBuildTriggerLambdaRole --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

AWSLambdaBasicExecutionRole là một policy đã được định nghĩa sẵn bởi AWS, nội dung policy cho phép một lambda function ghi thông tin ra AWS CloudWatch, nội dung trong policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

Đến bước này, chúng ta đã tạo ra lambda function và định nghĩa service role CodeBuildTriggerLambdaRole. Để triển khai Lambda function lên AWS, trong folder Clambda-function, AWS CLI với lệnh:

aws lambda create-function --function-name CodeBuildTriggerLambda \
--zip-file fileb://function.zip \
--runtime python3.8 \
--handler lambda_function.entrypoint \
--role arn:aws:iam::729365137003:role/CodeBuildTriggerLambdaRole

Output

{
    "FunctionName": "CodeBuildTriggerLambda",
    "FunctionArn": "arn:aws:lambda:ap-southeast-2:729365137003:function:CodeBuildTriggerLambda",
    "Runtime": "python3.8",
    "Role": "arn:aws:iam::729365137003:role/CodeBuildTriggerLambdaRole",
    "Handler": "lambda_function.entrypoint",
    "CodeSize": 264,
    "Description": "",
    "Timeout": 3,
    "MemorySize": 128,
    "LastModified": "2020-09-05T05:30:30.410+0000",
    "CodeSha256": "0nIiFteY2lEbDHSSLXvDJwBLljVshJNteEDzOc3XpxE=",
    "Version": "$LATEST",
    "TracingConfig": {
        "Mode": "PassThrough"
    },
    "RevisionId": "7e556d12-6150-44f8-9909-ae757501487d",
    "State": "Active",
    "LastUpdateStatus": "Successful"
}

Output cho biết giá trị FunctionArn của CodeBuildTriggerLambda:

arn:aws:lambda:ap-southeast-2:729365137003:function:CodeBuildTriggerLambda

Xác thực kết quả bằng cách hiển thị danh sách các AWS Lambda

aws lambda list-functions --region ap-southeast-2

Trên AWS Console, Lambda -> function, chúng ta thấy CodeBuildTriggerLambda được tạo ra với CloudWatch Logs Permission:

CloudWatch Log Permission Output Lambda function được tạo ra với cấu hình Service Role khai báo

2. Thực thi Project

Thực thi project và hiển thị log trên màn hình Terminal:

aws lambda invoke --function-name CodeBuildTriggerLambda  out --log-type Tail \
--query 'LogResult' --output text |  base64 -d

Câu lệnh trên sử dụng base64 để decode thông tin log từ việc thực thi của CodeBuildTriggerLambda.

Output

START RequestId: 8b166972-09c5-4e3f-a3fd-1e0622e8f43f Version: $LATEST
Starting a new build ...
END RequestId: 8b166972-09c5-4e3f-a3fd-1e0622e8f43f
REPORT RequestId: 8b166972-09c5-4e3f-a3fd-1e0622e8f43f	Duration: 1.33 ms	Billed Duration: 100 ms	Memory Size: 128 MB	Max Memory Used: 64 MB	Init Duration: 249.01 ms

Kết quả hiển thị tương tự trên AWS Console, CloudWatch -> CloudWatchLogs:

CloudWatch Output Hiển thị trên CloudWatch khi thực thi Lambda function

Hướng dẫn

Trong trường hợp cần thay đổi source code của CodeBuildTriggerLambda. Chúng ta thực hiện lại các bước:

  • zip function.zip lambda_function.py
  • aws lambda update-function-code --function-name CodeBuildTriggerLambda --zip-file fileb://function.zip

4. Subcribe Lambda với SNS Topic

Dựa trên giá trị ARN của CodeBuildTriggerLambda và SNS Topic PushMainBranchReminderFriendsTopic, thực hiện lệnh subscribe:

aws sns subscribe --topic arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic --protocol lambda --notification-endpoint arn:aws:lambda:ap-southeast-2:729365137003:function:CodeBuildTriggerLambda

Output

{
    "SubscriptionArn": "arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic:ced3e9ab-c24e-4de2-96b9-eee032a041ab"
}

Bổ sung permission cho phép SNS service gọi đến Lamda function

aws lambda add-permission --function-name CodeBuildTriggerLambda --action "lambda:InvokeFunction" --statement-id sns --principal sns.amazonaws.com --region ap-southeast-2 --source-arn arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic

Output

{
    "Statement": "{\"Sid\":\"sns\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:ap-southeast-2:729365137003:function:CodeBuildTriggerLambda\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:sns:ap-southeast-2:729365137003:PushMainBranchReminderFriendsTopic\"}}}"
}

Kiểm tra trên AWS Console, Lambda -> Function -> CodeBuildTriggerLambda:

Lambda Output Liên kết Lambda funciton và SNS Topic

Hướng dẫn

Bằng cách thực thi Lambda function mỗi khi Source Code thay đổi thông qua CodeCommit Trigger và SNS Topic, chúng ta có thể mở rộng logic của Lambda function này, cho phép kích hoạt quá trình biên dịch và triển khai với các dịch vụ khác như AWS CodeBuild, hoặc CodeDeploy. Có thể tham khảo thêm cách thức sử dụng CodeBuildTriggerLambda trong bài thực hành CodeBuild

5. Kiểm ra kết quả subscription

  • Trong FriendReminders, thay đổi source code và push lên CodeCommit
  • Xác nhận Email Notification trong địa chỉ Email Subscriber
  • Xác nhận AWS Lambda function thực thi trong CloudWatch Logs

Tài liệu tham khảo


Copyright © 2019-2022 Tuan Anh Le.