Praktik terbaik saat menggunakan Terraform [ditutup]


111

Saya sedang dalam proses menukar infrastruktur kami menjadi terraform. Apa praktik terbaik untuk benar-benar mengelola file dan status terraform? Saya menyadari itu infrastruktur sebagai kode, dan saya akan memasukkan file .tf saya ke git, tetapi apakah saya juga melakukan tfstate? Haruskah itu berada di suatu tempat seperti S3? Saya ingin akhirnya CI mengelola semua ini, tetapi itu jauh lebih panjang dan mengharuskan saya untuk mencari tahu bagian yang bergerak untuk file.

Saya benar-benar hanya ingin melihat bagaimana orang di luar sana benar-benar memanfaatkan jenis barang ini dalam produksi

Jawaban:


85

Saya juga dalam keadaan memigrasi infrastruktur AWS yang ada ke Terraform jadi saya akan berupaya untuk memperbarui jawabannya saat saya mengembangkan.

Saya sangat mengandalkan contoh resmi Terraform dan berbagai trial and error untuk menyempurnakan area yang saya tidak yakin.

.tfstate file

Konfigurasi Terraform dapat digunakan untuk menyediakan banyak kotak pada infrastruktur yang berbeda, yang masing-masing dapat memiliki status berbeda. Karena juga dapat dijalankan oleh banyak orang, status ini harus berada di lokasi terpusat (seperti S3) tetapi tidak git.

Ini dapat dikonfirmasi dengan melihat Terraform .gitignore.

Kontrol pengembang

Tujuan kami adalah untuk memberikan lebih banyak kontrol infrastruktur kepada pengembang sambil mempertahankan audit penuh (git log) dan kemampuan untuk memeriksa perubahan kewarasan (permintaan tarik). Dengan pemikiran tersebut, alur kerja infrastruktur baru yang saya tuju adalah:

  1. Fondasi dasar AMI umum yang mencakup modul yang dapat digunakan kembali misalnya boneka.
  2. Infrastruktur inti yang disediakan oleh DevOps menggunakan Terraform.
  3. Pengembang mengubah konfigurasi Terraform di Git sesuai kebutuhan (jumlah instance; VPC baru; penambahan wilayah / zona ketersediaan, dll.).
  4. Konfigurasi Git didorong dan permintaan penarikan dikirimkan untuk diperiksa kewarasannya oleh anggota regu DevOps.
  5. Jika disetujui, panggil webhook ke CI untuk membangun dan menerapkan (tidak yakin cara mempartisi beberapa lingkungan saat ini)

Edit 1 - Perbarui status saat ini

Sejak memulai jawaban ini saya telah menulis banyak kode TF dan merasa lebih nyaman dengan keadaan kita. Kami telah menemukan bug dan batasan di sepanjang jalan, tetapi saya menerima ini adalah karakteristik menggunakan perangkat lunak baru yang berubah dengan cepat.

Tata Letak

Kami memiliki infrastruktur AWS yang rumit dengan beberapa VPC, masing-masing dengan beberapa subnet. Kunci untuk mengelola ini dengan mudah adalah dengan mendefinisikan taksonomi fleksibel yang mencakup wilayah, lingkungan, layanan, dan pemilik yang dapat kita gunakan untuk mengatur kode infrastruktur kita (baik terraform maupun boneka).

Modul

Langkah selanjutnya adalah membuat repositori git tunggal untuk menyimpan modul terraform kami. Struktur direktori tingkat atas kami untuk modul terlihat seperti ini:

tree -L 1 .

Hasil:

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

Masing-masing menetapkan beberapa default yang waras tetapi memaparkannya sebagai variabel yang dapat ditimpa oleh "perekat" kami.

Lem

Kami memiliki repositori kedua dengan kami glueyang menggunakan modul yang disebutkan di atas. Ini diatur sesuai dengan dokumen taksonomi kami:

.
├── 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

Di dalam tingkat klien kami memiliki .tffile khusus akun AWS yang menyediakan sumber daya global (seperti peran IAM); berikutnya adalah level wilayah dengan kunci publik EC2 SSH; Akhirnya di lingkungan kita ( dev, stg, proddll) adalah setup VPC, misalnya penciptaan dan mengintip koneksi dll disimpan kami.

Catatan Samping: Seperti yang Anda lihat, saya bertentangan dengan saran saya sendiri di atas dengan tetap terraform.tfstatemenggunakan git. Ini adalah tindakan sementara sampai saya pindah ke S3 tetapi cocok untuk saya karena saat ini saya satu-satunya pengembang.

Langkah selanjutnya

Ini masih proses manual dan belum ada di Jenkins tetapi kami mem-porting infrastruktur yang agak besar dan rumit dan sejauh ini bagus. Seperti yang saya katakan, sedikit bug tetapi berjalan dengan baik!

Edit 2 - Perubahan

Sudah hampir setahun sejak saya menulis jawaban awal ini dan status Terraform dan saya sendiri telah berubah secara signifikan. Saya sekarang berada di posisi baru menggunakan Terraform untuk mengelola cluster Azure dan Terraform sekarang v0.10.7.

Negara

Orang-orang berulang kali mengatakan kepada saya bahwa negara bagian tidak boleh menggunakan Git - dan mereka benar. Kami menggunakan ini sebagai tindakan sementara dengan tim dua orang yang mengandalkan komunikasi dan disiplin pengembang. Dengan tim terdistribusi yang lebih besar, kami sekarang sepenuhnya memanfaatkan status jarak jauh di S3 dengan penguncian yang disediakan oleh DynamoDB. Idealnya ini akan dipindahkan ke konsul sekarang menjadi v1.0 untuk memotong penyedia lintas cloud.

Modul

Sebelumnya kami membuat dan menggunakan modul internal. Ini masih terjadi tetapi dengan munculnya dan pertumbuhan registri Terraform kami mencoba menggunakan ini setidaknya sebagai basis.

Struktur file

Posisi baru memiliki taksonomi yang jauh lebih sederhana dengan hanya dua lingkungan infx - devdan prod. Masing-masing memiliki variabel dan keluarannya sendiri, menggunakan kembali modul yang kami buat di atas. The remote_statepenyedia juga membantu dalam berbagi output dari sumber dibuat antara lingkungan. Skenario kami adalah subdomain dalam grup sumber daya Azure yang berbeda ke TLD yang dikelola secara global.

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

Perencanaan

Sekali lagi dengan tantangan ekstra dari tim terdistribusi, kami sekarang selalu menyimpan output dari terraform planperintah kami. Kami dapat memeriksa dan mengetahui apa yang akan dijalankan tanpa risiko beberapa perubahan antara panggung plandan apply(meskipun penguncian membantu dalam hal ini). Ingatlah untuk menghapus file rencana ini karena berpotensi berisi variabel "rahasia" teks biasa.

Secara keseluruhan kami sangat senang dengan Terraform dan terus belajar dan meningkatkan dengan fitur baru yang ditambahkan.


Apakah Anda beruntung / mengalami masalah sejak jawaban ini? Milik Anda tampaknya sangat mirip dengan apa yang ingin saya lakukan, tetapi Anda mungkin lebih jauh dari saya.
Marc Young

3
Saya penasaran mengapa menurut Anda file tfstate tidak boleh disimpan di git? Apakah karena keadaan lama tidak layak untuk diselamatkan, atau ada masalah lain?
Agbodike

3
@agbodike - Saat bekerja sebagai pengembang tunggal atau bagian dari tim yang sangat kecil, tfstate dapat disimpan di git selama dilakukan secara teratur dan didorong untuk menghindari konflik. Langkah saya selanjutnya adalah mengatur ini sesuai dengan dokumen status jarak jauh mereka di S3 (yang juga mengatakan: "hal ini membuat bekerja dengan Terraform dalam tim menjadi rumit karena sering menjadi sumber konflik penggabungan. Status jarak jauh membantu mengatasi masalah ini.") . Seperti kebanyakan hal, komunikasi tim yang baik dapat membantu meringankan sebagian besar / semua masalah terlepas dari taktik untuk menahan status :-)
Ewan

1
@ the0ther - Saya khawatir repositori utama saya adalah milik namun saat ini saya sedang mengerjakan yang pribadi yang akan saya sediakan untuk umum dalam waktu dekat.
Ewan

2
Ada keberuntungan di repo Git @Ewan? Saya ingin melihat apa yang Anda lakukan.
David

85

Kami banyak menggunakan Terraform dan penyiapan yang kami rekomendasikan adalah sebagai berikut:

Tata letak file

Kami sangat menyarankan untuk menyimpan kode Terraform untuk setiap lingkungan Anda (misalnya stage, prod, qa) dalam set template terpisah (dan karenanya, .tfstatefile terpisah ). Ini penting agar lingkungan Anda yang terpisah benar-benar terisolasi satu sama lain saat membuat perubahan. Jika tidak, saat mengotak-atik beberapa kode dalam pementasan, terlalu mudah untuk meledakkan sesuatu juga. Lihat Terraform, VPC, dan mengapa Anda menginginkan file tfstate per env untuk diskusi penuh warna tentang alasannya.

Oleh karena itu, tata letak file khas kami terlihat seperti ini:

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

Semua kode Terraform untuk VPC tahap masuk ke stagefolder, semua kode untuk VPC prod masuk ke prodfolder, dan semua kode yang berada di luar VPC (misalnya pengguna IAM, topik SNS, bucket S3) masuk ke globalfolder .

Perhatikan bahwa, berdasarkan kesepakatan, kami biasanya memecah kode Terraform kami menjadi 3 file:

  • vars.tf: Variabel masukan.
  • outputs.tf: Variabel keluaran.
  • main.tf: Sumber daya yang sebenarnya.

Modul

Biasanya, kami mendefinisikan infrastruktur kami dalam dua folder:

  1. infrastructure-modules: Folder ini berisi modul kecil, dapat digunakan kembali, berversi. Pikirkan setiap modul sebagai cetak biru tentang cara membuat satu bagian infrastruktur, seperti VPC atau database.
  2. infrastructure-live: Folder ini berisi infrastruktur yang sedang berjalan dan aktif, yang dibuat dengan menggabungkan modul di infrastructure-modules. Pikirkan kode di folder ini sebagai rumah sebenarnya yang Anda bangun dari cetak biru Anda.

Sebuah terraform modul hanya setiap set terraform template dalam folder. Sebagai contoh, kita mungkin memiliki folder bernama vpcdalam infrastructure-modulesmendefinisikan bahwa semua tabel rute, subnet, gateway, ACL, dll untuk VPC tunggal:

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

Kemudian kita dapat menggunakan modul itu dalam infrastructure-live/stagedan infrastructure-live/produntuk membuat VPC panggung dan prod. Misalnya, berikut infrastructure-live/stage/main.tftampilannya:

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"
}

Untuk menggunakan modul, Anda menggunakan modulesumber daya dan mengarahkan sourcebidangnya ke jalur lokal pada hard drive Anda (misalnya source = "../infrastructure-modules/vpc") atau, seperti dalam contoh di atas, URL Git (lihat sumber modul ). Keuntungan dari Git URL adalah kita dapat menentukan git sha1 atau tag ( ref=v0.0.4) tertentu. Sekarang, kami tidak hanya mendefinisikan infrastruktur kami sebagai sekumpulan modul kecil, tetapi kami dapat membuat versi modul tersebut dan memperbarui atau mengembalikannya secara hati-hati sesuai kebutuhan.

Kami telah membuat sejumlah Paket Infrastruktur yang dapat digunakan kembali, diuji, dan didokumentasikan untuk membuat VPC, kluster Docker, database, dan seterusnya, dan di balik terpal, kebanyakan dari mereka hanyalah modul Terraform berversi.

Negara

Saat Anda menggunakan Terraform untuk membuat sumber daya (misalnya instans EC2, database, VPC), Terraform mencatat informasi tentang apa yang dibuatnya dalam sebuah .tfstatefile. Untuk membuat perubahan pada sumber daya tersebut, setiap orang di tim Anda memerlukan akses ke .tfstatefile yang sama ini , tetapi Anda TIDAK harus memeriksanya ke Git (lihat di sini untuk penjelasan mengapa ).

Sebagai gantinya, kami merekomendasikan untuk menyimpan .tfstatefile di S3 dengan mengaktifkan Terraform Remote State , yang secara otomatis akan mendorong / menarik file terbaru setiap kali Anda menjalankan Terraform. Pastikan untuk mengaktifkan pembuatan versi di bucket S3 Anda sehingga Anda dapat memutar kembali ke .tfstatefile lama seandainya Anda merusak versi terbaru. Namun, catatan penting: Terraform tidak menyediakan penguncian . Jadi jika dua anggota tim berjalan terraform applypada waktu yang sama di .tfstatefile yang sama , mereka mungkin akan saling menimpa perubahan satu sama lain.

Untuk mengatasi masalah ini, kami membuat alat sumber terbuka yang disebut Terragrunt , yang merupakan pembungkus tipis untuk Terraform yang menggunakan Amazon DynamoDB untuk menyediakan penguncian (yang seharusnya gratis untuk sebagian besar tim). Lihat Tambahkan Penguncian dan Konfigurasi Status Jarak Jauh Otomatis ke Terraform dengan Terragrunt untuk info lebih lanjut.

Bacaan lebih lanjut

Kami baru saja memulai serangkaian posting blog yang disebut Panduan Komprehensif untuk Terraform yang menjelaskan secara detail semua praktik terbaik yang telah kami pelajari untuk menggunakan Terraform di dunia nyata.

Pembaruan: Seri posting blog Panduan Komprehensif Terraform menjadi begitu populer sehingga kami mengembangkannya menjadi sebuah buku berjudul Terraform: Up & Running !


Saya rasa ini adalah jawaban yang benar. Gunakan modul, buat versi, dan pisahkan lingkungan.
Wrangler

Apakah langkah konfigurasi jarak jauh perlu dijalankan ulang setiap kali Anda ingin bekerja pada komponen terraform yang berbeda / lingkungan / modul / apa pun jika tidak menggunakan terragrunt atau pembungkus lain?
jmreicha

@jmreicha: Anda perlu menjalankan remote configjika Anda baru saja memeriksa konfigurasi Terraform Anda atau jika Anda ingin mengubah konfigurasi jarak jauh sebelumnya. Terraform 0.9 akan memperkenalkan konsep backends, yang akan menyederhanakan banyak hal. Lihat PR ini untuk lebih jelasnya.
Yevgeniy Brikman

Supaya saya mengerti - saya sedang mengerjakan 'panggung' lingkungan tetapi kemudian mulai mengerjakan 'prod'. Saya perlu menjalankan kembali remote configperintah untuk menunjuk ke status prod. Dengan asumsi keadaan berbeda per lingkungan. Apakah itu benar? Saya berharap untuk v0.9.
jmreicha

Jika Anda akan menerapkan kumpulan .tffile yang sama persis ke dua lingkungan yang berbeda, ya, Anda harus menjalankannya remote configsetiap kali Anda beralih. Ini jelas sangat rawan kesalahan, jadi saya tidak merekomendasikan benar-benar menggunakan teknik ini. Sebagai gantinya, lihat tata letak file Terraform yang direkomendasikan di postingan blog ini bersama dengan cara menggunakan modul Terraform di postingan blog ini .
Yevgeniy Brikman

9

Sebelumnya remote configdiperbolehkan ini tetapi sekarang telah diganti dengan " backends ", jadi terraform remote tidak lagi tersedia.

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

Lihat dokumen untuk detailnya.


Apakah sumber jarak jauh perlu dikonfigurasi ulang setiap kali Anda ingin bekerja pada komponen terraform yang berbeda / environment / module / apa saja?
jmicha

6

Dicakup lebih dalam oleh @Yevgeny Brikman tetapi secara khusus menjawab pertanyaan OP:

Apa praktik terbaik untuk benar-benar mengelola file dan status terraform?

Gunakan git untuk file TF. Tapi jangan centang file Status di (yaitu tfstate). Sebagai gantinya gunakan Terragruntuntuk sinkronisasi / penguncian file status ke S3.

tetapi apakah saya juga melakukan tfstate?

Tidak.

Haruskah itu berada di suatu tempat seperti S3?

Iya


2

Saya tahu ada banyak jawaban di sini tetapi pendekatan saya sangat berbeda.

   Modules
   Environment management 
   Separation of duties

Modul

  1. Buat modul untuk kumpulan sumber daya yang logis. Contoh: Jika tujuan Anda adalah menerapkan API, yang memerlukan DB, VM HA, penskalaan otomatis, DNS, PubSub, dan penyimpanan objek, maka semua sumber daya ini harus diberi template dalam satu modul.
  2. Hindari membuat modul yang menggunakan satu sumber daya. Ini dapat dan telah dilakukan dan banyak modul di registri melakukan ini, tetapi ini adalah praktik yang membantu aksesibilitas sumber daya daripada orkestrasi infrastruktur. Contoh: Modul untuk AWS EC2 membantu pengguna mengakses EC2 dengan membuat konfigurasi kompleks menjadi lebih mudah untuk dijalankan, tetapi modul seperti contoh di 1. membantu pengguna saat mengatur infrastruktur yang digerakkan oleh aplikasi, komponen, atau layanan.
    1. Hindari deklarasi sumber daya di ruang kerja Anda. Ini lebih tentang menjaga kode Anda tetap rapi dan teratur. Karena modul mudah diversi, Anda memiliki kontrol lebih besar atas rilis Anda.

Pengelolaan lingkungan

IaC telah membuat proses SDLC relevan dengan manajemen infrastruktur dan tidak normal mengharapkan infrastruktur pengembangan serta lingkungan aplikasi pengembangan.

  1. Jangan gunakan folder untuk mengelola lingkungan IaC Anda. Ini mengarah ke drift karena tidak ada template umum untuk infrastruktur Anda.
  2. Gunakan satu ruang kerja dan variabel untuk mengontrol spesifikasi lingkungan. Contoh: Tulis modul Anda sehingga ketika Anda mengubah variabel lingkungan (var.stage populer) rencana berubah agar sesuai dengan kebutuhan Anda. Biasanya lingkungan harus bervariasi sesedikit mungkin dengan kuantitas, eksposur dan kapasitas biasanya menjadi konfigurasi variabel. Pengembang mungkin menerapkan 1 VM dengan 1 inti dan 1GB RAM dalam topologi pribadi tetapi produksi mungkin 3 VM dengan 2 inti dan 4GB RAM dengan topologi publik tambahan. Anda tentu saja dapat memiliki lebih banyak variasi: dev dapat menjalankan proses database di server yang sama dengan aplikasi untuk menghemat biaya tetapi produksi mungkin memiliki instans DB khusus. Semua ini dapat dikelola dengan mengubah variabel tunggal, pernyataan terner, dan interpolasi.

Pemisahan tugas

Jika Anda berada dalam organisasi kecil atau menjalankan infrastruktur pribadi, ini tidak benar-benar berlaku tetapi akan membantu Anda mengelola operasi Anda.

  1. Hancurkan infrastruktur Anda berdasarkan tugas, tanggung jawab, atau tim. Contoh: Pusat kendali TI yang mendasari layanan bersama (jaringan virtual, subnet, alamat IP publik, grup log, sumber daya tata kelola, DB multi tenant, kunci bersama, dll.) Sementara tim API hanya mengontrol sumber daya yang diperlukan untuk layanan mereka (VM, LB , PubSub, dll.) Dan menggunakan layanan IT Pusat melalui sumber data dan pencarian status jarak jauh.
    1. Atur akses tim. Contoh: TI Pusat mungkin memiliki hak admin tetapi tim API hanya memiliki akses ke kumpulan API cloud publik yang dibatasi.

Ini juga membantu dengan masalah rilis karena Anda akan menemukan beberapa sumber daya jarang berubah sementara yang lain berubah sepanjang waktu. Pemisahan menghilangkan risiko dan kompleksitas.

Strategi ini paralel dengan strategi multi akun AWS. Baca untuk info lebih lanjut.

CI / CD

Ini adalah topik tersendiri tetapi Terraform bekerja dengan sangat baik dalam pipeline yang baik. Kesalahan paling umum di sini adalah memperlakukan CI sebagai peluru perak. Secara teknis Terraform seharusnya hanya menyediakan infrastruktur selama tahapan pipeline perakitan. Ini akan terpisah dari apa yang terjadi dalam tahapan CI di mana seseorang biasanya memvalidasi dan menguji template.

NB Ditulis di ponsel jadi mohon maaf jika ada kesalahan.


0

Sebelum jawaban menjadi sangat solid dan informatif, saya akan mencoba menambahkan 2 sen saya di sini

Rekomendasi umum untuk menyusun kode

  1. Lebih mudah dan lebih cepat untuk bekerja dengan sumber daya yang lebih sedikit:

    • Cmds terraform plandan terraformterapkan keduanya melakukan panggilan API cloud untuk memverifikasi status sumber daya.
    • Jika Anda memiliki seluruh infrastruktur dalam satu komposisi, ini dapat memakan waktu beberapa menit (meskipun Anda memiliki beberapa file dalam folder yang sama).
  2. Radius ledakan lebih kecil dengan sumber daya yang lebih sedikit:

    • Mengisolasi sumber daya yang tidak terkait satu sama lain dengan menempatkannya dalam komposisi (folder) terpisah mengurangi risiko jika terjadi kesalahan.
  3. Mulai proyek Anda menggunakan status jarak jauh:

  4. Cobalah untuk mempraktikkan struktur yang konsisten dan konvensi penamaan:

    • Seperti kode prosedural, kode Terraform harus ditulis agar orang bisa membaca terlebih dahulu, konsistensi akan membantu ketika perubahan terjadi enam bulan dari sekarang.
    • Dimungkinkan untuk memindahkan sumber daya dalam file status Terraform tetapi mungkin lebih sulit dilakukan jika Anda memiliki struktur dan penamaan yang tidak konsisten.
  5. Jaga modul sumber daya sejelas mungkin.

  6. Jangan nilai hard-code yang dapat diteruskan sebagai variabel atau ditemukan menggunakan sumber data.

  7. Gunakan datasumber dan terraform_remote_statesecara khusus sebagai perekat antara modul infrastruktur dalam komposisi.

( artikel ref: https://www.terraform-best-practices.com/code-structure )


Contoh:

Lebih mudah dan lebih cepat untuk bekerja dengan jumlah sumber daya yang lebih kecil jadi di bawah ini kami menyajikan tata letak kode yang disarankan.

CATATAN: hanya sebagai referensi untuk tidak diikuti secara ketat karena setiap proyek memiliki karakteristik spesifiknya sendiri

.
├── 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

Saya yakin ada beberapa praktik terbaik yang perlu diikuti saat menggunakan terraform untuk mengatur infrastruktur

  1. Jangan menulis kode yang sama lagi (Dapat digunakan kembali)
  2. Pisahkan konfigurasi lingkungan untuk menjaganya dengan mudah.
  3. Gunakan backend s3 jarak jauh (terenkripsi) dan dynamo DB untuk menangani penguncian konkurensi
  4. Buat modul dan gunakan modul itu dalam infrastruktur utama beberapa kali, ini seperti fungsi yang dapat digunakan kembali yang dapat dipanggil beberapa kali dengan melewatkan parameter yang berbeda.

Tangani banyak lingkungan

Sebagian besar waktu yang disarankan adalah menggunakan 'ruang kerja' terraform untuk menangani berbagai lingkungan, tetapi saya yakin penggunaan ruang kerja dapat bervariasi berdasarkan cara kerja dalam suatu organisasi. Yang lainnya adalah menyimpan kode Terraform untuk setiap lingkungan Anda (misalnya stage, prod, QA) untuk memisahkan status lingkungan. Namun, dalam kasus ini kami hanya menyalin kode yang sama di banyak tempat.

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

Saya mengikuti beberapa pendekatan berbeda untuk menangani dan menghindari duplikasi kode terraform yang sama dengan menyimpannya di setiap folder lingkungan karena saya percaya sebagian besar waktu semua lingkungan akan 90% sama.

├── 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

Konfigurasi yang terkait dengan lingkungan

Pisahkan konfigurasi dan parameter terkait lingkungan dalam file variabel dan teruskan nilai tersebut untuk mengonfigurasi infrastruktur. misal seperti dibawah ini

  • 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"

Melewati bagian infrastruktur bersyarat

Buat konfigurasi di file variabel spesifik env dan berdasarkan variabel tersebut putuskan untuk membuat atau melewatkan bagian itu. Dengan cara ini berdasarkan kebutuhan, bagian tertentu dari infrastruktur dapat dilewati.

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"
}

perintah di bawah ini diperlukan untuk menginisialisasi dan menjalankan infra perubahan untuk setiap lingkungan, cd ke folder lingkungan yang diperlukan.

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

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

Untuk referensi: https://github.com/mattyait/devops_terraform


0

Saya tidak suka ide subfolder karena ini akan menghasilkan sumber yang berbeda per lingkungan dan ini cenderung melayang.

Pendekatan yang lebih baik adalah memiliki satu tumpukan untuk semua lingkungan (katakanlah dev, preprod dan prod). Untuk bekerja pada penggunaan lingkungan tunggal terraform workspace.

terraform workspace new dev

Ini menciptakan ruang kerja baru. Ini termasuk file status khusus dan variabel terraform.workspaceyang dapat Anda gunakan dalam kode Anda.

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

Dengan cara ini Anda akan mendapatkan panggilan ember

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

setelah menerapkan ke ruang kerja di atas (gunakan terraform workspace select <WORKSPACE>untuk mengubah lingkungan). Untuk membuat kode tersebut bahkan multi-region-proof, lakukan seperti ini:

data "aws_region" "current" {}

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

untuk mendapatkan (untuk wilayah us-east-1)

  • my-tf-test-bucket-us-east-1-dev
  • my-tf-test-bucket-us-east-1-preprod
  • my-tf-test-bucket-us-east-1-prod

0

Beberapa Praktik Terbaik Terraform untuk Diikuti:

  1. Hindari pengkodean keras: Terkadang pengembang membuat sumber daya secara manual secara langsung. Anda perlu menandai sumber daya ini dan menggunakan impor terraform untuk memasukkannya ke dalam kode. Sebuah sampel:

    account_number = “123456789012" account_alias = "perusahaan saya"

  2. Jalankan Terraform dari container docker: Terraform merilis container Docker resmi yang memungkinkan Anda mengontrol dengan mudah versi mana yang dapat Anda jalankan.

Direkomendasikan untuk menjalankan container Terraform Docker saat Anda menyetel pekerjaan build Anda di pipeline 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"

Untuk lebih lanjut, silakan merujuk ke blog saya: https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3


0

Saya ingin berkontribusi pada utas ini.

  • Kemungkinan besar ini adalah AWS S3 + DynamoDB kecuali Anda menggunakan Terraform Cloud.
  • Infrastruktur terpisah (jaringan + RBAC) dari backend produksi dan non-prod.
  • Rencanakan untuk menonaktifkan akses ke file status (akses jaringan dan RBAC) dari luar jaringan yang ditentukan (misalnya kumpulan agen penyebaran).
  • Jangan simpan infrastruktur backend Terraform dengan lingkungan run-time. Gunakan akun terpisah.
  • Aktifkan pembuatan versi objek di backend Terraform Anda untuk menghindari kehilangan perubahan dan file status, dan untuk mempertahankan riwayat status Terraform.

Dalam beberapa kasus khusus, akses manual ke file status Terraform akan diperlukan. Hal-hal seperti pemfaktoran ulang, pemutusan perubahan, atau perbaikan kerusakan akan memerlukan pengoperasian status Terraform oleh personel operasi. Untuk kesempatan seperti itu, rencanakan akses terkontrol yang luar biasa ke status Terraform menggunakan bastion host, VPN, dll.

Lihat blog praktik terbaik yang lebih panjang yang membahasnya secara detail termasuk pedoman untuk pipeline CI / CD.


-1

Jika Anda masih mencari solusi yang lebih baik, lihat ruang kerja yang dapat menggantikan mempertahankan struktur folder lingkungan yang berbeda dapat memiliki variabel khusus ruang kerja.

Seperti yang disebutkan Yevgeniy Brikman , lebih baik memiliki struktur modul.


-1

Gunakan cloud terraform untuk mengelola dan menyimpan status, bersama dengan saran di atas.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.