Các phương pháp hay nhất khi sử dụng Terraform [đã đóng]


111

Tôi đang trong quá trình chuyển đổi cơ sở hạ tầng của chúng tôi thành địa hình. Thực tiễn tốt nhất để thực sự quản lý các tệp và trạng thái địa hình là gì? Tôi nhận ra đó là cơ sở hạ tầng dưới dạng mã và tôi sẽ cam kết các tệp .tf của mình thành git, nhưng tôi có cam kết cả tfstate không? Có nên cư trú ở đâu đó như S3 không? Cuối cùng tôi cũng muốn CI quản lý tất cả những điều này, nhưng điều đó đã kéo dài quá mức và đòi hỏi tôi phải tìm ra các phần chuyển động cho các tệp.

Tôi thực sự chỉ muốn xem mọi người ngoài kia thực sự sử dụng loại công cụ này như thế nào trong sản xuất

Câu trả lời:


85

Tôi cũng đang trong tình trạng di chuyển cơ sở hạ tầng AWS hiện có sang Terraform, vì vậy tôi sẽ cố gắng cập nhật câu trả lời khi tôi phát triển.

Tôi đã dựa rất nhiều vào các ví dụ Terraform chính thức và nhiều lần thử và sai để xác định các khu vực mà tôi không chắc chắn.

.tfstate các tập tin

Cấu hình Terraform có thể được sử dụng để cung cấp nhiều hộp trên cơ sở hạ tầng khác nhau, mỗi hộp có thể có một trạng thái khác nhau. Vì nó cũng có thể được điều hành bởi nhiều người, trạng thái này phải ở một vị trí tập trung (như S3) nhưng không git.

Điều này có thể được xác nhận khi nhìn vào Terraform .gitignore .

Kiểm soát nhà phát triển

Mục đích của chúng tôi là cung cấp nhiều quyền kiểm soát hơn đối với cơ sở hạ tầng cho các nhà phát triển trong khi vẫn duy trì kiểm tra đầy đủ (git log) và khả năng kiểm tra các thay đổi (yêu cầu kéo). Với ý nghĩ đó, quy trình làm việc cơ sở hạ tầng mới mà tôi đang hướng tới là:

  1. Nền tảng cơ bản của AMI thông thường bao gồm các mô-đun có thể tái sử dụng, ví dụ như con rối.
  2. Cơ sở hạ tầng cốt lõi do DevOps cung cấp bằng Terraform.
  3. Các nhà phát triển thay đổi cấu hình Terraform trong Git nếu cần (số lượng phiên bản; VPC mới; bổ sung khu vực / vùng khả dụng, v.v.).
  4. Cấu hình Git được đẩy và một yêu cầu kéo được gửi để được kiểm tra bởi một thành viên của nhóm DevOps.
  5. Nếu được chấp thuận, hãy gọi webhook tới CI để xây dựng và triển khai (không chắc chắn cách phân vùng nhiều môi trường tại thời điểm này)

Chỉnh sửa 1 - Cập nhật trạng thái hiện tại

Kể từ khi bắt đầu câu trả lời này, tôi đã viết rất nhiều mã TF và cảm thấy thoải mái hơn trong tình trạng của chúng tôi. Chúng tôi đã gặp phải những lỗi và hạn chế trong quá trình thực hiện nhưng tôi chấp nhận đây là đặc điểm của việc sử dụng phần mềm mới, thay đổi nhanh chóng.

Bố trí

Chúng tôi có một cơ sở hạ tầng AWS phức tạp với nhiều VPC, mỗi VPC có nhiều mạng con. Chìa khóa để dễ dàng quản lý điều này là xác định một phân loại linh hoạt bao gồm khu vực, môi trường, dịch vụ và chủ sở hữu mà chúng ta có thể sử dụng để tổ chức mã cơ sở hạ tầng của mình (cả địa hình và con rối).

Mô-đun

Bước tiếp theo là tạo một kho lưu trữ git duy nhất để lưu trữ các mô-đun địa hình của chúng tôi. Cấu trúc dir cấp cao nhất của chúng tôi cho các mô-đun trông như thế này:

tree -L 1 .

Kết quả:

├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates

Mỗi người đặt một số mặc định lành mạnh nhưng hiển thị chúng dưới dạng các biến có thể bị ghi đè bởi "keo" của chúng tôi.

Keo dán

Chúng tôi có một kho lưu trữ thứ hai với của chúng tôi glueđể sử dụng các mô-đun được đề cập ở trên. Nó được trình bày phù hợp với tài liệu phân loại của chúng tôi:

.
├── README.md
├── clientA
   ├── eu-west-1
      └── dev
   └── us-east-1
       └── dev
├── clientB
   ├── eu-west-1
      ├── dev
      ├── ec2-keys.tf
      ├── prod
      └── terraform.tfstate
   ├── iam.tf
   ├── terraform.tfstate
   └── terraform.tfstate.backup
└── clientC
    ├── eu-west-1
       ├── aws.tf
       ├── dev
       ├── iam-roles.tf
       ├── ec2-keys.tf
       ├── prod
       ├── stg
       └── terraform.tfstate
    └── iam.tf

Bên trong cấp độ khách hàng, chúng tôi có các .tftệp tài khoản AWS cụ thể cung cấp tài nguyên toàn cầu (như vai trò IAM); tiếp theo là cấp vùng với khóa công khai EC2 SSH; Cuối cùng trong môi trường của chúng tôi ( dev, stg,prod vv) là thiết lập VPC, tạo ví dụ của chúng tôi và nhìn chăm chú kết nối vv được lưu trữ.

Lưu ý phụ: Như bạn có thể thấy, tôi đang đi ngược lại lời khuyên của riêng tôi ở trên giữterraform.tfstate git. Đây là biện pháp tạm thời cho đến khi tôi chuyển sang S3 nhưng phù hợp với tôi vì tôi hiện là nhà phát triển duy nhất.

Bước tiếp theo

Đây vẫn là một quy trình thủ công và chưa có trong Jenkins nhưng chúng tôi đang chuyển một cơ sở hạ tầng khá lớn, phức tạp và cho đến nay rất tốt. Như tôi đã nói, ít lỗi nhưng sẽ tốt!

Chỉnh sửa 2 - Thay đổi

Đã gần một năm kể từ khi tôi viết câu trả lời đầu tiên này và trạng thái của cả Terraform và bản thân tôi đã thay đổi đáng kể. Bây giờ tôi đang ở một vị trí mới khi sử dụng Terraform để quản lý một cụm Azure và Terraform bây giờ là như vậy v0.10.7.

Tiểu bang

Mọi người đã nhiều lần nói với tôi rằng nhà nước không nên sử dụng Git - và họ đã đúng. Chúng tôi đã sử dụng điều này như một biện pháp tạm thời với một nhóm hai người dựa vào giao tiếp và kỷ luật của nhà phát triển. Với một nhóm lớn hơn, phân tán, chúng tôi hiện đang tận dụng hoàn toàn trạng thái từ xa trong S3 với khóa do DynamoDB cung cấp. Lý tưởng nhất là điều này sẽ được chuyển sang lãnh sự bây giờ là v1.0 để cắt các nhà cung cấp đám mây chéo.

Mô-đun

Trước đây chúng tôi đã tạo và sử dụng các mô-đun nội bộ. Điều này vẫn xảy ra nhưng với sự ra đời và phát triển của sổ đăng ký Terraform, chúng tôi cố gắng sử dụng chúng làm cơ sở ít nhất.

Cấu trúc tệp

Vị trí mới có cách phân loại đơn giản hơn nhiều chỉ với hai môi trường infx - devprod. Mỗi biến có các biến và kết quả đầu ra riêng, sử dụng lại các mô-đun của chúng tôi đã tạo ở trên. Nhà remote_statecung cấp cũng giúp chia sẻ kết quả đầu ra của các tài nguyên đã tạo giữa các môi trường. Kịch bản của chúng tôi là các miền phụ trong các nhóm tài nguyên Azure khác nhau đến một TLD được quản lý toàn cầu.

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
    ├── main.tf
    ├── output.tf
    └── variables.tf

Lập kế hoạch

Một lần nữa với những thách thức bổ sung của một nhóm phân tán, giờ đây chúng tôi luôn lưu đầu ra của terraform planlệnh. Chúng tôi có thể kiểm tra và biết những gì sẽ được chạy mà không có rủi ro về một số thay đổi giữa planapply giai đoạn giai đoạn (mặc dù việc khóa giúp ích cho việc này). Hãy nhớ xóa tệp kế hoạch này vì nó có thể chứa các biến "bí mật" văn bản thuần túy.

Nhìn chung, chúng tôi rất hài lòng với Terraform và tiếp tục học hỏi và cải thiện với các tính năng mới được thêm vào.


Bạn có gặp may mắn / vấn đề nào kể từ câu trả lời này không? Của bạn có vẻ rất giống những gì tôi muốn làm, nhưng bạn có thể tiến xa hơn tôi.
Marc Young

3
Tôi tò mò là tại sao bạn nghĩ rằng các tệp tfstate không nên được lưu trữ trong git? Đơn giản là vì trạng thái cũ không đáng để lưu, hay có vấn đề gì khác?
agbodike

3
@agbodike - Khi làm việc với tư cách là một nhà phát triển đơn lẻ hoặc một phần của một nhóm rất nhỏ, tfstate có thể được giữ trong git miễn là nó được cam kết và đẩy thường xuyên để tránh xung đột. Bước tiếp theo của tôi là thiết lập điều này theo tài liệu trạng thái từ xa của họ trong S3 (cũng cho biết: "nó làm cho việc làm việc với Terraform trong một nhóm trở nên phức tạp vì nó là nguồn thường xuyên gây ra xung đột hợp nhất. Trạng thái từ xa giúp giảm bớt những vấn đề này.") . Như với hầu hết mọi thứ dù tốt đội ngũ truyền thông có thể giúp làm giảm bớt nhất / tất cả các vấn đề bất kể của chiến thuật để nhà nước giữ :-)
Ewan

1
@ the0ther - Tôi e rằng kho lưu trữ chính của tôi là độc quyền tuy nhiên tôi hiện đang làm việc trên một kho lưu trữ cá nhân mà tôi sẽ công bố rộng rãi trong tương lai gần.
Ewan

2
Có may mắn nào trên Git repo @Ewan không? Tôi muốn xem bạn đang làm gì.
David,

85

Chúng tôi sử dụng Terraform rất nhiều và thiết lập được đề xuất của chúng tôi như sau:

Bố cục tệp

Chúng tôi thực sự khuyên bạn nên lưu trữ mã Terraform cho từng môi trường của bạn (ví dụ: stage, prod, qa) trong các tập mẫu riêng biệt (và do đó, .tfstatecác tệp riêng biệt ). Điều này rất quan trọng để các môi trường riêng biệt của bạn thực sự tách biệt với nhau trong khi thực hiện các thay đổi. Nếu không, trong khi lộn xộn với một số mã trong dàn dựng, quá dễ dàng để làm nổ tung một cái gì đó trong sản phẩm. Xem Terraform, VPC và lý do bạn muốn có tệp tfstate trên mỗi env để có một cuộc thảo luận đầy màu sắc về lý do.

Do đó, bố cục tệp điển hình của chúng tôi trông giống như sau:

stage
   main.tf
   vars.tf
   outputs.tf
prod
   main.tf
   vars.tf
   outputs.tf
global
   main.tf
   vars.tf
   outputs.tf

Tất cả mã Terraform cho giai đoạn VPC đi vào stagethư mục, tất cả mã cho VPC sản phẩm đi vào prodthư mục và tất cả mã nằm bên ngoài VPC (ví dụ: người dùng IAM, chủ đề SNS, nhóm S3) đi vàoglobal thư mục .

Lưu ý rằng, theo quy ước, chúng tôi thường chia mã Terraform của mình thành 3 tệp:

  • vars.tf: Các biến đầu vào.
  • outputs.tf: Các biến đầu ra.
  • main.tf: Các tài nguyên thực tế.

Mô-đun

Thông thường, chúng tôi xác định cơ sở hạ tầng của mình trong hai thư mục:

  1. infrastructure-modules: Thư mục này chứa các mô-đun nhỏ, có thể tái sử dụng, được tạo phiên bản. Hãy coi mỗi mô-đun như một bản thiết kế cho cách tạo một phần cơ sở hạ tầng, chẳng hạn như VPC hoặc cơ sở dữ liệu.
  2. infrastructure-live: Thư mục này chứa cơ sở hạ tầng đang hoạt động thực tế mà nó tạo ra bằng cách kết hợp các mô-đun vào infrastructure-modules. Hãy coi đoạn mã trong thư mục này giống như những ngôi nhà thực tế mà bạn đã xây dựng từ bản thiết kế của mình.

Một Terraform mô-đun chỉ là bất kỳ bộ Terraform mẫu trong một thư mục. Ví dụ: chúng ta có thể có một thư mục được gọi vpctrong infrastructure-modulesđó xác định tất cả các bảng định tuyến, mạng con, cổng, ACL, v.v. cho một VPC:

infrastructure-modules
   vpc
     main.tf
     vars.tf
     outputs.tf

Sau đó, chúng tôi có thể sử dụng mô-đun đó trong infrastructure-live/stageinfrastructure-live/prodđể tạo các VPC sân khấu và sản phẩm. Ví dụ: đây là những gì infrastructure-live/stage/main.tfcó thể trông như thế này:

module "stage_vpc" {
  source = "git::git@github.com:gruntwork-io/module-vpc.git//modules/vpc-app?ref=v0.0.4"

  vpc_name         = "stage"
  aws_region       = "us-east-1"
  num_nat_gateways = 3
  cidr_block       = "10.2.0.0/18"
}

Để sử dụng một mô-đun, bạn sử dụng moduletài nguyên và trỏ sourcetrường của nó tới một đường dẫn cục bộ trên ổ cứng của bạn (ví dụ source = "../infrastructure-modules/vpc") hoặc, như trong ví dụ trên, một URL Git (xem nguồn mô-đun ). Ưu điểm của URL Git là chúng ta có thể chỉ định một git sha1 hoặc thẻ ( ref=v0.0.4) cụ thể. Bây giờ, chúng tôi không chỉ xác định cơ sở hạ tầng của mình là một loạt các mô-đun nhỏ, mà chúng tôi có thể phiên bản các mô-đun đó và cập nhật hoặc khôi phục cẩn thận khi cần thiết.

Chúng tôi đã tạo một số Gói cơ sở hạ tầng có thể sử dụng lại, đã thử nghiệm và được lập thành văn bản để tạo VPC, cụm Docker, cơ sở dữ liệu, v.v.

Tiểu bang

Khi bạn sử dụng Terraform để tạo tài nguyên (ví dụ: phiên bản EC2, cơ sở dữ liệu, VPC), nó sẽ ghi lại thông tin về những gì nó đã tạo trong một .tfstatetệp. Để thực hiện các thay đổi đối với các tài nguyên đó, mọi người trong nhóm của bạn cần có quyền truy cập vào cùng một .tfstatetệp này, nhưng bạn KHÔNG nên kiểm tra nó vào Git (xem tại đây để giải thích lý do ).

Thay vào đó, chúng tôi khuyên bạn nên lưu trữ .tfstatetệp trong S3 bằng cách bật Trạng thái Từ xa Terraform , trạng thái này sẽ tự động đẩy / kéo các tệp mới nhất mỗi khi bạn chạy Terraform. Đảm bảo bật lập phiên bản trong bộ chứa S3 của bạn để bạn có thể quay lại các .tfstatetệp cũ hơn trong trường hợp bằng cách nào đó bạn làm hỏng phiên bản mới nhất. Tuy nhiên, một lưu ý quan trọng: Terraform không cung cấp khóa . Vì vậy, nếu hai thành viên trong nhóm chạy terraform applycùng lúc trên cùng một .tfstatetệp, họ có thể ghi đè các thay đổi của nhau.

Để giải quyết vấn đề này, chúng tôi đã tạo một công cụ mã nguồn mở có tên Terragrunt , là một công cụ bao bọc mỏng cho Terraform, sử dụng Amazon DynamoDB để cung cấp khóa (nên hoàn toàn miễn phí cho hầu hết các nhóm). Kiểm tra Thêm cấu hình và khóa trạng thái từ xa tự động vào Terraform với Terragrunt để biết thêm thông tin.

đọc thêm

Chúng tôi vừa bắt đầu một loạt các bài đăng trên blog có tên Hướng dẫn toàn diện về Terraform mô tả chi tiết tất cả các phương pháp hay nhất mà chúng tôi đã học được để sử dụng Terraform trong thế giới thực.

Cập nhật: loạt bài đăng trên blog Hướng dẫn Toàn diện về Terraform trở nên phổ biến đến nỗi chúng tôi đã mở rộng nó thành một cuốn sách có tên Terraform: Up & Running !


Tôi nghĩ đây là câu trả lời chính xác. Sử dụng các mô-đun, phiên bản chúng và giữ các môi trường riêng biệt.
wrangler

Bước cấu hình từ xa có cần phải chạy lại mỗi khi bạn muốn làm việc trên một thành phần / môi trường / mô-đun / mô-đun địa hình khác nhau nếu không sử dụng terragrunt hoặc một số trình bao bọc khác không?
jmreicha

@jmreicha: Bạn cần chạy remote confignếu bạn vừa kiểm tra cấu hình Terraform của mình hoặc nếu bạn muốn thay đổi cấu hình từ xa trước đó. Terraform 0.9 sẽ giới thiệu khái niệm về backends, sẽ đơn giản hóa rất nhiều điều này. Xem PR này để biết thêm chi tiết.
Yevgeniy Brikman

Chỉ để tôi hiểu - tôi đang làm việc trên một môi trường 'sân khấu' nhưng sau đó bắt đầu làm việc trên 'sản phẩm'. Tôi sẽ cần chạy lại remote configlệnh để chỉ vào trạng thái sản phẩm. Giả sử trạng thái khác nhau cho mỗi môi trường. Có đúng không? Tôi mong chờ v0.9.
jmreicha

Nếu bạn định triển khai cùng một tập hợp .tftệp cho hai môi trường khác nhau, thì có, bạn cần chạy remote configmỗi khi chuyển đổi. Điều này rõ ràng là rất dễ xảy ra lỗi, vì vậy tôi không khuyên bạn thực sự sử dụng kỹ thuật này. Thay vào đó, hãy xem bố cục tệp Terraform được đề xuất trong bài đăng blog này cùng với cách sử dụng mô-đun Terraform trong bài đăng blog này .
Yevgeniy Brikman

9

Trước đây remote configcho phép điều này nhưng bây giờ đã được thay thế bằng " phụ trợ ", vì vậy điều khiển từ xa bằng terraform không khả dụng nữa.

terraform remote config -backend-config="bucket=<s3_bucket_to_store_tfstate>" -backend-config="key=terraform.tfstate" -backend=s3
terraform remote pull
terraform apply
terraform remote push

Xem tài liệu để biết chi tiết.


Nguồn từ xa có cần phải được cấu hình lại mỗi khi bạn muốn làm việc trên một thành phần / môi trường / mô-đun / bất cứ thứ gì địa hình khác nhau không?
jmreicha

6

Được @Yevgeny Brikman đề cập sâu hơn nhưng trả lời cụ thể các câu hỏi của OP:

Thực tiễn tốt nhất để thực sự quản lý các tệp và trạng thái địa hình là gì?

Sử dụng git cho các tệp TF. Nhưng đừng kiểm tra tệp trạng thái trong (tức là tfstate). Thay vào đó, sử dụng Terragruntđể đồng bộ / khóa các tệp trạng thái với S3.

nhưng tôi có cam kết tfstate không?

Không.

Có nên cư trú ở đâu đó như S3 không?

Đúng


2

Tôi biết có rất nhiều câu trả lời ở đây nhưng cách tiếp cận của tôi khá khác biệt.

   Modules
   Environment management 
   Separation of duties

Mô-đun

  1. Tạo mô-đun cho các bộ sưu tập tài nguyên hợp lý. Ví dụ: Nếu mục tiêu của bạn là triển khai một API, yêu cầu DB, HA VM, tự động phân cấp, DNS, PubSub và lưu trữ đối tượng thì tất cả các tài nguyên này nên được tạo mẫu trong một mô-đun duy nhất.
  2. Tránh tạo các mô-đun sử dụng một tài nguyên duy nhất. Điều này có thể và đã được thực hiện và rất nhiều mô-đun trong sổ đăng ký làm điều này nhưng đó là một phương pháp giúp hỗ trợ khả năng truy cập tài nguyên hơn là điều phối cơ sở hạ tầng. Ví dụ: Một mô-đun cho AWS EC2 giúp người dùng truy cập vào EC2 bằng cách làm cho các cấu hình phức tạp trở nên đơn giản hơn để gọi nhưng một mô-đun như ví dụ trong 1. hỗ trợ người dùng khi điều phối cơ sở hạ tầng hướng ứng dụng, thành phần hoặc dịch vụ.
    1. Tránh khai báo tài nguyên trong không gian làm việc của bạn. Điều này là về việc giữ cho mã của bạn ngăn nắp và có tổ chức. Vì các mô-đun được tạo phiên bản dễ dàng, bạn có nhiều quyền kiểm soát hơn đối với các bản phát hành của mình.

Quản lý môi trường

IaC đã thực hiện quy trình SDLC liên quan đến quản lý cơ sở hạ tầng và không bình thường khi mong đợi có cơ sở hạ tầng phát triển cũng như môi trường ứng dụng phát triển.

  1. Không sử dụng các thư mục để quản lý môi trường IaC của bạn. Điều này dẫn đến việc không có mẫu chung cho cơ sở hạ tầng của bạn.
  2. Sử dụng một không gian làm việc và các biến để kiểm soát các thông số kỹ thuật của môi trường. Ví dụ: Viết các mô-đun của bạn để khi bạn thay đổi biến môi trường (var.stage là phổ biến), kế hoạch sẽ thay đổi để phù hợp với yêu cầu của bạn. Thông thường, các môi trường phải thay đổi càng ít càng tốt với số lượng, độ phơi sáng và dung lượng thường là các cấu hình thay đổi. Nhà phát triển có thể triển khai 1 VM với 1 lõi và RAM 1GB trong cấu trúc liên kết riêng nhưng sản xuất có thể là 3 máy ảo với 2 lõi và RAM 4GB với cấu trúc liên kết chung bổ sung. Tất nhiên, bạn có thể có nhiều biến thể hơn: dev có thể chạy quy trình cơ sở dữ liệu trên cùng một máy chủ với ứng dụng để tiết kiệm chi phí nhưng sản xuất có thể có một phiên bản DB chuyên dụng. Tất cả những điều này có thể được quản lý bằng cách thay đổi một biến đơn, các câu lệnh bậc ba và phép nội suy.

Tách nhiệm vụ

Nếu bạn đang ở trong một tổ chức nhỏ hoặc đang điều hành cơ sở hạ tầng cá nhân, điều này không thực sự áp dụng nhưng nó sẽ giúp bạn quản lý hoạt động của mình.

  1. Chia nhỏ cơ sở hạ tầng của bạn theo nhiệm vụ, trách nhiệm hoặc nhóm. Ví dụ: Kiểm soát CNTT trung tâm các dịch vụ chia sẻ cơ bản (mạng ảo, mạng con, địa chỉ IP công cộng, nhóm nhật ký, tài nguyên quản trị, DB nhiều người thuê, khóa chia sẻ, v.v.) trong khi nhóm API chỉ kiểm soát các tài nguyên cần thiết cho dịch vụ của họ (VM, LB , PubSub, v.v.) và sử dụng các dịch vụ CNTT Trung tâm thông qua nguồn dữ liệu và tra cứu trạng thái từ xa.
    1. Quyền truy cập của nhóm chính phủ. Ví dụ: Trung tâm CNTT có thể có quyền quản trị nhưng nhóm API chỉ có quyền truy cập vào một nhóm API đám mây công khai bị hạn chế.

Điều này cũng giúp giải tỏa những lo lắng vì bạn sẽ thấy một số tài nguyên hiếm khi thay đổi trong khi những tài nguyên khác luôn thay đổi. Sự tách biệt loại bỏ rủi ro và phức tạp.

Chiến lược này tương đồng với chiến lược đa tài khoản của AWS. Hãy đọc để biết thêm thông tin.

CI / CD

Đây là một chủ đề của riêng nó nhưng Terraform hoạt động rất tốt trong một quy trình tốt. Lỗi phổ biến nhất ở đây là coi CI như một viên đạn bạc. Về mặt kỹ thuật, Terraform chỉ nên cung cấp cơ sở hạ tầng trong các giai đoạn của một đường ống lắp ráp. Điều này sẽ tách biệt với những gì xảy ra trong các giai đoạn CI, nơi người ta thường xác nhận và kiểm tra các mẫu.

NB Được viết trên di động nên xin miễn có lỗi.


0

Trước khi các câu trả lời rất chắc chắn và đầy đủ thông tin, tôi sẽ cố gắng thêm 2 xu của mình vào đây

Các khuyến nghị phổ biến để cấu trúc mã

  1. Làm việc với số lượng tài nguyên nhỏ hơn sẽ dễ dàng và nhanh hơn:

    • Cmds terraform planterraformứng dụng đều thực hiện lệnh gọi API đám mây để xác minh trạng thái của tài nguyên.
    • Nếu bạn có toàn bộ cơ sở hạ tầng của mình trong một thành phần duy nhất, việc này có thể mất nhiều phút (ngay cả khi bạn có nhiều tệp trong cùng một thư mục).
  2. Bán kính vụ nổ nhỏ hơn với ít tài nguyên hơn:

    • Cách ly các tài nguyên không liên quan với nhau bằng cách đặt chúng trong các thành phần (thư mục) riêng biệt giúp giảm rủi ro nếu có sự cố.
  3. Bắt đầu dự án của bạn bằng trạng thái từ xa:

  4. Cố gắng thực hành một cấu trúc nhất quán và quy ước đặt tên:

    • Giống như mã thủ tục, mã Terraform nên được viết để mọi người đọc trước, tính nhất quán sẽ hữu ích khi các thay đổi xảy ra sau sáu tháng kể từ bây giờ.
    • Có thể di chuyển tài nguyên trong tệp trạng thái Terraform nhưng có thể khó thực hiện hơn nếu bạn có cấu trúc và cách đặt tên không nhất quán.
  5. Giữ các mô-đun tài nguyên càng đơn giản càng tốt.

  6. Không mã hóa các giá trị có thể được chuyển dưới dạng biến hoặc được phát hiện bằng cách sử dụng các nguồn dữ liệu.

  7. Sử dụng datacác nguồn và terraform_remote_statecụ thể là chất kết dính giữa các mô-đun cơ sở hạ tầng trong thành phần.

( bài viết tham khảo: https://www.terraform-best-practices.com/code-osystem )


Thí dụ:

Làm việc với số lượng tài nguyên ít hơn sẽ dễ dàng và nhanh hơn, vì vậy dưới đây chúng tôi trình bày một bố cục mã được đề xuất.

LƯU Ý: chỉ là tài liệu tham khảo không cần tuân thủ nghiêm ngặt vì mỗi dự án có những đặc điểm cụ thể riêng

.
├── 1_tf-backend #remote AWS S3 + Dynamo Lock tfstate 
   ├── main.tf
   ├── ...
├── 2_secrets
   ├── main.tf
   ├── ...
├── 3_identities
   ├── account.tf
   ├── roles.tf
   ├── group.tf
   ├── users.tf
   ├── ...
├── 4_security
   ├── awscloudtrail.tf
   ├── awsconfig.tf
   ├── awsinspector.tf
   ├── awsguarduty.tf
   ├── awswaf.tf
   └── ...
├── 5_network
   ├── account.tf
   ├── dns_remote_zone_auth.tf
   ├── dns.tf
   ├── network.tf
   ├── network_vpc_peering_dev.tf
   ├── ...
├── 6_notifications
   ├── ...
├── 7_containers
   ├── account.tf
   ├── container_registry.tf
   ├── ...
├── config
   ├── backend.config
   └── main.config
└── readme.md

0

Tôi tin rằng có một số phương pháp hay nhất cần tuân theo khi sử dụng terraform để điều phối cơ sở hạ tầng

  1. Không viết lại cùng một mã (Khả năng tái sử dụng)
  2. Giữ cấu hình môi trường riêng biệt để duy trì nó dễ dàng.
  3. Sử dụng chương trình phụ trợ từ xa s3 (được mã hóa) và Dyo DB để xử lý khóa đồng thời
  4. Tạo một mô-đun và sử dụng mô-đun đó trong cơ sở hạ tầng chính nhiều lần, nó giống như một chức năng có thể tái sử dụng có thể được gọi nhiều lần bằng cách truyền tham số khác nhau.

Xử lý nhiều môi trường

Hầu hết thời gian, cách được đề xuất là sử dụng 'không gian làm việc' theo địa hình để xử lý nhiều môi trường nhưng tôi tin rằng việc sử dụng không gian làm việc có thể thay đổi tùy theo cách làm việc trong một tổ chức. Khác là lưu trữ mã Terraform cho từng môi trường của bạn (ví dụ: giai đoạn, sản phẩm, QA) để tách các trạng thái môi trường. Tuy nhiên, trong trường hợp này, chúng tôi chỉ sao chép cùng một mã ở nhiều nơi.

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf

Tôi đã làm theo một số cách tiếp cận khác nhau để xử lý và tránh trùng lặp mã địa hình giống nhau bằng cách giữ trong mỗi thư mục môi trường vì tôi tin rằng hầu hết thời gian tất cả môi trường sẽ giống nhau 90%.

├── deployment
 ├── 01-network.tf
 ├── 02-ecs_cluster.tf
 ├── 03-ecs_service.tf
 ├── 04-eks_infra.tf
 ├── 05-db_infra.tf
 ├── 06-codebuild-k8s.tf
 ├── 07-aws-secret.tf
 ├── backend.tf
 ├── provider.tf
 └── variables.tf
├── env
 ├── dev
  ├── dev.backend.tfvar
  └── dev.variables.tfvar
 └── prod
 ├── prod.backend.tfvar
 └── prod.variables.tfvar
├── modules
 └── aws
 ├── compute
  ├── alb_loadbalancer
  ├── alb_target_grp
  ├── ecs_cluster
  ├── ecs_service
  └── launch_configuration
 ├── database
  ├── db_main
  ├── db_option_group
  ├── db_parameter_group
  └── db_subnet_group
 ├── developertools
 ├── network
  ├── internet_gateway
  ├── nat_gateway
  ├── route_table
  ├── security_group
  ├── subnet
  ├── vpc
 └── security
 ├── iam_role
 └── secret-manager
└── templates

Cấu hình liên quan đến môi trường

Giữ cấu hình và thông số liên quan đến môi trường riêng biệt trong một tệp biến và chuyển giá trị đó để định cấu hình cơ sở hạ tầng. ví dụ như dưới đây

  • dev.backend.tfvar

      region = "ap-southeast-2"
      bucket = "dev-samplebackendterraform"
      key = "dev/state.tfstate"
      dynamo_db_lock = "dev-terraform-state-lock"
  • dev.variable.tfvar

    environment                     =   "dev"
    vpc_name                        =   "demo"
    vpc_cidr_block                  =   "10.20.0.0/19"
    private_subnet_1a_cidr_block    =   "10.20.0.0/21"
    private_subnet_1b_cidr_block    =   "10.20.8.0/21"
    public_subnet_1a_cidr_block     =   "10.20.16.0/21"
    public_subnet_1b_cidr_block     =   "10.20.24.0/21"

Bỏ qua có điều kiện phần cơ sở hạ tầng

Tạo một cấu hình trong tệp biến cụ thể env và dựa trên biến đó quyết định tạo hoặc bỏ qua phần đó. Theo cách này dựa trên nhu cầu, phần cụ thể của cơ sở hạ tầng có thể được bỏ qua.

variable vpc_create {
   default = "true"
}

module "vpc" {
  source = "../modules/aws/network/vpc"
  enable = "${var.vpc_create}"
  vpc_cidr_block = "${var.vpc_cidr_block}"
  name = "${var.vpc_name}"
 }

 resource "aws_vpc" "vpc" {
    count                = "${var.enable == "true" ? 1 : 0}"
    cidr_block           = "${var.vpc_cidr_block}"
    enable_dns_support   = "true"
   enable_dns_hostnames = "true"
}

lệnh dưới đây được yêu cầu để khởi tạo và thực thi các thay đổi hạ tầng cho từng môi trường, cd vào thư mục môi trường được yêu cầu.

  terraform init -var-file=dev.variables.tfvar -backend-config=dev.backend.tfvar ../../deployment/

  terraform apply -var-file=dev.variables.tfvar ../../deployment

Để tham khảo: https://github.com/mattyait/devops_terraform


0

Tôi không thích ý tưởng về các thư mục con vì điều này sẽ dẫn đến các nguồn khác nhau trên mỗi môi trường và điều này có xu hướng bị trôi.

Cách tiếp cận tốt hơn là có một ngăn xếp duy nhất cho tất cả các môi trường (giả sử như dev, preprod và prod). Để làm việc trên một môi trường sử dụng terraform workspace.

terraform workspace new dev

Điều này tạo ra một không gian làm việc mới. Điều này bao gồm một tệp trạng thái chuyên dụng và biến terraform.workspacebạn có thể sử dụng trong mã của mình.

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${terraform.workspace}"
}

Bằng cách này, bạn sẽ nhận được các nhóm được gọi là

  • my-tf-test-bucket-dev
  • my-tf-test-bucket-preprod
  • my-tf-test-bucket-prod

sau khi áp dụng cho các vùng làm việc trên (sử dụng terraform workspace select <WORKSPACE>để thay đổi môi trường). Để làm cho mã thậm chí có khả năng chống đa vùng, hãy làm như sau:

data "aws_region" "current" {}

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${data.aws_region.current.name}-${terraform.workspace}"
}

để có được (cho chúng tôi-đông-1 khu vực)

  • my-tf-test-bucket-us-west-1-dev
  • my-tf-test-bucket-us-west-1-preprod
  • my-tf-test-bucket-us-East-1-prod

0

Một số phương pháp hay nhất về Terraform để làm theo:

  1. Tránh viết mã khó: Đôi khi các nhà phát triển tạo tài nguyên trực tiếp theo cách thủ công. Bạn cần đánh dấu tài nguyên này và sử dụng nhập địa hình để đưa chúng vào mã. Một ví dụ:

    account_number = “123456789012" account_alias = "mycompany"

  2. Chạy Terraform từ vùng chứa docker: Terraform phát hành vùng chứa Docker chính thức cho phép bạn dễ dàng kiểm soát phiên bản nào bạn có thể chạy.

Bạn nên chạy vùng chứa Terraform Docker khi bạn thiết lập công việc xây dựng của mình trong đường ống CI / CD.

TERRAFORM_IMAGE=hashicorp/terraform:0.11.7
TERRAFORM_CMD="docker run -ti --rm -w /app -v ${HOME}/.aws:/root/.aws -v ${HOME}/.ssh:/root/.ssh -v `pwd`:/app $TERRAFORM_IMAGE"

Để biết thêm, vui lòng tham khảo blog của tôi: https://medium.com/tech-darwinbox/how-darwinbox-manages-infraosystem-at-scale-with-terraform-371e2c5f04d3


0

Tôi muốn đóng góp cho chủ đề này.

  • Đây rất có thể sẽ là AWS S3 + DynamoDB trừ khi bạn đang sử dụng Terraform Cloud.
  • Cơ sở hạ tầng riêng biệt (mạng + RBAC) của sản xuất và phụ trợ không sản xuất.
  • Lập kế hoạch để vô hiệu hóa quyền truy cập vào các tệp trạng thái (truy cập mạng và RBAC) từ bên ngoài mạng được chỉ định (ví dụ: nhóm tác nhân triển khai).
  • Không giữ cơ sở hạ tầng phụ trợ Terraform với môi trường thời gian chạy. Sử dụng tài khoản riêng biệt.
  • Bật lập phiên bản đối tượng trên phụ trợ Terraform của bạn để tránh mất các thay đổi và tệp trạng thái, đồng thời để duy trì lịch sử trạng thái Terraform.

Trong một số trường hợp đặc biệt, sẽ yêu cầu quyền truy cập thủ công vào tệp trạng thái Terraform. Những việc như tái cấu trúc, phá vỡ các thay đổi hoặc sửa lỗi sẽ yêu cầu nhân viên vận hành chạy các hoạt động trạng thái Terraform. Đối với những trường hợp như vậy, hãy lập kế hoạch truy cập có kiểm soát bất thường vào trạng thái Terraform bằng máy chủ pháo đài, VPN, v.v.

Kiểm tra blog về các phương pháp hay nhất dài hơn bao gồm chi tiết về vấn đề này, bao gồm cả hướng dẫn về đường ống CI / CD.


-1

Nếu bạn vẫn đang tìm kiếm giải pháp tốt hơn, hãy xem không gian làm việc có thể thay thế việc duy trì cấu trúc thư mục môi trường khác nhau có thể có các biến cụ thể của không gian làm việc.

Như Yevgeniy Brikman đã đề cập , tốt hơn là nên có một cấu trúc mô-đun.


-1

Sử dụng đám mây địa hình để quản lý và lưu trạng thái, cùng với lời khuyên ở trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.