Danh sách bài viết trong series Hành Trình Làm Chủ Terraform
- Bài 1. Học Terraform Cơ Bản: Terraform Là Gì? Cài Đặt Và Viết Mã Đầu Tiên
- Bài 2. Học Terraform Với AWS: 5 Bước Tạo Máy Chủ EC2 Đầu Tiên
- Bài 3. Tạo VPC Với Terraform: Xây Dựng Hạ Tầng Mạng Trên AWS
- Bài 4. Quản Lý Tài Nguyên Với Terraform: Sử Dụng Variables Và Outputs
- Bài 5. Tự Động Hóa Triển Khai Với Terraform: Tạo Load Balancer Và Auto Scaling Group
- Bài 6. Sử Dụng Terraform Modules: Tái Sử Dụng Mã Để Quản Lý Hạ Tầng Hiệu Quả
- Bài 7. Terraform Workspaces: Quản Lý Nhiều Môi Trường Hiệu Quả Trên AWS
- Bài 8. Terraform State: Quản Lý Trạng Thái Hạ Tầng Với S3 Và DynamoDB
- Bài 9. Terraform Provisioners: Tự Động Hóa Cấu Hình Web Server Trên EC2
- 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:
- Đả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.
- 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 ý.
- Truy cập GitHub, đăng nhập, và tạo repository mới (VD:
- Tạo thư mục dự án trên máy local:
mkdir terraform-cicd-example cd terraform-cicd-example git init
- Đảm bảo bạn đã cài đặt Git trên máy local:
- 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).
- Sau khi chạy
Bước 2: Tạo Mã Terraform Và Cấu Hình GitHub Actions
-
Hành động:
-
Tạo file
main.tf
trong thư mụcterraform-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 }
-
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_ID
vàAWS_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).
- Cấu trúc thư mục sẽ là:
Bước 3: Tạo AWS Credentials Và Cấu Hình Secrets Trong GitHub
- Hành động:
- 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:
AKIA1234567890
vàabc123def456
).
- 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
.
- Truy cập repository
- Tạo IAM User trên AWS để GitHub Actions sử dụng:
- 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_ID
vàAWS_SECRET_ACCESS_KEY
đã được thêm.
- Trên AWS Console, bạn sẽ thấy user
Bước 4: Đẩy Mã Lên GitHub Và Kiểm Tra Pipeline
- Hành động:
- 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). - 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.
- Truy cập repository
- Commit và đẩy mã lên GitHub:
-
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áiRunning
.
- Sau khi đẩy mã, terminal sẽ hiển thị:
Bước 5: Xóa Tài Nguyên Để Dọn Dẹp
- Hành động:
- Thêm bước destroy vào pipeline:
- Mở file
.github/workflows/terraform.yml
, thêm bướcTerraform 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
- Mở file
- Kiểm tra pipeline trên GitHub Actions để xác nhận tài nguyên đã bị xóa.
- Xóa IAM User trên AWS:
- Truy cập AWS Console > IAM > Users >
github-actions-user
> Delete.
- Truy cập AWS Console > IAM > Users >
- Thêm bước destroy vào pipeline:
- 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.
- Sau khi đẩy mã, pipeline sẽ chạy lại và bao gồm bước destroy:
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ạyterraform 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ạyterraform 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).