Deploy Spring Boot cùng MySQL lên AWS

1. Tổng quan AWS (Amazon Web Services) là một trong những dịch vụ đám mây phổ biến, cung cấp nhiều gói dịch vụ đám mây. Trong tutorial này, mình sẽ hướng dẫn các bạn deploy Spring Boot app cùng MySQL miễn phí lên AWS sử dụng Elastic Beanstalk. Yêu cầu trước: Python Pip Git Java

1. Tổng quan

AWS (Amazon Web Services) là một trong những dịch vụ đám mây phổ biến, cung cấp nhiều gói dịch vụ đám mây. Trong tutorial này, mình sẽ hướng dẫn các bạn deploy Spring Boot app cùng MySQL miễn phí lên AWS sử dụng Elastic Beanstalk.

Yêu cầu trước:

  • Python
  • Pip
  • Git
  • Java
  • MySQL
  • Maven

2. Lưu ý khi đăng ký tài khoản Amazon AWS

AWS cung cấp cho bạn một tài khoản có bậc miễn phí các dịch vụ trong vòng 12 tháng trong phạm vi cho phép. Mình khuyên là nên deploy những dự án demo nhỏ nhỏ ở hạng mục này thôi, chứ về lâu về dài nên đầu tư một gói lớn hơn.

Ngoài ra, AWS cũng đòi hỏi một thẻ ngân hàng quốc tế để xác nhận danh tính như Visa, Mastercard… và cũng sẽ trừ thử 1 USD (1 USD này sẽ được hoàn trả lại nhưng phí quy đổi ngoại tệ thì không :v). Ở đây, thì mình dùng thẻ MasterCard ảo của Viettel Pay vì mỗi tháng không phải đóng phí.

3. Có sẵn một Spring Boot app để deploy

Mình sẽ sử dụng một app Spring Boot cung cấp Restful API đi cùng với MySQL database mình đã tạo trước đó. Các bạn có thể download source code tại Github.

$ git clone https://github.com/npthao1312/springdoc-book-service

Đây là một app Rest CRUD đơn giản, gồm những API sau:

Methods Urls Actions
POST /api/books tạo Book mới
GET /api/books gọi tất cả các Book
GET /api/books/:id tạo một Book bằng :id
PUT /api/books/:id chỉnh sửa một Book bằng :id
DELETE /api/books/:id xóa một Book bằng :id

Bạn có thể xem chi tiết và test thử qua giao diện Swagger UI. Tutorial cách xây dựng app này có thể tìm thấy ở đây: Tự động hóa tạo tài liệu API sử dụng Java Springdoc và Swagger UI

4. Install Elastic Beanstalk CLI (EB CLI)

Ở phần trên bài, có yêu cầu bạn phải cài đặt Python và Pip trước, nếu không bạn có thể bắt đầu tải và cài đặt tại trang chính thức của Python: https://www.python.org/downloads/

EB CLI là giao diện dòng lệnh cho AWS Elastic Beanstalk giúp chúng ta quản lý môi trường từ local của chính mình. Có rất nhiều cách để làm việc với hạ tầng của AWS, như AWS Console hay CloudFormation, mỗi cái đều có lợi hại riêng nhưng ở bài này mình sẽ sử dụng CLI.

Chạy câu lệnh sau:

$ pip install awsebcli --upgrade --user

Phần –upgrade sẽ bảo pip upgrade tất cả các module cần dùng. Phần –user sẽ bảo pip install EB CLI chỉ install cho user đang sử dụng thôi để không phải chỉnh sửa các thư viện mà OS đang sử dụng.

Xác nhận là EB CLI đã được install đúng cách:

$ eb --version
EB CLI 3.20.0 (Python 3.9.6)

5. Khởi tạo dự án Beanstalk

Để khởi tạo một dự án Beanstalk, mở CMD ở root folder của Spring Boot App, rồi chạy câu lệnh:

$ eb init

Chúng ta sẽ chọn vùng, ở đây mình chọn Singapore

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
18) eu-north-1 : EU (Stockholm)
19) eu-south-1 : EU (Milano)
20) ap-east-1 : Asia Pacific (Hong Kong)
21) me-south-1 : Middle East (Bahrain)
22) af-south-1 : Africa (Cape Town)
(default is 3): 7

Cung cấp token AWS của bạn. Nếu chưa có thì hãy truy cấp tới, AWS Security Credentials:

Nhấn vào mục Access keys (access key ID and secret access key). Nhấn nút Create New Access Key. Hãy tải xuống file đó và nhập các key vào CMD của bạn.

Tạo access key

Tiếp theo là đặt tên app, phần này mình lựa chọn mặc địch, bạn có thể đặt tên app dễ nhớ hơn:

Enter Application Name (default is "springdoc-book-service"):

Tiếp đến, chúng ta sẽ chọn platform để deploy,

Select a platform.
1) .NET Core on Linux
2) .NET on Windows Server
3) Docker
4) GlassFish
5) Go
6) Java
7) Node.js
8) PHP
9) Packer
10) Python
11) Ruby
12) Tomcat
(make a selection): 6

Có thể deploy app bằng Tomcat nhưng mình sẽ chọn Java cho đơn giản. Nhấn số 6. Tiếp theo là version Java, trong Spring Boot app này mình sử dụng Java 8, chọn 2:

Select a platform branch.
1) Corretto 11 running on 64bit Amazon Linux 2
2) Corretto 8 running on 64bit Amazon Linux 2
3) Java 8 running on 64bit Amazon Linux (Deprecated)
4) Java 7 running on 64bit Amazon Linux (Deprecated)
(default is 1): 2

Có thể thấy là hiện tại dịch vụ AWS chưa cung cấp tới Java 16. Đây là một điều các bạn có thể cân nhắc trước khi deploy lên AWS.

Ở đây mình cũng sẽ không sử dụng CodeCommit (một dạng VCS của AWS) vì mình không có nhu cầu.

Do you wish to continue with CodeCommit? (Y/n): n

Mình nghĩ là nên set up SSH khi cần kết nối với EC2, bạn sẽ tạo một keypair.

Do you want to set up SSH for your instances? (Y/n): Y

6. Cấu hình môi trường cho Spring Boot với MySQL trên AWS

Chúng ta sẽ tạo một môi trường Elastic Beanstalk với câu lệnh sau:

$ eb create --single --database --database.username {master username của bạn} --database.password {mật khẩu của bạn}

Nên tạo tài khoản và mật khẩu trùng với thông tin đã được set up trong cấu hình Spring Boot app để không gây xung đột. Phần –single là để tạo duy nhất một instance và không đi kèm với load balancer. Vì đây mới chỉ là một dự án để test thử, sẽ không cần load balance như production.

Bạn có thể tùy chọn giữa nhiều RDS khác nhau như mysql, oracle-se1, postgres, sqlserver-ex, sqlserver-web, sqlserver-se với phần tùy chọn –database.engine. Thông tin rõ hơn có thể tìm kiếm ở đây.

Enter Environment Name
(default is springdoc-book-service-dev):
Enter DNS CNAME prefix
(default is springdoc-book-service-dev): book-dev

Would you like to enable Spot Fleet requests for this environment? (y/N): N

Phần DNS CNAME sẽ là tên subdomain dẫn tới website của bạn, nên viết cho ngắn một tí. Chờ một lúc đợi khởi tạo xong, nhanh tầm 1 bài nhạc, lâu thì 2-3 bài nhạc :v

Uploading: [##################################################] 100% Done...
Environment details for: springdoc-book-service-dev
  Application name: springdoc-book-service
  Region: ap-southeast-1
  Deployed Version: app-end-210730_211742
  Environment ID: e-pwkry3cy69
  Platform: arn:aws:elasticbeanstalk:ap-southeast-1::platform/Corretto 8 running on 64bit Amazon Linux 2/3.2.3
  Tier: WebServer-Standard-1.0
  CNAME: book-dev.ap-southeast-1.elasticbeanstalk.com
  Updated: 2021-07-30 14:18:17.737000+00:00
Printing Status:
2021-07-30 14:18:16    INFO    createEnvironment is starting.
2021-07-30 14:18:17    INFO    Using elasticbeanstalk-ap-southeast-1-495580400293 as Amazon S3 storage bucket for environment data.
2021-07-30 14:18:40    INFO    Created security group named: awseb-e-pwkry3cy69-stack-AWSEBSecurityGroup-CYQJE550PXKO
2021-07-30 14:18:55    INFO    Creating RDS database named: aaaogu14v5vhq4. This may take a few minutes.
2021-07-30 14:18:55    INFO    Created EIP: 13.213.126.54

Dùng câu lệnh eb console để mở cửa sổ console của Enviroment này, như thế này là ổn:

Click vào phần Configuration:

Capture.PNG

Copy endpoint của RB:

Chúng ta cần chỉnh sửa lại một tí biến môi trường để tương thích với AWS. Spring Boot App sẽ tự động chạy trên cổng 8080, nhưng AWS sẽ bắt cổng 5000, truy cập vào file src/main/resources/application.properties:

server.port=5000
spring.datasource.url=jdbc:mysql://aaaogu14v5vhq4.ccmcaualowje.ap-southeast-1.rds.amazonaws.com:3306/ebdb
spring.datasource.username= 
spring.datasource.password= 
spring.datasource.platform=mysql
spring.datasource.initialization-mode=always

spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto= update

Chúng ta sẽ tạo một file jar cho Spring Boot app, sử dụng Maven hoặc những tool có sẵn trong IDE:

$ mvn clean package spring-boot:repackage

Câu lệnh này sẽ tạo ra một phiên bản ứng dụng standalone có tên springdoc-book-service-0.0.1-SNAPSHOT.jar ở trong thư mục target.

7. Cấu hình Deploy trong file yaml

Sau khi hoàn thành các bước ở trên, Elastic Beanstalk sẽ tự động tạo một file cấu hình deploy trong thư mục .elasticbeanstalk/config.yml. Chúng ta sẽ cho thêm hai dòng để trỏ deploy file jar trên:

deploy:
  artifact: target/springdoc-book-service-0.0.1-SNAPSHOT.jar

File config.yml đầy đủ sẽ giống như thế này:

branch-defaults:
  main:
    environment: null
    group_suffix: null
deploy:
  artifact: target/springdoc-book-service-0.0.1-SNAPSHOT.jar
global:
  application_name: springdoc-book-service
  branch: null
  default_ec2_keyname: aws-eb
  default_platform: Corretto 8 running on 64bit Amazon Linux 2
  default_region: ap-southeast-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: eb-cli
  repository: null
  sc: git
  workspace_type: Application

8. Deploy

Bây giờ, chúng ta sẽ deploy.

$  eb deploy
Uploading: [##################################################] 100% Done...
2021-07-30 14:54:53    INFO    Environment update is starting.

Check lại console và copy đường link tới website:

Và nó đã lên:

9. Test

Chúng ta sẽ test bằng chính Swagger UI:

10. Terminate AWS Elastic Beanstalk Enviroment

Vì mình cũng chỉ deploy cái app này để biết bài này thôi nên không cần phải nó chạy mãi tốt giờ sử dụng, nên đây là cách Terminate một Enviroment trên Elastic Beanstalk, thường thì nếu chỉ stop thôi có khi vẫn còn tài nguyên đang sử dụng. Tốt nhất là nên Terminate, sử dụng câu lệnh:

$ eb terminate springdoc-book-service-dev

Phụ lục: Kiểm tra RDS

Đôi khi chúng ta cần phải có một số thao tác với database, để kết nối với RDS, chúng ta cần phải cài đặt luật lệ cho cổng inbound TCP. Chọn DB instance ở phần Configuration ở trên, kéo xuống tới Security group và chọn và loạt EC2 – Inbound:

Chọn Edit Inbound Rules:

Chọn Add new rule, nhấn chọn loại MySQL/Aurora, và source đến từ My IP, IP của bạn sẽ tự hiện ra:
Capture.PNG

Từ đây, các bạn có thể thoải mái connect với database MySQL RDS bằng username và mật khẩu bạn đã tạo:

$ mysql -h aaaogu14v5vhq4.ccmcaualowje.ap-southeast-1.rds.amazonaws.com -P 3306 -u root -p

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ