EP4: Kết nối Terraform với AWS - AWS Provider và Các Phương Thức Xác Thực

Dat Ngo TienDat Ngo Tien
9 min read

Chào mừng các bạn đã quay trở lại series "Terraform và AWS Cho Người Mới Bắt Đầu"! Trong Bài 3: Ngôn ngữ HCL và Cấu trúc File Terraform Cơ bản, chúng ta đã làm quen với HCL - ngôn ngữ để "trò chuyện" với Terraform và cấu trúc cơ bản của một tệp .tf.

Đến đây, có lẽ bạn đang rất háo hức muốn biết làm thế nào để Terraform thực sự tương tác được với tài khoản AWS của mình, phải không? Bài viết này sẽ giải đáp điều đó. Chúng ta sẽ cùng nhau tìm hiểu sâu về:

  • Terraform Providers và vai trò then chốt của AWS Provider.

  • Cách khai báo và cấu hình AWS Provider trong tệp Terraform.

  • Các phương thức xác thực an toàn để Terraform có quyền truy cập vào tài khoản AWS của bạn.

  • Một số cấu hình quan trọng trong khối provider "aws".

Nắm vững những kiến thức này là bước đệm cực kỳ quan trọng trước khi chúng ta bắt đầu tạo ra những tài nguyên AWS đầu tiên. Hãy đảm bảo bạn đã cấu hình AWS CLI từ Bài 2 nhé!

Terraform Providers là gì? Vai trò của AWS Provider

Hãy tưởng tượng Terraform như một tổng chỉ huy đa năng, còn các Providers là những "sứ giả" chuyên biệt, giúp Terraform giao tiếp với từng hệ thống cụ thể. Mỗi provider là một plugin mà Terraform sử dụng để tương tác với API của một dịch vụ nào đó, ví dụ:

  • Các nhà cung cấp đám mây: AWS, Azure, Google Cloud Platform (GCP).

  • Các nền tảng ảo hóa: VMware vSphere.

  • Các dịch vụ SaaS: GitHub, Datadog, Cloudflare.

AWS Provider (hashicorp/aws) là một trong những provider phổ biến và mạnh mẽ nhất. Nó cho phép Terraform hiểu và quản lý hàng trăm loại tài nguyên khác nhau trên Amazon Web Services, từ EC2 instances, S3 buckets, VPCs, cho đến các dịch vụ phức tạp hơn như EKS (Elastic Kubernetes Service) hay Lambda functions.

Khi bạn chạy terraform init, Terraform sẽ đọc khối required_providers trong cấu hình của bạn, sau đó tìm và tải xuống các plugin provider cần thiết từ Terraform Registry (một kho lưu trữ công cộng các providers và modules).

Khai báo AWS Provider trong Cấu hình Terraform

Như đã giới thiệu ở Bài 3, việc khai báo provider được thực hiện trong hai khối chính:

  1. Khối terraform {}: Bên trong khối này, bạn có khối required_providers {} để chỉ định các provider cần thiết và phiên bản của chúng.

    Terraform

     # main.tf
    
     terraform {
       required_version = ">= 1.0" # Ví dụ: yêu cầu Terraform phiên bản 1.0 trở lên
    
       required_providers {
         aws = {
           source  = "hashicorp/aws" # Nguồn chính thức của AWS provider
           version = "~> 5.0"        # Chỉ định phiên bản, ví dụ: các bản vá lỗi của 5.x
                                     # Dấu ~> (Pessimistic Constraint Operator) có nghĩa là
                                     # "cho phép các phiên bản patch và minor mới hơn trong 5.x,
                                     # nhưng không tự động nâng cấp lên 6.0.0".
                                     # Điều này giúp đảm bảo tính ổn định.
         }
       }
     }
    
    • source = "hashicorp/aws": Đây là địa chỉ chính thức của AWS provider trên Terraform Registry. hashicorp là namespace của nhà phát triển (HashiCorp), và aws là tên của provider.

    • version = "~> 5.0": Việc ghim phiên bản (version pinning) rất quan trọng. Nó giúp đảm bảo rằng cấu hình của bạn sẽ hoạt động ổn định và có thể dự đoán được, ngay cả khi các phiên bản mới của provider được phát hành với những thay đổi có thể không tương thích ngược.

  2. Khối provider "aws" {}: Khối này dùng để cấu hình các thiết lập cụ thể cho AWS provider, ví dụ như region mặc định mà bạn muốn Terraform làm việc.

    Terraform

     provider "aws" {
       region = "ap-southeast-1" # Ví dụ: làm việc với region Singapore
       # Các cấu hình khác sẽ được thảo luận bên dưới
     }
    

Các Phương thức Xác thực Terraform với AWS

Để Terraform có thể tạo, sửa đổi hoặc xóa tài nguyên trên AWS, nó cần được cấp quyền truy cập vào tài khoản AWS của bạn. Terraform không tự quản lý thông tin đăng nhập mà dựa vào các cơ chế xác thực được AWS SDK (Software Development Kit) hỗ trợ, vì AWS provider sử dụng SDK này ở tầng dưới.

Dưới đây là các phương thức phổ biến:

  1. Shared Credentials File (~/.aws/credentials~/.aws/config):

    • Đây là phương thức chúng ta đã thiết lập ở Bài 2 khi chạy lệnh aws configure. AWS CLI lưu Access Key ID và Secret Access Key vào tệp credentials, và region mặc định, output format vào tệp config.

    • Terraform sẽ tự động tìm và sử dụng các thông tin này từ profile default.

    • Sử dụng profile cụ thể: Nếu bạn có nhiều profile trong tệp credentials (ví dụ: cho các tài khoản AWS khác nhau hoặc các vai trò IAM khác nhau), bạn có thể chỉ định profile Terraform nên sử dụng: Terraform

        provider "aws" {
          region  = "us-east-1"
          profile = "my-dev-profile" # Tên profile trong tệp credentials
        }
      
    • Đây là phương thức khuyến nghị cho việc phát triển và học tập trên máy cá nhân.

  2. Biến Môi trường (Environment Variables):

    • Terraform cũng có thể đọc thông tin xác thực từ các biến môi trường:

      • AWS_ACCESS_KEY_ID

      • AWS_SECRET_ACCESS_KEY

      • AWS_SESSION_TOKEN (nếu sử dụng thông tin xác thực tạm thời, ví dụ từ IAM Roles)

      • AWS_DEFAULT_REGION

      • AWS_PROFILE

    • Phương thức này thường được sử dụng trong các môi trường CI/CD (Continuous Integration/Continuous Deployment).

  3. IAM Roles cho EC2 Instances (Instance Profile):

    • Khi Terraform chạy trên một EC2 instance, nó có thể tự động sử dụng các quyền hạn được cấp cho IAM Role đã gắn với instance đó (gọi là Instance Profile).

    • Đây là một phương thức rất an toàn và được khuyến nghị khi chạy Terraform trong môi trường AWS (ví dụ: máy chủ CI/CD đặt trên EC2). Bạn không cần lưu trữ credentials trên instance.

  4. Hardcoding Credentials trong file .tf (TUYỆT ĐỐI KHÔNG NÊN LÀM!):

    • Mặc dù provider aws có các đối số như access_keysecret_key, việc viết thẳng thông tin xác thực vào code là một rủi ro bảo mật cực kỳ lớn.

    • VÍ DỤ VỀ VIỆC KHÔNG NÊN LÀM:

        # TUYỆT ĐỐI KHÔNG LÀM THEO CÁCH NÀY!
        # provider "aws" {
        #   region     = "us-west-2"
        #   access_key = "AKIAIOSFODNN7EXAMPLE" # KHÔNG BAO GIỜ VIẾT THẲNG VÀO CODE
        #   secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" # KHÔNG BAO GIỜ VIẾT THẲNG VÀO CODE
        # }
      
    • Nếu bạn commit code này lên một repository công khai (hoặc thậm chí cả repository riêng tư), thông tin xác thực của bạn có thể bị lộ.

Thứ tự ưu tiên tìm kiếm credentials của AWS SDK (và do đó là Terraform AWS provider) thường là:

  1. Biến môi trường.

  2. Shared credentials file.

  3. IAM role (nếu chạy trên EC2 hoặc ECS Task, Lambda...).

Khuyến nghị cho series này: Tiếp tục sử dụng Shared Credentials File đã cấu hình qua aws configure.

Cấu hình Chi tiết Khối provider "aws"

Ngoài regionprofile, khối provider "aws" còn nhiều đối số hữu ích khác:

  • region (bắt buộc): Chỉ định AWS Region mặc định cho các tài nguyên được quản lý bởi provider này. Ví dụ: "ap-southeast-1", "us-east-1".

  • profile (tùy chọn): Tên profile trong tệp AWS shared credentials để sử dụng.

  • shared_credentials_files (tùy chọn): Một danh sách các đường dẫn đến tệp credentials, nếu bạn không muốn sử dụng tệp mặc định (~/.aws/credentials hoặc %USERPROFILE%\.aws\credentials).

      # provider "aws" {
      #   shared_credentials_files = ["/custom/path/to/credentials", "~/.aws/team_credentials"]
      #   profile                  = "custom_profile"
      #   region                   = "eu-west-1"
      # }
    
  • default_tags (rất hữu ích):

    • Cho phép bạn định nghĩa một tập hợp các tags (thẻ) mặc định sẽ được tự động áp dụng cho tất cả các tài nguyên AWS có hỗ trợ tagging do provider này quản lý.

    • Điều này giúp đảm bảo tính nhất quán trong việc gắn thẻ, rất quan trọng cho việc quản lý chi phí, tổ chức tài nguyên và tự động hóa.

    • Ví dụ: Terraform

        provider "aws" {
          region = "ap-southeast-1"
      
          default_tags {
            tags = {
              Environment = "Terraform-Learning-Series"
              Project     = "MyBlog"
              ManagedBy   = "Terraform"
              Owner       = "YourName"
            }
          }
        }
      

      Tất cả các tài nguyên (như EC2, S3 bucket, VPC...) được tạo bởi provider này sẽ tự động có các tags trên, trừ khi bạn ghi đè chúng trong định nghĩa của từng resource.

  • assume_role (nâng cao): Cho phép provider đảm nhận một IAM Role khác trước khi thực hiện các hành động. Rất hữu ích trong các kịch bản bảo mật và quản lý đa tài khoản. (Chúng ta sẽ không đi sâu vào đây trong bài này).

Thực hành: Cập nhật main.tfterraform init

Hãy cùng nhau cập nhật tệp main.tf từ Bài 3 để bao gồm cấu hình default_tags:

  1. Mở tệp main.tf trong VS Code.

  2. Cập nhật khối provider "aws" như sau (bạn có thể tùy chỉnh các tags):

     # main.tf
    
     terraform {
       required_version = ">= 1.0"
    
       required_providers {
         aws = {
           source  = "hashicorp/aws"
           version = "~> 5.0"
         }
       }
     }
    
     provider "aws" {
       region = "ap-southeast-1" # Hoặc region bạn đã chọn
    
       default_tags {
         tags = {
           Environment = "Terraform-Blog-Series"
           Course      = "Terraform-For-Beginners"
           ManagedBy   = "Terraform"
         }
       }
     }
    
  3. Lưu tệp main.tf.

  4. Mở Terminal trong thư mục dự án và chạy lại lệnh:

     terraform init
    

    Nếu bạn đã chạy init ở bài trước và phiên bản provider không thay đổi, Terraform có thể sẽ không tải lại gì nhiều mà chỉ xác nhận backend và provider đã được khởi tạo. Nếu có thay đổi về yêu cầu provider, nó sẽ cập nhật.

  5. Kiểm tra cú pháp:

     terraform validate
    

    Nếu không có lỗi, bạn sẽ thấy thông báo "Success! The configuration is valid."

An toàn là trên hết: Quản lý Credentials

Xin nhắc lại một vài điểm quan trọng về bảo mật khi làm việc với AWS credentials:

  • Không bao giờ commit Access Keys hoặc Secret Keys lên Git (hoặc bất kỳ hệ thống quản lý phiên bản nào).

  • Sử dụng tệp .gitignore để loại trừ các tệp nhạy cảm như terraform.tfstate (nếu dùng local state, chúng ta sẽ nói về remote state sau), .terraform/ (thư mục chứa plugins), và các tệp .tfvars chứa thông tin bí mật.

  • Luôn tuân theo Nguyên tắc Đặc quyền Tối thiểu (Principle of Least Privilege): Cấp cho IAM User (hoặc Role) mà Terraform sử dụng chỉ những quyền hạn thực sự cần thiết để thực hiện công việc của nó.

Kết luận

Qua bài viết này, bạn đã hiểu rõ hơn về vai trò của AWS Provider, cách Terraform xác thực với AWS, và cách cấu hình khối provider "aws" trong tệp Terraform, bao gồm cả tính năng default_tags rất hữu ích. Nền tảng kết nối giữa Terraform và AWS của bạn giờ đã được thiết lập một cách vững chắc và an toàn.

Chúng ta đã sẵn sàng cho phần thú vị nhất: tạo ra tài nguyên AWS thực sự! Trong Bài 5: Resource Terraform Đầu tiên trên AWS - Tạo một S3 Bucket Đơn giản, bạn sẽ được tự tay viết code để Terraform tạo ra một S3 bucket trên tài khoản AWS của mình. Đừng bỏ lỡ nhé!

0
Subscribe to my newsletter

Read articles from Dat Ngo Tien directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Dat Ngo Tien
Dat Ngo Tien

Hi friend. Nice to meet you in here. Hope you will find useful information on the blog. Follow and chill with me.