Phần II: Cấu hình Server và triển khai Gitlab CI để tự động hóa deploy code lên Elastic Beanstalk và S3
Tổng quan về những gì mình sẽ làm
Chào mọi người lại là Hiệp 23 tuổi với 24 năm kinh nghiệm đây. Hôm nay mình sẽ cấu hình con server mà chúng ta đã tạo được từ phần trước và tiến hành kết hợp Gitlab CICD để tự động hóa deploy nhé. Link phần 1 ở đây, mọi người ai có thấy hay thì cho mình xin 1 upvote ủng hộ nha ( https://viblo.asia/p/cac-buoc-deploy-project-len-aws-ec2-mot-cach-don-gian-tu-a-den-a-yZjJY9zXJOE )
Cấu hình BE ở trên EC2 server và FE ở trên S3
Đầu tiên thì mình sẽ tiến hành triển khai và cấu hình server ở trên EC2 server mà mình đã tạo từ phần trước. Trong phần này thì mình sẽ triển khai 1 project Larave và ReactJS, mình sẽ chỉ init 2 project chứ không đi chuyên sâu vào trong code nên là mọi người dù không biết PHP, Laravel hay ReactJS thì đều có thể đọc được nha. Nào chúng ta hãy cùng bắt tay vào làm nào.
Cấu hình phía backend
Bước 1: Đầu tiên thì do việc tạo EC2 server thông quá Elastic Beanstalk nên là mình sẽ không cần config gì nữa ở máy server mà mình sẽ chỉ cần tiến hành cài đặt thêm EB Cli ở máy bastion để có thể tiến hành việc tự động hóa deploy. Để làm được việc này ta sẽ tiến hành SSH vào máy server EC2 mà ta đã tạo từ phần trước thông qua máy bastion làm tunnel. Mình sẽ giải thích qua 1 chút về 2 con máy kia cho những ai chưa biết. Thì trong phần trước mình đã setup 1 con máy EC2 server nằm trên 1 private subnet ở trên VPC để không thể truy cập từ bên ngoài vào mà chỉ có thể truy cập SSH từ con máy bastion mà mình để trên public subnet. Đầu tiên chúng ta sẽ di chuyển đến thư mục có chứa cặp key pair mà ta đã tạo từ lúc tạo con máy EC2 bastion rồi bật terminal sau đó gõ lệnh ssh -i "key-pair-ec2-server" ec2-user@private-ip-ec2-server -o ProxyCommand="ssh -W %h:%p -i "key-pair-ec2-bastion" ec2-user@ec2-public-ip-ec2-bastion.compute-1.amazonaws.com"
. Hoặc các bạn có thể tạo file config trong .ssh để những lần sau thuận tiện vào hơn
Bước 2: Tiếp đến ta sẽ truy cập vào máy bastion để cài thêm 1 số phần mềm. Đầu tiên là ta sẽ cài pip và aws eb cli trong link chính chủ sau đây https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install-linux.html.
Cấu hình phía FE
Ở đây thì mình sẽ chỉ đơn giản là tạo bucket thôi, vì ở phần 1 mình đã tạo 1 bucket FE rồi dụng Clouidfront trỏ vào nên nếu bạn nào chưa biết thì có thể xem lại phần 1 của mình nha
Cấu hình gitlab-ci.yml để tích hợp CICD
Cấu hình gitlab-ci.yml ở source BE
Như đã nói ở phần 1 thì mình sẽ xây dựng source BE là Laravel ( 1 framework của PHP ), tuy nhiên thì mình sẽ không đi sâu vào source mà chỉ tập trung nói về việc config CICD trong file gitlab.ci và repo trên gitlab vậy nên bạn hoàn toàn có thể áp dụng được cho các ngôn ngữ khác.
Bước 1: Đầu tiên việc không thể thiếu thì ta sẽ cần đẩy code lên repo gitlab ( mình sẽ skip bước này ). Tiếp đến thì các bạn sẽ ấn vô mục Settings > CI/CD > Variables để setup các biến mà chúng ta sẽ sử dụng trong file gitlab-ci.yml. Ở đây mình sẽ sử dụng 5 biến như trong hình bên dưới. Trong đó thì thì DEPLOY_DIR sẽ là thư mục chứa source code ở trên EC2 bastion, DEPLOY_HOST là địa chỉ ip public của bastion, DEPLOY_USER là user để ssh, EB_ENV_NAME là tên environment ở trên elastic beanstalk, SSH_PRIVATE_KEY là nội dung trong file key_pair mà ta tạo lúc tạo EC2
Bước 2: Tiếp đến thì ta sẽ cấu hình file gitlab-ci.yml. Các bạn hãy tạo 1 file tên gitlab-ci.yml ở trong source code của dự án. Dưới đây là nội dung file gitlab-ci.yml mà mình đã tạo để có thể deploy lên EC2 server trên Elastic Beanstalk thông máy EC2 bastion. Mình sẽ giải thích qua chút về nội dung file cho mọi người dễ hiểu
- Đầu tiên thì đây sẽ là file mà gitlab sẽ dựa vào để chạy phần CICD deploy lên server.
- Phần image là docker image mà gitlab CICD sẽ chạy trên
- Phần stages là các phần và thứ tự các phần ( hay còn gọi là pipeline ) mà CICD sẽ chạy. Ở đây mình sẽ tạo đơn giản 3 phần là build, test và deploy
- Phần building sẽ đảm nhiệm trọng trách build dự án. Trong này có stage là để khai báo nó thuộc stage nào, cache là để cache lại cho những lần chạy pipeline Building sau này, scirpt là những script mà mình sẽ chạy trong pipeline này ( trong này thì mọi người có thể thay đổi tùy theo ngôn ngữ của mọi người, vd như node js thì các bạn có thể chạy npm install ... ), artifacts là để lưu trữ các file, thư mục cho những pipeline sau có thể sử dụng lại được
- Phần testing thì mình sẽ chạy script để test dự án, ở đây thì mình viết câu lệnh của php unit test trong laravel
- Phần deploying là mình sẽ chạy script để deploy dự án. Đầu tiên thì mình sẽ chạy script để tạo SSH agent đã kích hoạt và có chứa private key, sẵn sàng để sử dụng cho các lệnh deploy từ GitLab CI. Tiếp đến là mình sẽ sử dụng rsync để có thể đồng bộ dự án từ local lên trên con EC2 bastion. Tiế đến mình sẽ viết script để SSH vào máy bastion rồi chạy lệnh eb deploy để deploy dự án trên Elastic Beanstalk
image: php:8.2-fpm
stages:
- build
- test
- deploy
Building:
stage: build
cache:
key: ${CI_COMMIT_REF_SLUG}
untracked: true
paths:
- vendor/
script:
- echo "Run $CI_JOB_NAME."
- echo "Installing Composer..."
- curl -sS https://getcomposer.org/installer | php
- mv composer.phar /usr/local/bin/composer
- cp .env.example .env
- composer install --no-interaction --optimize-autoloader
- php artisan key:generate
artifacts:
paths:
- vendor/
- .env
expire_in: 1 hrs
Testing:
stage: test
script:
- echo "Run $CI_JOB_NAME."
- ./vendor/bin/phpunit --testdox
Deploying:
stage: deploy
only:
- master
script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- apt-get install rsync -y
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod -R 700 ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- php artisan config:cache
- rsync -azPq --exclude='.git' ./ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_DIR/
- ssh $DEPLOY_USER@$DEPLOY_HOST "export PATH=$PATH:~/.local/bin
&& cd $DEPLOY_DIR && eb deploy $EB_ENV_NAME -l $CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"
Cấu hình gitlab-ci.yml ở source FE
Source FE thì mình sẽ sử dụng ReactJS và các bạn có thể hoàn toàn đổi sang ngôn ngữ, thư viện, framework FE nào khác nha
Bước 1: Đầu tiên việc mình sẽ lại tạo repo gitlab rồi đẩy code lên. Tiếp đến thì các bạn sẽ ấn vô mục Settings > CI/CD > Variables để setup các biến mà chúng ta sẽ sử dụng trong file gitlab-ci.yml. Ở đây mình sẽ sử dụng 5 biến như trong hình bên dưới ( giá trị các biến sẽ giống với các biến ở trong repo source BE chỉ khác là ta sẽ thay EB_ENV_NAME thành S3_BUCKET với tên của S3_BUCKET mà ta đã tạo )
Bước 2: Ở bước này thì chúng ta sẽ tạo và cấu hình file gitlab-ci.yml. Dưới đây là nội dung file gitlab-ci.yml mà mình đã tạo để có thể deploy lên máy bastion rồi từ máy bastion sẽ đẩy dữ liệu lên trên S3 Bucket. Ở đây mình sẽ chỉ có 2 bước là build và deploy và nó cũng khá giống với file mà ta đã tạo ở source BE chỉ khác ở đoạn cuối cùng của deploy là ta sẽ đẩy lên S3 thay vì Elastic Beanstalk. Mình sẽ dùng câu lệnh s3 sync để đồng bộ file lên S3 ( mọi người có thể search AWS Cli S3 để biết thêm )
stages:
- Build
- Deploy
image: node:16.16.0-alpine
Building:
stage: Build
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
script:
- yarn install
- yarn build
artifacts:
paths:
- build/
- .env
expire_in: 1 hrs
Deploying:
stage: Deploy
only:
- master
script:
- apk add rsync && apk add openssh
- eval $(ssh-agent -s) && echo "$SSH_PRIVATE_KEY" | ssh-add -
- mkdir -p ~/.ssh
- chmod -R 700 ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- rsync -avzPq build/ $DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_DIR/
- ssh $DEPLOY_USER@$DEPLOY_HOST "aws s3 sync $DEPLOY_DIR/ s3://$S3_BUCKET/client"
Tổng Kết
Sau khi viết xong file thì mọi người hãy ra làm cho mình một tách cà phê rồi chờ đợi pipeline và thành quả của mình thôi nào. Đến đây là mình sẽ kết thúc series về việc tạo, tự động hóa deploy 1 hệ thống như trong thực tế và đã được áp dụng và một số dự án nhỏ và vừa mà mình đã làm. Với việc là một BE developer nên là tiếp nối series này thì mình có thể có những series khác về việc chia sẽ những kiến thức của mình về SQL hay về code nữa. Nếu mọi người thấy hay và bài viết mình có thể giúp được mọi người 1 phần nào đó thì mong rằng mọi người hãy cho mình xin 1 upvote và follow để giúp tạo thêm động lực nha. Ngoài ra nếu có bất cứ góp ý hay hỏi đáp gì thì đừng ngần ngại comment cho mình biết nhé. Cảm ơn bạn vì đã đọc đến dòng này, chúc mọi người trên con đường lập trình sắp tới .
All rights reserved