0
0
Lập trình
TT

Xây dựng Pipeline CI/CD với GitHub Actions, Docker và Terraform

Đăng vào 5 ngày trước

• 7 phút đọc

Giới thiệu

Gần đây, tôi đã thực hiện một dự án giúp tôi ôn lại những khái niệm quan trọng về CI/CD, containerizationinfrastructure as code. Trong bài viết này, tôi sẽ chia sẻ kinh nghiệm, công nghệ sử dụng, những khó khăn gặp phải và bài học rút ra từ dự án. Bài viết này không chỉ tập trung vào công cụ mà còn vào khả năng thiết kế, xây dựng và tích hợp các công cụ và giải pháp hiện đại, cũng như hiểu cách và khi nào nên sử dụng chúng.

Dự Án

Mục tiêu của tôi là đơn giản: xây dựng một API bằng Python với Flask trả về các câu nói động lực ngẫu nhiên, container hóa nó với Docker và cấu hình để triển khai tự động bằng GitHub ActionsTerraform trên một nhà cung cấp cloud.

Kết quả cuối cùng là một pipeline thực hiện:

  1. Xây dựng hình ảnh Docker của ứng dụng.
  2. Tự động triển khai trên nhà cung cấp cloud.
  3. Cung cấp hạ tầng thông qua Terraform.

Tất cả những điều này sẽ được kích hoạt mỗi khi có commit vào nhánh main.

Công Nghệ Sử Dụng

  • Python + Flask – để xây dựng API.
  • Docker – để đóng gói ứng dụng và đảm bảo khả năng di động.
  • GitHub Actions – để tạo pipeline CI/CD.
  • Terraform – để quản lý hạ tầng như mã.
  • Cloud – nhà cung cấp dịch vụ lưu trữ và triển khai.

Cấu Trúc Cơ Bản Của API

Dưới đây là mã nguồn đơn giản để minh họa cấu trúc ứng dụng:

python Copy
# app/advice.py
from flask import Flask, jsonify
import random

app = Flask(__name__)

frases = [
    "Acredite em você!",
    "Você é capaz de mais do que imagina.",
    "Persistência leva ao sucesso.",
    "Cada erro é uma oportunidade de aprendizado."
]

@app.route("/")
def home():
    return jsonify({"message": "Chào mừng bạn đến với API Câu Nói Động Lực!"})

@app.route("/frase")
def frase():
    return jsonify({"frase": random.choice(frases)})

@app.errorhandler(404)
def not_found(error):
    return jsonify({"error": "Đường dẫn không tồn tại"}), 404

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=80)

Dockerfile Để Container Hóa

Hình ảnh được xây dựng từ một base Python và mở cổng 80:

dockerfile Copy
FROM python:3.10-slim

WORKDIR /app

COPY app/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app/ .

EXPOSE 80

CMD ["python", "advice.py"]

Để kiểm tra cục bộ:

bash Copy
docker build -t api-advice .
docker run -p 80:80 api-advice

Workflow Của GitHub Actions

Workflow được cấu hình để chạy trên nhánh main với các luồng riêng biệt để thực hiện build, test và deploy:

yaml Copy
name: CI Pipeline

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Build hình ảnh Docker
        run: docker build -t test-image:latest .

      - name: Chạy kiểm tra trong container
        run: |
          docker run --rm -d -p 80:80 --name test-container test-image:latest
          sleep 5
          curl -f http://localhost/ || exit 1
          curl -f http://localhost/frase || exit 1
          curl -s -o /dev/null -w "%{http_code}" http://localhost/inexistente | grep -q "404" && echo "404 OK" || exit 1
          docker stop test-container

      - name: Kiểm tra đã vượt qua ✅
        run: echo "Tất cả các bài kiểm tra đã thành công!"

Action cho Infra

yaml Copy
name: Provisionar Infraestrutura Render

on:
  push:
    branches: [infra]

jobs:
  terraform:
    runs-on: ubuntu-latest
    environment: render

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.12.2

      - name: Terraform Init
        working-directory: infra
        run: terraform init

      - name: Terraform Plan
        working-directory: infra
        env:
          TF_VAR_cloud_api_key: ${{ secrets.SECRET_API_KEY }}
          TF_VAR_cloud_owner_id: ${{ secrets.SECRET_OWNER_ID }}
        run: terraform plan -out=tfplan

      - name: Terraform Apply
        working-directory: infra
        env:
          TF_VAR_cloud_api_key: ${{ secrets.SECRET_API_KEY }}
          TF_VAR_cloud_owner_id: ${{ secrets.SECRET_OWNER_ID }}
        run: terraform apply -auto-approve

Mã Terraform Cho Cloud

Trong thư mục infra/, tôi đã cấu hình các tài nguyên cho nhà cung cấp tương ứng:

hcl Copy
tf_version ">= 0.12"

provider "cloud" {
  api_key = var.cloud_api_key
}

resource "cloud_service" "api" {
  name    = "api-advice"
  type    = "web_service"
  plan    = "starter"
  env     = "docker"
  branch  = "main"
  repo    = "https://github.com/seu-usuario/seu-repo"
}

Những Bài Học Chính

1. Containerization với Docker

Tôi đã ôn lại việc tạo một hình ảnh Docker cho ứng dụng Flask, mở cổng 80 và cấu hình đúng CMD để khởi động server. Tôi cũng đã thử nghiệm gọi API bằng curl để xác nhận tính năng hoạt động trong container.

2. Tự Động Hóa Với GitHub Actions

Tôi đã cấu hình một workflow thực hiện:

  • Xây dựng hình ảnh Docker.
  • Tự động xuất bản ứng dụng trên nhà cung cấp cloud.
  • Cung cấp hạ tầng với Terraform.

3. Hạ Tầng Như Mã Với Terraform

Tôi đã củng cố lại khái niệm về tổ chức tệp tin (main.tf, variables.tf, outputs.tf, terraform.tfvars) và các thực hành tốt khi sử dụng biến và outputs.

4. Cấu Trúc Dự Án

Giữ sự tách biệt giữa mã ứng dụng và mã hạ tầng giúp dễ dàng duy trì hơn.

Những Khó Khăn Gặp Phải

  • Ôn lại Terraform: Đã một thời gian tôi không làm việc với Terraform, vì vậy tôi cần ôn lại tài liệu chính thức để nhớ lại cú pháp đúng của các mô-đun và đảm bảo tương thích với các phiên bản hiện tại.
  • Tìm Hiểu Nhà Cung Cấp: Vì tôi chưa biết nhà cung cấp được định nghĩa cho dự án này, tôi đã mất thêm thời gian để hiểu cách thức thực hiện triển khai tự động từ các commit trên nhánh main.

Công Cụ Hỗ Trợ

Trong quá trình phát triển, tôi đã sử dụng một số công cụ AI giúp tăng tốc độ học tập:

  • ChatGPT (OpenAI): để giải đáp thắc mắc và đề xuất giải pháp.
  • GitHub Copilot: để đẩy nhanh quá trình viết mã và các tệp cấu hình.
  • Claude Sonnet 3.7 (Anthropic): để xem xét và đề xuất cải tiến về tổ chức dự án.

Kết Luận

Dự án này không chỉ là việc tạo ra một API đơn giản — nó còn là bài tập thực tế về tích hợp giữa phát triển, tự động hóa và hạ tầng. Tôi đã ôn lại những khái niệm quan trọng và học hỏi những quy trình làm việc mới với các công cụ hiện đại như Render.

Nếu bạn đang bắt đầu với CI/CD, tôi khuyến nghị mạnh mẽ việc tạo ra một dự án từ đầu, tích hợp Docker, Terraform và một pipeline triển khai tự động. Kinh nghiệm thực tiễn là không thể thay thế.

Tách Biệt Các Pipeline

Tôi đã tạo ra hai workflow riêng biệt:

  • Pipeline CI (ci.yml): chịu trách nhiệm xây dựng hình ảnh Docker và chạy các bài kiểm tra tự động đơn giản (bao gồm kiểm tra đường dẫn và trạng thái HTTP). Việc triển khai tại Render được kích hoạt tự động qua tích hợp của Render với GitHub ngay khi có push vào nhánh main.
  • Pipeline Hạ Tầng (infra.yml): dành riêng cho việc cung cấp hạ tầng thông qua Terraform, kích hoạt bởi các push vào nhánh infra.

Việc tách biệt này đảm bảo tổ chức tốt hơn, dễ dàng trong việc khắc phục sự cố và cho phép phát triển từng phần của quy trình một cách độc lập.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào