Bài 10. Terraform CI/CD: Tự Động Triển Khai Hạ Tầng Với GitHub Actions

Tại Sao Cần Tích Hợp Terraform CI/CD?

Terraform CI/CD là bước quan trọng để tự động hóa quy trình triển khai hạ tầng, giúp bạn tiết kiệm thời gian, giảm lỗi thủ công và đảm bảo tính nhất quán trong môi trường DevOps. Trong các bài trước, chúng ta đã làm quen với Terraform cơ bản (bài 1), tạo máy chủ EC2 (bài 2), xây dựng hạ tầng mạng VPC (bài 3), sử dụng variables/outputs (bài 4), tự động hóa triển khai với Load Balancer và Auto Scaling Group (bài 5), sử dụng Terraform modules (bài 6), quản lý nhiều môi trường với Terraform workspaces (bài 7), quản lý trạng thái với Terraform state (bài 8), và tự động hóa cấu hình với Terraform provisioners (bài 9).

Tuy nhiên, trong thực tế, việc triển khai hạ tầng bằng Terraform thường cần tích hợp vào quy trình CI/CD để tự động chạy các lệnh terraform apply khi mã được đẩy lên repository. GitHub Actions là một công cụ phổ biến để xây dựng pipeline CI/CD, và trong bài này, mình sẽ hướng dẫn bạn 5 bước để tích hợp Terraform CI/CD, tự động triển khai một EC2 trên AWS bằng GitHub Actions.

Terraform CI/CD: Hướng Dẫn Từng Bước

Bước 1: Chuẩn Bị Môi Trường Và GitHub Repository

  • Hành động:
    1. Đảm bảo bạn đã cài đặt Git trên máy local:
      git --version

      Nếu chưa cài, tải và cài đặt từ Git Official Website.

    2. Tạo một repository mới trên GitHub:
      • Truy cập GitHub, đăng nhập, và tạo repository mới (VD: terraform-cicd-example).
      • Chọn public hoặc private tùy ý.
    3. Tạo thư mục dự án trên máy local:
      mkdir terraform-cicd-example
      cd terraform-cicd-example
      git init
  • Kết quả thực tế:
    • Sau khi chạy git --version, terminal sẽ hiển thị:
      git version 2.39.2

      (Xác nhận Git đã được cài đặt).

    • Sau khi tạo repository trên GitHub, bạn sẽ thấy repository terraform-cicd-example trên GitHub.
    • Sau khi chạy git init, terminal sẽ hiển thị:
      Initialized empty Git repository in /path/to/terraform-cicd-example/.git/

      (Xác nhận thư mục đã được khởi tạo Git).

Bước 2: Tạo Mã Terraform Và Cấu Hình GitHub Actions

  • Hành động:

    1. Tạo file main.tf trong thư mục terraform-cicd-example:

      touch main.tf

      Mở file main.tf trong VS Code và dán nội dung sau:

      terraform {
      required_providers {
       aws = {
         source = "hashicorp/aws"
         version = "5.0.0"
       }
      }
      }
      
      provider "aws" {
      region = "us-east-1"
      }
      
      # Tạo Security Group cho EC2
      resource "aws_security_group" "cicd_sg" {
      name_prefix = "cicd-sg-"
      
      ingress {
       from_port   = 22
       to_port     = 22
       protocol    = "tcp"
       cidr_blocks = ["0.0.0.0/0"]
      }
      
      egress {
       from_port   = 0
       to_port     = 0
       protocol    = "-1"
       cidr_blocks = ["0.0.0.0/0"]
      }
      
      tags = {
       Name = "CICDSG"
      }
      }
      
      # Tạo EC2
      resource "aws_instance" "cicd_ec2" {
      ami           = "ami-0c55b159cbfafe1f0" # Amazon Linux 2 in us-east-1
      instance_type = "t2.micro"
      vpc_security_group_ids = [aws_security_group.cicd_sg.id]
      
      tags = {
       Name = "CICDEC2"
      }
      }
      
      # Output public IP của EC2
      output "ec2_public_ip" {
      description = "Public IP of the EC2 instance"
      value       = aws_instance.cicd_ec2.public_ip
      }
    2. Tạo thư mục và file cho GitHub Actions workflow:

      mkdir -p .github/workflows
      touch .github/workflows/terraform.yml

      Mở file .github/workflows/terraform.yml trong VS Code và dán nội dung sau:

      name: Terraform CI/CD Pipeline
      
      on:
      push:
       branches:
         - main
      
      jobs:
      terraform:
       runs-on: ubuntu-latest
      
       steps:
       - name: Checkout code
         uses: actions/checkout@v3
      
       - name: Setup Terraform
         uses: hashicorp/setup-terraform@v2
         with:
           terraform_version: 1.11.2
      
       - name: Terraform Init
         run: terraform init
         env:
           AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
           AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      
       - name: Terraform Plan
         run: terraform plan -out=tfplan
         env:
           AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
           AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      
       - name: Terraform Apply
         run: terraform apply -auto-approve tfplan
         env:
           AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
           AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      Giải thích:

      • main.tf: Tạo một EC2 đơn giản với Security Group cho phép SSH.
      • terraform.yml: Định nghĩa pipeline GitHub Actions:
      • Trigger khi push lên branch main.
      • Sử dụng Ubuntu runner.
      • Checkout mã, cài đặt Terraform 1.11.2, chạy terraform init, terraform plan, và terraform apply.
      • Sử dụng secrets AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY để truy cập AWS (sẽ cấu hình ở bước sau).
  • Kết quả thực tế:
    • Cấu trúc thư mục sẽ là:
      terraform-cicd-example/
      ├── .github/
      │   └── workflows/
      │       └── terraform.yml
      └── main.tf

      (Kiểm tra bằng lệnh ls -R, bạn sẽ thấy các file đã được tạo).

Bước 3: Tạo AWS Credentials Và Cấu Hình Secrets Trong GitHub

  • Hành động:
    1. Tạo IAM User trên AWS để GitHub Actions sử dụng:
      • Truy cập AWS Console > IAM > Users > Add User.
      • Tạo user (VD: github-actions-user), chọn “Access key – Programmatic access”.
      • Gắn policy AdministratorAccess (chỉ để thử nghiệm, trong môi trường production nên giới hạn quyền).
      • Tải Access Key ID và Secret Access Key (VD: AKIA1234567890abc123def456).
    2. Cấu hình secrets trong GitHub:
      • Truy cập repository terraform-cicd-example trên GitHub.
      • Vào Settings > Secrets and variables > Actions > New repository secret.
      • Thêm hai secrets:
      • Name: AWS_ACCESS_KEY_ID, Value: AKIA1234567890.
      • Name: AWS_SECRET_ACCESS_KEY, Value: abc123def456.
  • Kết quả thực tế:
    • Trên AWS Console, bạn sẽ thấy user github-actions-user với Access Key đã được tạo.
    • Trên GitHub, vào Settings > Secrets and variables > Actions, bạn sẽ thấy hai secrets AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY đã được thêm.

Bước 4: Đẩy Mã Lên GitHub Và Kiểm Tra Pipeline

  • Hành động:
    1. Commit và đẩy mã lên GitHub:
      git add .
      git commit -m "Add Terraform code and GitHub Actions workflow"
      git branch -M main
      git remote add origin https://github.com/your-username/terraform-cicd-example.git
      git push -u origin main

      (Thay your-username bằng tên người dùng GitHub của bạn).

    2. Kiểm tra pipeline trên GitHub:
      • Truy cập repository terraform-cicd-example > Actions.
      • Bạn sẽ thấy workflow “Terraform CI/CD Pipeline” đang chạy.
  • Kết quả thực tế:

    • Sau khi đẩy mã, terminal sẽ hiển thị:
      Enumerating objects: 5, done.
      Counting objects: 100% (5/5), done.
      Delta compression using up to 8 threads
      Compressing objects: 100% (5/5), done.
      Writing objects: 100% (5/5), 1.23 KiB | 1.23 MiB/s, done.
      Total 5 (delta 0), reused 0 (delta 0)
      To https://github.com/your-username/terraform-cicd-example.git
      * [new branch]      main -> main
      Branch 'main' set up to track remote branch 'main' from 'origin'.

      (Xác nhận mã đã được đẩy lên GitHub).

    • Trên GitHub Actions, sau khi pipeline hoàn thành, bạn sẽ thấy log (được rút gọn):

      Terraform Init
      [command] terraform init
      Initializing the backend...
      Initializing provider plugins...
      - Installed hashicorp/aws v5.0.0 (signed by HashiCorp)
      Terraform has been successfully initialized!
      
      Terraform Plan
      [command] terraform plan -out=tfplan
      Plan: 2 to add, 0 to change, 0 to destroy.
      
      Terraform Apply
      [command] terraform apply -auto-approve tfplan
      aws_security_group.cicd_sg: Creating...
      aws_security_group.cicd_sg: Creation complete after 2s [id=sg-0123456789abcdef0]
      aws_instance.cicd_ec2: Creating...
      aws_instance.cicd_ec2: Creation complete after 15s [id=i-0123456789abcdef0]
      Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
      
      Outputs:
      ec2_public_ip = "54.123.45.67"

      (Pipeline đã chạy thành công, tạo EC2 với public IP 54.123.45.67).

    • Kiểm tra trên AWS Console (EC2 Dashboard):
    • Một instance với tag Name: CICDEC2, trạng thái Running.

Bước 5: Xóa Tài Nguyên Để Dọn Dẹp

  • Hành động:
    1. Thêm bước destroy vào pipeline:
      • Mở file .github/workflows/terraform.yml, thêm bước Terraform Destroy vào cuối:
      • name: Terraform Destroy if: always() run: terraform destroy -auto-approve env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      • Commit và đẩy mã:
        git add .
        git commit -m "Add Terraform Destroy step to pipeline"
        git push
    2. Kiểm tra pipeline trên GitHub Actions để xác nhận tài nguyên đã bị xóa.
    3. Xóa IAM User trên AWS:
      • Truy cập AWS Console > IAM > Users > github-actions-user > Delete.
  • Kết quả thực tế:
    • Sau khi đẩy mã, pipeline sẽ chạy lại và bao gồm bước destroy:
      Terraform Destroy
      [command] terraform destroy -auto-approve
      aws_instance.cicd_ec2: Destroying... [id=i-0123456789abcdef0]
      aws_instance.cicd_ec2: Destruction complete after 15s
      aws_security_group.cicd_sg: Destroying... [id=sg-0123456789abcdef0]
      aws_security_group.cicd_sg: Destruction complete after 2s
      Destroy complete! Resources: 2 destroyed.

      (Xác nhận tài nguyên đã bị xóa).

    • Kiểm tra trên AWS Console:
    • EC2 Dashboard: Instance CICDEC2 không còn tồn tại.
    • IAM Dashboard: User github-actions-user đã bị xóa.

Kết Quả Đạt Được

  • Bạn đã học cách tích hợp Terraform CI/CD bằng GitHub Actions, tự động triển khai EC2 trên AWS khi đẩy mã lên branch main.
  • Bạn đã kiểm tra pipeline và xác nhận hạ tầng được tạo thành công.
  • Bạn đã thêm bước destroy vào pipeline và xóa tài nguyên để tránh phát sinh chi phí.

Lưu Ý Quan Trọng

  • Bảo mật credentials: Không bao giờ lưu AWS Access Key trong mã nguồn. Sử dụng GitHub Secrets như trong bài để bảo mật.
  • Chi phí AWS: Instance t2.micro trong bài nằm trong Free Tier, nhưng nếu dùng loại instance khác, có thể phát sinh chi phí. Luôn chạy terraform destroy sau khi thử nghiệm.
  • Tối ưu pipeline: Trong môi trường production, bạn nên thêm bước kiểm tra (terraform plan) và phê duyệt thủ công trước khi chạy terraform apply.
  • Tài liệu tham khảo: Xem thêm về GitHub Actions (GitHub Actions Documentation) và tích hợp Terraform với CI/CD (Terraform CI/CD Best Practices).
Điều hướng chuỗi bài viết<< Bài 9. Terraform Provisioners: Tự Động Hóa Cấu Hình Web Server Trên EC2
Article Thumbnail
Datadog Webinar: Modernize AWS Logs at Scale

Sự kiện đang hiện hành

Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận