- vừa được xem lúc

DRY folder structure for Terraform

0 0 12

Người đăng: Trinh Huu Vu

Theo Viblo Asia

Giới thiệu

Hiện nay việc định nghĩa và xây dựng infrastructure trên các cloud platform sử dụng ngôn ngữ IaC (Infrastructure as Code) như là Terraform đã quá quen thuộc với mọi người. Gần đây, mình có cơ hội được sử dụng ngôn ngữ này trong dự án thực tế, nên muốn chia sẻ những điều mình đã tìm hiểu và rút ra được. Bài viết sẽ không nhắc lại những kiến thức cơ bản về Terraform, mà sẽ nhắm tới giới thiệu cấu trúc folder DRY cho ngôn ngữ này trong thực tế. (Cụ thể cloud platform trong bài viết sẽ là AWS)

Folder structure

Cụ thể cấu trúc folder mình muốn giới thiệu sẽ như dưới đây.

+- pj-root/ |---- terraform-version | +---- shared/ | +---- main.tf | +---- provider.tf | +---- variables.tf | +---- modules/ | | +---- alb/ | | +----- alb.tf | | +----- listener.tf | | +----- target.tf | | +----- outputs.tf | | +----- variables.tf | | +---- cloudfront/ | | +---- ecs/ | | +---- iam/ | | +---- network/ | | +---- oai/ | | +---- rds/ | | +---- route53/ | | +---- s3/ | | +---- security_group/ +---- env/ | +---- dev/ | | +----- backend.tf | | +----- locals.tf | | +----- terraform.tfvars | | +----- main.tf Symbolic link to /shared/main.tf | | +----- provider.tf Symbolic link to /shared/provider.tf | | +----- variables.tf Symbolic link to /shared/variables.tf | +---- stg/ | +---- prd/ +---- templates/ | +---- ecs/ | +----- sample.json.tftpl +---- backend/ +---- terraform_backend.yaml

Giải thích

  • shared/

    • Định nghĩa các files, modules, variables có thể sử dụng chung ở các môi trường.
    • Các file main.tf, provider.tf, variables.tf sẽ được tạo Symbolic Link tương ứng ở từng môi trường (Dev/Stg/Prd).
    • Thư mục modules/ định nghĩa các modules cho từng service.
  • env/

    • Quản lý các file tf dành riêng cho từng môi trường (Dev/Stg/Prd).
    • Các file main.tf, provider.tf, variables.tf sẽ được link tới các file tương ứng trong thư mục shared bằng Symbolic Link.
    • Với từng môi trường chỉ cần chỉnh sửa các file backend.tf, locals.tf, terrform.tfvars.
  • templates/

    • Lưu các config files và templates có thể tái sử dụng như là ECS Task definition, Lambda source code, CloudWatch Agent, v.v..
  • backend/

    • Lưu CloudFormation template để tạo S3 Bucket và DynamoDB table (nhằm mục đích lưu lại lock state của Terraform Backend)
  • terraform-version

    • File lưu lại version terraform mà dự án sử dụng

Symbolic Link

  • Một điểm cần chú ý trong cấu trúc này là việc sử dụng Symbolic Link
  • Cách tạo Symbolic Link có thể tham khảo ở đây: Symbolic Link
  • Trong các folder môi trường dev, stg, prd, ta sẽ không copy paste từng file main.tf, provider.tf, variables.tf , mà sẽ link tới các file tương ứng trong thư mục shared/.
  • Với cách liên kết này ta có thể đảm bảo quản lý file cho các môi trường một cách đồng bộ và thống nhất.
  • Một điều cần chú ý là khi khai báo source cho các module thì ta cần phải lấy đường dẫn dựa trên thư mục shared/
# Right source path module "sample" { source = "../../shared/modules/sample" sample = local.sample
}
# Wrong source path module "sample" { source = "./modules/sample" sample = local.sample
}

Quản lý tfstate

  • Terraform có support quản lý tfstate remote bằng S3 bucket và DynamoDB table. Đây là 1 tính năng rất hữu ích để đảm bảo state được lưu đồng bộ trên AWS, đặc biệt là khi làm việc trong 1 team đông người.
  • Để sử dụng được chức năng này ta cần tạo trước 1 S3 Bucket và 1 DynamoDB table nhằm lưu lại state dưới dạng key và hỗ trợ state locking và consistency checking
    • Việc tạo S3/DynamoDB này có thể thông qua AWS Console hoặc AWS CLI, tuy nhiên với mục đích sử dụng IaC tối đa có thể, nên trong cấu trúc này đang sử dụng CloudFormation template lưu trong thư mục Backend
    • Sau khi tạo xong ta cần khai báo tên bucket và tên table trong file backend.tf tương ứng cho từng môi trường
    • File sample backend.tf
    terraform { backend "s3" { bucket = "sample-bucket" key = "dev.tfstate" dynamodb_table = "sample-table" region = "ap-northeast-1" }
    }
    

Sử dụng template

  • Ta có thể định nghĩa ra template cho các config file thường lặp đi lặp lại (Ví dụ như ECS task definition), trong đó định nghĩa các variable cho những phần có thể thay đổi
  • Sau đó, ở các module sẽ sử dụng function templatefile và truyền vào value các variable này.

VD cách sử dụng template với trường hợp ECS

templates/ecs/sample_task_definition.json.tftpl

[ { "name": "sample_task", "image": "${repository_url}:latest", "cpu": 0, "portMappings": [ { "containerPort": 80, "hostPort": 80, "protocol": "tcp" } ], "essential": true, "environment": [], "mountPoints": [], "volumesFrom": [], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/sample-${environment}-task", "awslogs-region": "${region}", "awslogs-stream-prefix": "ecs" } } }
]

shared/modules/ecs/task_definition.tf

resource "aws_ecs_task_definition" "sample" { family = "sample-${var.environment}-task" container_definitions = templatefile("../../templates/ecs/sample_task_definition.json.tftpl", { region = var.region, environment = var.environment repository_url = aws_ecr_repository.sample.repository_url }) ...
}

DRY syntax

Khi định nghĩa các service trong từng module, ta cần chú ý tận dụng các Meta-Argument và Build-in Function mà Terraform cung cấp để không cần phải lặp đi lặp lại code để định nghĩa cho các instance/resource tương tự nhau. (Đảm bảo tính DRY)

Một vài command hữu dụng

Ngoài các command cơ bản như init, plan, apply, mình muốn giới thiệu 1 vài command mình thấy khá hữu dụng khi làm việc với Terraform

1/ Validate syntax in all .tf files

terraform validate

2/ Force unlock Terraform state lock

terraform force-unlock [options] LOCK_ID

3/ List resources within a Terraform state

terraform state list [options] [address...]

4/ Destroy specific resources

terraform destroy -target RESOURCE_TYPE.NAME

Lời kết

Trên đây là cấu trúc folder DRY cho Terraform mà mình đã tìm hiểu được, ngoài ra cũng có một số thông tin mình rút ra được trong quá trình áp dụng cấu trúc này vào dự án thực tế. Mong bài viết sẽ giúp ích cho mọi người trong công việc hoặc đơn giản là trong quá trình tìm hiểu về Terraform.

References

TerraformにおけるDRYなディレクトリ構成

Terraform developer docs

Bình luận

Bài viết tương tự

- vừa được xem lúc

Nhập môn Infrastructure as Code - Sử dụng Terraform để provision infrastructure trên GCP

Hôm nay, mình sẽ dành thời gian để viết 1 bài Hands-on đơn giản về Terraform - Một công cụ để viết Infrastructrure as Code. .

0 0 53

- vừa được xem lúc

Terraform Series - Bài 1 - Infrastructure as Code và Terraform

Giới thiệu. Chào các bạn tới với series về Terraform.

0 0 23

- vừa được xem lúc

Terraform Series - Bài 2 - Life cycle của một resource trong Terraform

Giới thiệu. Chào các bạn tới với series về Terraform.

0 0 52

- vừa được xem lúc

Terraform Series - Bài 3 - Terraform functional programming

Giới thiệu. Chào các bạn tới với series về Terraform.

0 0 20

- vừa được xem lúc

Terraform và các câu hỏi thường gặp khi đi phỏng vấn

Khi đọc tiêu đề bạn có thể thấy lạ, thông thường nhà tuyển dụng(interviewer) sẽ hỏi các câu hỏi liên quan tới terraform cho ứng viên devops, nhưng mình ứng tuyển vào vị trí backend developer lại bị hỏ

0 0 58

- vừa được xem lúc

Terraform Series - Bài 4 - Terraform Module: Create Virtual Private Cloud on AWS

Giới thiệu. Chào các bạn tới với series về Terraform, ở bài trước chúng ta đã nói về cách viết một số config cơ bản trong Terraform.

0 0 69