- vừa được xem lúc

Serverless Series (Golang) - Bài 9 - Codepipeline Notification with AWS Chatbot and AWS SNS

0 0 16

Người đăng: Quân Huỳnh

Theo Viblo Asia

Giới thiệu

Chào các bạn tới với series về Serverless, ở bài trước chúng ta đã tìm hiểu về cách dựng CI/CD với Codepipeline. Ở bài này chúng ta sẽ làm thêm phần notification cho Codepipeline khi nó chạy xong hoặc trong quá trình build bị lỗi gì đó, bằng cách sử dụng SNS + Lambda và AWS Chatbot + Slack.

Đây là một nhu cầu rất thực tế khi ta làm CI/CD, ta không thể suốt ngày lên trên AWS Console để xem pipeline của ta đã chạy xong hay chưa, với lại khi làm một team thì cả PM, dev và tester đều cần biết là CI/CD chạy xong chưa để họ nhảy lên sản phẩm của ta kiểm tra chức năng mới. Hệ thống mà ta sẽ xây dựng như sau.

image.png

Ta sẽ dùng SNS + Lambda để gửi thông báo tới client qua email và dùng AWS Chatbot để gửi thông báo tới client qua Slack channel.

Provisioning previous system

Mình sẽ dùng terraform để tạo lại hệ thống, nếu các bạn muốn biết cách tạo bằng tay từng bước thì các bạn xem từ bài 2 nhé. Các bạn tải source code ở git repo này https://github.com/hoalongnatsu/serverless-series.git.

Di chuyển tới folder bai-9/terraform-start. Ở file policies/lambda_policy.json, dòng "Resource": "arn:aws:dynamodb:us-west-2:<ACCOUNT_ID>:table/books", cập nhật lại <ACCOUNT_ID> với account id của bạn.

Tiếp theo ở file vars.tf các bạn sẽ thấy có một biến là codestar_connection, ta cần cập nhật lại giá trị cho biến này. Vì resource này cần phải có thêm bước authentication bằng tay nữa, nên ta không sử dụng Terraform để tự động provisioning nó được, các bạn đọc hướng dẫn ở bài trước để tạo connection, sau đó copy ARN của nó và dán vào giá trị default của biến codestar_connection.

variable "codestar_connection" { type = string default = "arn:aws:codestar-connections:<region>:<ACCOUNT_ID>:connection/<id>"
}

Xong sau đó chạy câu lệnh.

terraform init
terraform apply -auto-approve

Sau khi Terraform chạy xong, nó sẽ in ra terminal URL của API Gateway.

base_url = { "api_production" = "https://94x695g7da.execute-api.us-west-2.amazonaws.com/production" "api_staging" = "https://94x695g7da.execute-api.us-west-2.amazonaws.com/staging"
}

Và ta sẽ có hai pipeline cho build và deploy.

image.png

AWS SNS and AWS Chatbot

Amazon Simple Notification Service (SNS) là một hệ thống pub sub, quản lý message, thường được sử dụng để làm hệ thống notification hoặc làm hệ thống quản lý message trong một distributed systems, microservices.

image.png

AWS Chatbot thường được sử dụng để tương tác với các chat room, hiện tại khi mình viết bài này thì chatbot của AWS hỗ trợ hai kênh là Slack và Amazon Chime.

image.png

Implement Notification with SNS

Bây giờ ta sẽ thực hiện việc gửi thông báo tới cho client khi codepipeline được thực thi xong bằng cách sử dụng AWS SNS. Ta thực hiện các bước sau.

  1. Truy cập CodePipeline console https://console.aws.amazon.com/codepipeline, chọn list-function-staging, chọn Notify => Create notification rule.

  1. Nhập vào tên là list-function-staging-notification, chỗ Detail type chọn Full.

  1. Mục Events that trigger notifications ta chọn Failed và Succeeded ở Pipeline execution.

  1. Ở mục Targets, ta chọn SNS topic.

  1. Bấm Create target. Nhập vào tên là codepipeline_sns_alert.

  1. Bấm Create để tạo SNS topic và bấm Submit.

Sau khi xong bước này thì ta đã tạo được Notification Rule và SNS topic. Khi Codepipeline chạy thành công thì nó sẽ gửi một message tới SNS topic này.

Tiếp theo là ta sẽ tạo một subscribe cho SNS trên. Để subscribe đó thực hiện công việc gửi notification tới cho một client bất kì nào mà ta muốn. Ở bài này thì ta sẽ gửi mail tới cho client.

Subscribe with email

Ta thực hiện các bước sau.

  1. Truy cập Amazon SNS console.
  2. Ở menu, chọn Topics, và chọn codepipeline_sns_alert.
  3. Kéo xuống tab Subscriptions, bấm Create subscription.

image.png

  1. Nó sẽ dẫn ta qua trang tạo, ở mục Protocol, chọn Email, sau đó nhập email của bạn.

image.png

  1. Bấm Create subscription. Lúc này Subscription của ta sẽ ở trạng thái Pending confirmation.

image.png

  1. Truy cập email của bạn và confirm subscription. Sau khi ta confirm thì trạng thái của subscription sẽ chuyển sang Confirmed.

image.png

Giờ bạn quay lại CodePipeline console, chạy lại list-function-staging pipeline, khi nó chạy xong bạn kiểm tra email thì sẽ thấy email thông báo của SNS được gửi tới 😁.

image.png

Đây là mẫu email mặc định, nếu ta muốn custom lại email template cho nó đẹp hơn thì ta cần sử dụng Subscribe với protocol là Lambda.

Subscribe with Lambda

Vì SNS chỉ có hỗ trợ một vài loại Subscribe nhất định, nên để mở rộng khả năng gửi thông báo tới nhiều client khác nhau, ta cần sử dụng Subscribe với target là Lambda. Ở trong Lambda này khi ta nhận được message từ SNS, thì ta có thể viết code để nó gửi tới đâu cũng được.

Ví dụ ở bài này ta sẽ dùng Lambda để gửi email tới client với mẫu email template custom. Ở chỗ Subscriptions của codepipeline_sns_alert, ta nhấn vào tạo thêm một Subscription nữa.

image.png

Ta chọn protocol là AWS Lambda, để lấy ARN của Lambda notification function, ta bấm qua Lambda console.

image.png

Và chọn notification để lấy ARN của nó (function này được tạo bằng Terraform ở trên). Sau đó ta bấm tạo Subscription.

image.png

Oke, giờ ta sẽ tiến hành viết code cho Lambda function. Truy cập vào bai-9/code/notification, cập nhật lại file main.go như sau.

package main import ( "context" "crypto/tls" "encoding/json" "fmt" "log" "os" "time" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" mail "github.com/xhit/go-simple-mail/v2"
) type Detail struct { Pipeline string `json:"pipeline"` State string `json:"state"`
} type Message struct { Time time.Time `json:"time"` Detail Detail `json:"detail"`
} const html = `
<html>
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body> <p>Codepipeline %s is %s at %s</p>
</body>
` func handler(ctx context.Context, snsEvent events.SNSEvent) { server := mail.NewSMTPClient() server.Host = "smtp.yandex.com" server.Port = 465 server.Username = os.Getenv("MAIL_USERNAME") server.Password = os.Getenv("MAIL_PASSWORD") server.Encryption = mail.EncryptionSTARTTLS server.TLSConfig = &tls.Config{InsecureSkipVerify: true} smtpClient, err := server.Connect() if err != nil { log.Fatal(err) } // Create email email := mail.NewMSG() email.SetFrom(fmt.Sprintf("From Me <%s>", os.Getenv("MAIL_USERNAME"))) email.AddTo(os.Getenv("MAIL_TO")) email.SetSubject("Codepipeline Notification") for _, record := range snsEvent.Records { snsRecord := record.SNS fmt.Printf("[%s %s] Message = %s \n", record.EventSource, snsRecord.Timestamp, snsRecord.Message) message := &Message{} json.Unmarshal([]byte(snsRecord.Message), message) email.SetBody(mail.TextHTML, fmt.Sprintf(html, message.Detail.Pipeline, message.Detail.State, message.Time)) err = email.Send(smtpClient) if err != nil { log.Fatal(err) } }
} func main() { lambda.Start(handler)
}

Ta sẽ thấy có hai biến env là MAIL_USERNAME với MAIL_PASSWORD, truy cập tới Lambda console, chọn notification function, bấm qua tab Configuration, bấm Edit ở Environment variables, thêm vào hai giá trị sau, nhớ thêm chính xác mật khẩu email của bạn nhé.

image.png

Lưu ý là nếu bạn xài gmail của google thì nhớ bật Less secure app access lên.

image.png

Quay lại CodePipeline console và chạy lại list-function-staging pipeline nhé. Sau đó ta kiểm tra email thì sẽ thấy thông báo với mẫu template custom của ta. Oke, tiếp theo ta sẽ làm usecase thực tế nhất và chắc là được sử dụng khá nhiều, là gửi thông báo tới Slack.

Implement Notification with AWS Chatbot

Đầu tiên ta cần tạo connection giữa AWS Chatbot và Slack. Ta thực hiện các bước sau để integrate Chatbot với Slack.

  1. Truy cập Chatbot console https://console.aws.amazon.com/chatbot/home
  2. Chọn Configure new client. Chọn Slack.

image.png

  1. Nó sẽ dẫn ta qua trang Authentication với Slack, ta bấm Allow. Sau đó nó sẽ dẫn ta quay về AWS console với UI như sau.

image.png

  1. Bấm Configure new channel. Ở trang UI tạo, ta điền vào tên là codepipeline_alert.

image.png

  1. Ở mục Slack Channel, ta chọn Private và điền vào ID của channel (ID nằm trên URL nếu bạn mở Slack bằng website).

image.png

  1. Ở mục Permissions => Role settings chọn Channel IAM role, Role name ta nhập vào là AWSCodeStarNotifications-Chatbot-Slack-Role, mục Policy templates chọn Notification permissions và Channel guardrails ta chọn AWSCodepipelineFullAccess.

image.png

  1. Bấm Configure.

image.png

Oke, Tiếp theo để AWS có thể gửi thông báo tới Slack được, ta cần install AWS App lên trên Slack channel như sau.

image.png

Kiếm AWS Chatbot và Bấm Add.

image.png

Vậy là ta đã xong bước integrate AWS Chatbot với Slack, tiếp theo ta sẽ integrate Codepipeline với Chatbot này để nó có gửi thông báo tới kênh của Slack. Ta làm như sau.

  1. Truy cập tới Codepipeline console, chọn list-function-staging như ở trên và bấm vào Create notification rule. Ở mục name ta nhập vào list-function-staging-slack. Events that trigger notifications ta cũng chọn Failed và Succeeded giống như trên.
  2. Ở mục Targets bây giờ ta sẽ chọn AWS Chatbot.

image.png

  1. Bấm Submit.

Ta chạy lại list-function-staging pipeline, và khi nó chạy xong nó sẽ gửi thông báo tới Slack channel cho ta.

image.png

Oke, vậy là ta đã implement notification cho codepipeline xong 😁.

Kết luận

Vậy là ta đã tìm hiểu xong cách gửi thông báo bằng cách sử dụng SNS và AWS Chatbot. SNS ngoại trừ dùng để gửi thông báo thì nó vẫn còn nhiều chức năng khác rất hữu ích, ở trên chỉ là 1 trong những usecase của nó. Sử dụng AWS Chatbot giúp ta dễ dàng integrate với Slack hơn, tương lai nếu nó có hỗ trợ thêm nhiều chat platform nữa thì việc ta tương tác với các hệ thống chat sẽ dễ dàng hơn nhiều so với việc phải tự viết code. Nếu có thắc mắc hoặc cần giải thích rõ thêm chỗ nào thì các bạn có thể hỏi dưới phần comment. Hẹn gặp mọi người ở bài tiếp theo.

Mục tìm kiếm đồng đội

Hiện tại thì bên công ty mình, là Hoàng Phúc International, với hơn 30 năm kinh nghiệm trong lĩnh vực thời trang. Và là trang thương mại điện tử về thời trang lớn nhất Việt Nam. Team công nghệ của HPI đang tìm kiếm đồng đội cho các vị trí như:

Với mục tiêu trong vòng 5 năm tới về mảng công nghệ là:

  • Sẽ có trang web nằm trong top 10 trang web nhanh nhất VN với 20 triệu lượt truy cập mỗi tháng.
  • 5 triệu loyal customers và có hơn 10 triệu transactions mỗi năm.

Team đang xây dựng một hệ thống rất lớn với rất nhiều vấn để cần giải quyết, và sẽ có rất nhiều bài toàn thú vị cho các bạn. Nếu các bạn có hứng thú trong việc xây dựng một hệ thống lớn, linh hoạt, dễ dàng mở rộng, và performance cao với kiến trúc microservices thì hãy tham gia với tụi mình.

Nếu các bạn quan tâm hãy gửi CV ở trong trang tuyển dụng của Hoàng Phúc International hoặc qua email của mình nha _@.com. Cảm ơn các bạn đã đọc.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Đề thi interview DevOps ở Châu Âu

Well. Chào mọi người, mình là Rice - một DevOps Engineers ở đâu đó tại Châu Âu.

0 0 65

- vừa được xem lúc

In calculus, love also means zero.

Mình nhớ hồi năm 2 đại học, thầy giáo môn calculus, trong một giây phút ngẫu hứng, đã đưa ra cái definition này. Lúc đấy mình cũng không nghĩ gì nhiều.

0 0 51

- vừa được xem lúc

Chuyện thay đổi

Thay đổi là một thứ gì đó luôn luôn đáng sợ. Cách đây vài tháng mình có duyên đi làm cho một banking solution tên là X.

0 0 30

- vừa được xem lúc

Pet vs Cattle - Thú cưng và gia súc

Khái niệm. Pets vs Cattle là một khái niệm cơ bản của DevOps. Bài viết này sẽ nói về sự phát triển của các mô hình dịch vụ từ cốt lõi Pets and Cattle. 1.

0 0 22

- vừa được xem lúc

Git workflow được Google và Facebook sử dụng có gì hay ho

Với developer thì Git hẳn là công cụ rất quen thuộc và không thể thiếu rồi. Thế nhưng có mấy ai thực sự hiểu được Git.

0 0 65

- vừa được xem lúc

Kubernetes - Học cách sử dụng Kubernetes Namespace cơ bản

Namespace trong Kubernetes là gì. Tại sao nên sử dụng namespace.

0 0 96