
كان لدينا 4 حسابات أمازون ، و 9 من منتجات VPC ، و 30 من بيئات التطوير الأكثر قوة ، والمراحل ، والانحدارات - في المجموع أكثر من 1000 نموذج EC2 من جميع الألوان والظلال. منذ أن بدأت في جمع الحلول السحابية للأعمال ، أحتاج إلى الذهاب في هوايتي إلى النهاية والتفكير في كيفية أتمتة كل هذا.
تحية! اسمي كيريل كازارين ، أعمل مهندسًا في DINS. نحن نعمل على تطوير حلول الاتصالات التجارية القائمة على السحابة. في عملنا ، نستخدم بنشاط Terraform ، التي ندير بها بنيتنا الأساسية بمرونة. سوف أشارك تجربتي مع هذا الحل.
المقال طويل ، لذا قم
بتخزين شاي
الفشار واذهب!
وهناك فارق بسيط آخر - تمت كتابة المقالة على أساس الإصدار 0.11 ، في 0.12 جديدة تم تغيير الكثير ولكن الممارسات والنصائح الرئيسية لا تزال ذات صلة. مسألة الهجرة من 0.11 إلى 0.12 تستحق مقالة منفصلة!
ما هو Terraform
Terraform هي أداة Hashicorp شائعة ظهرت في 2014.
تتيح لك هذه الأداة المساعدة إدارة البنية التحتية السحابية الخاصة بك في
البنية التحتية كنموذج
رمز بلغة تعريفية ودية للغاية وسهلة القراءة. يوفر لك تطبيقه نوعًا موحدًا من الموارد وتطبيق ممارسات التعليمات البرمجية لإدارة البنية التحتية ، والتي تم تطويرها منذ فترة طويلة بواسطة مجتمع المطورين. يدعم Terraform جميع المنصات السحابية الحديثة ، ويسمح لك بتغيير البنية الأساسية بأمان وبشكل متوقع.
عند بدء التشغيل ، يقرأ Terraform الكود ، وبإضافة المكونات الإضافية التي يوفرها مزودو الخدمات السحابية ، ينقل البنية الأساسية الخاصة بك إلى الحالة الموصوفة عن طريق إجراء مكالمات API الضرورية.
يقع مشروعنا بالكامل في منطقة الأمازون ، ويتم نشره على أساس خدمات AWS ، وبالتالي أكتب عن استخدام Terraform في هذا السياق. بشكل منفصل ، ألاحظ أنه يمكن استخدامه ليس فقط للأمازون. انها تسمح لك لإدارة كل ما لديه API.
بالإضافة إلى ذلك ، فإننا ندير إعدادات VPC وسياسات IAM والأدوار. ندير جداول التوجيه والشهادات و ACLs الشبكة. نحن ندير إعدادات جدار الحماية الخاص بتطبيق الويب لدينا ، S3-bucket ، SQS- قوائم الانتظار - كل ما يمكن أن تستخدمه خدمتنا في Amazon. لم أر حتى الآن ميزات مع Amazon لا يمكن لـ Terraform وصفها من حيث البنية التحتية.
إنه يتحول إلى بنية تحتية كبيرة إلى حد ما ، مع دعم يديك بسهولة. ولكن مع Terraform أنها مريحة وبسيطة.
ما Terraform مصنوع من
الموفرون هم مكونات إضافية للعمل مع واجهة برمجة التطبيقات الخاصة بالخدمة. أنا أحسبهم
أكثر من 100 . من بينها مزودي خدمات Amazon و Google و DigitalOcean و VMware Vsphere و Docker. لقد وجدت مزودًا في هذه القائمة الرسمية التي تسمح لك
بإدارة قواعد Cisco ASA !
من بين أشياء أخرى ، يمكنك التحكم في:
وهؤلاء هم مقدمو الخدمات الرسميون فقط ، بل يوجد عدد غير رسمي من مقدمي الخدمات. خلال التجارب ، صادفت على GitHub جهة خارجية ، غير مدرجة في مزود القائمة الرسمي ، والذي
سمح بالعمل مع DNS من GoDaddy ، وكذلك مع
موارد Proxmox .
ضمن مشروع Terraform واحد ، يمكنك استخدام مزودين مختلفين ، وبالتالي ، موارد مزودي الخدمة أو التقنيات المختلفة. على سبيل المثال ، يمكنك إدارة البنية التحتية الخاصة بك في AWS ، مع DNS خارجي من GoDaddy. وغداً ، اشترت شركتك شركة ناشئة استضافت في DO أو Azure. وبينما تقرر ترحيل هذا إلى AWS أم لا ، يمكنك أيضًا دعم هذا باستخدام نفس الأداة!
الموارد. هذه هي الكيانات السحابية التي يمكنك إنشاؤها باستخدام Terraform. تعتمد قائمتهم وصياغتهم وخصائصهم على المزود المستخدم ، في الواقع - على السحابة المستخدمة. أو ليس فقط السحب.
وحدات. هذه هي الكيانات التي تسمح لك Terraform بنموذج التكوين الخاص بك. وبالتالي ، تتيح لك القوالب جعل كودك أصغر ، وتتيح لك إعادة استخدامه. حسنًا ، إنهم يساعدون على العمل معه بشكل مريح.
لماذا اخترنا Terraform
لأنفسنا ، حددنا 5 أسباب رئيسية. ربما من وجهة نظرك ، لن يبدو كل منهم مهمًا:
- Terraform هي أداة دعم سحابة متعددة تدعم
Agnostic (شكرًا على التعليق الثمين في التعليقات) . عندما اخترنا هذه الأداة ، فكرنا في: - ماذا سيحدث إذا أتت الإدارة إلينا غدًا أو خلال أسبوع وتقول: " الرجال ، وفكرنا - دعونا لا ننشر فقط في Amazon. لدينا نوع من المشاريع ، حيث سنحتاج إلى الحصول على البنية التحتية في Google Cloud. أو في Azure - حسنًا ، أنت لا تعرف أبدًا ". قررنا أننا نرغب في الحصول على أداة لن يتم ربطها بشكل صارم بأي خدمة سحابية. - المصدر المفتوح . Terraform هو حل مفتوح المصدر . يحتوي مستودع المشروع على تصنيف أكثر من 16 ألف نجم ، وهذا تأكيد جيد لسمعة المشروع.
لقد صادفنا أكثر من مرة أو مرتين حقيقة أنه في بعض الإصدارات يوجد أخطاء أو لا يوجد سلوك مفهوم تمامًا. يتيح لك وجود مستودع مفتوح التأكد من أن هذا خطأ بالفعل ، ويمكننا حل المشكلة ببساطة عن طريق تحديث المحرك أو إصدار المكون الإضافي. أو أن هذا خطأ ، ولكن "يا شباب ، انتظر ، بعد يومين حرفيًا ، سيتم إصدار نسخة جديدة وسنصلحها". أو: "نعم ، هذا شيء غير مفهوم ، غريب ، يفرزونه ، لكن هناك حل بديل." انها مريحة جدا. - السيطرة . Terraform كأداة هي تماما تحت سيطرتك. يمكن تثبيته على جهاز كمبيوتر محمول ، على خادم ، ويمكن دمجه بسهولة في خط الأنابيب الخاص بك ، والذي يمكن القيام به على أساس أي أداة. على سبيل المثال ، نستخدمها في GitLab CI.
- التحقق من حالة البنية التحتية . يمكن لـ Terraform إجراء فحص جيد لحالة البنية الأساسية لديك.
افترض أنك بدأت استخدام Terraform في فريقك. يمكنك إنشاء وصف لبعض الموارد في Amazon ، على سبيل المثال ، Security Group ، قم بتطبيقه - تم إنشاؤه لك ، كل شيء على ما يرام. وهنا - بام! زميلك ، الذي عاد من إجازة أمس ولم يدرك بعد أنك رتبت كل شيء بشكل جميل هنا ، أو حتى زميل من قسم آخر يأتي ويغير إعدادات مجموعة الأمان هذه يدويًا.
وبدون مقابلته ، دون التحدث ، أو دون افتراض مشكلة معينة لاحقًا ، لن تعرف أبدًا هذا الأمر في وضع طبيعي. ولكن ، إذا كنت تستخدم Terraform ، فإن تشغيل خمول الخطة على هذا المورد سيوضح لك أن هناك تغييرات في بيئة العمل.
عندما ينظر Terraform إلى شفرتك ، فإنه يستدعي في وقت واحد واجهة برمجة تطبيقات موفر السحابة ، ويستقبل حالة الكائنات منه ويقارن: "والآن هناك نفس الشيء الذي فعلته من قبل ، ماذا أتذكر؟" ثم يقارنها بالكود ، ويبحث في الأشياء الأخرى التي يجب تغييرها. على سبيل المثال ، إذا كان كل شيء هو نفسه في قصته ، وفي ذاكرته ، وفي شفرتك ، ولكن هناك تغييرات هناك ، فسوف يعرض عليك ويعرضها للتراجع. في رأيي ، أيضا خاصية جيدة جدا. وبالتالي ، هذه خطوة أخرى ، بالنسبة لنا شخصيًا ، لضمان وجود بنية تحتية ثابتة. - ميزة أخرى مهمة للغاية هي الوحدات التي ذكرتها ، والتهم. سأتحدث عن هذا بعد قليل. عندما سأقارن مع الأدوات.
وأيضا كرز على الكعكة: يحتوي Terraform على
قائمة كبيرة إلى حد ما من الوظائف المدمجة . هذه الوظائف ، على الرغم من اللغة التصريحية ، تسمح لنا بتنفيذ بعض ، وليس ليقول البرنامجية ، ولكن المنطق.
على سبيل المثال ، تقوم بعض العمليات الحسابية التلقائية ، وخطوط الانقسام ، والصرف بالحالة السفلية والعلوية ، وإزالة الحروف من هذا السطر. نحن نستخدمها بنشاط. إنها تجعل الحياة أسهل كثيرًا ، خاصةً عند كتابة وحدة سيتم إعادة استخدامها لاحقًا في بيئات مختلفة.
Terraform مقابل CloudFormation
تقارن الشبكة غالبًا Terraform بـ CloudFormation. سألنا هذا السؤال أيضًا عند اختياره. وهنا نتيجة المقارنة.
كيف تبدأ مع Terraform
بشكل عام ، البدء بسيط للغاية. فيما يلي الخطوات الأولى لفترة وجيزة:
- بادئ ذي بدء ، قم بإنشاء مستودع Git وابدأ على الفور في تخزين كل التغييرات والتجارب وكل شيء.
- اقرأ دليل البدء . إنها صغيرة وبسيطة ومفصلة إلى حد ما وتصف جيدًا كيفية البدء في استخدام هذه الأداة.
- اكتب بعض التجريبي ، رمز العمل. يمكنك حتى نسخ بعض الأمثلة لتلعب معها لاحقًا.
ممارستنا مع Terraform
شفرة المصدر
لقد بدأت مشروعك الأول وحفظت كل شيء في ملف main.tf كبير واحد.
هنا مثال نموذجي (أخذت بأمانة أول
مثال حصلت عليه من جيثب).
لا بأس ، لكن حجم قاعدة الكود يميل إلى النمو بمرور الوقت. التبعيات بين الموارد تنمو أيضا. بعد مرور بعض الوقت ، يصبح الملف ضخمًا ومعقدًا وغير قابل للقراءة ولا تتم صيانته بشكل سيئ - ويمكن أن يؤدي أي تغيير مهمل في مكان واحد إلى حدوث مشكلات.
أول شيء أوصي به هو تسليط الضوء على ما يسمى مستودع التخزين الأساسي ، أو الحالة الأساسية لمشروعك ، بيئتك. بمجرد البدء في إنشاء بنية أساسية باستخدام Terraform ، أو استيرادها ، ستصادف على الفور أن لديك بعض الكيانات ، بمجرد نشرها ، تكوينها ، نادرًا ما تتغير. على سبيل المثال ، هذه هي إعدادات VPC ، أو VPC نفسها. هذه هي الشبكات ، مجموعات الأمان الأساسية العامة مثل SSH-access - يمكنك تجميع قائمة كبيرة إلى حد ما.
ليس من المنطقي الاحتفاظ بهذا في نفس مستودع التخزين مثل الخدمات التي تقوم بتغييرها بشكل متكرر. حددها في مستودع منفصل وقم بتثبيتها من خلال ميزة Terraform مثل الحالة البعيدة.
- إنك تقلل من قاعدة الكود الخاصة بهذا الجزء من المشروع الذي تعمل معه غالبًا بشكل مباشر.
- بدلاً من ملف tfstate كبير واحد يحتوي على وصف لحالة البنية التحتية الخاصة بك ، ملفين أصغر ، وفي وقت معين كنت تعمل مع واحد منهم.
ما هي الحيلة؟ عندما يقوم Terraform بوضع خطة ، أي ، يقوم بحساب وحساب ما يجب تغييره ، وتطبيقه - يقوم بحساب هذه الحالة بالكامل ، والتحقق من الكود ، والتحقق من الحالة في AWS. كلما زادت ولايتك ، ستستغرق الخطة فترة أطول.
لقد توصلنا إلى هذه الممارسة عندما استغرقنا 20 دقيقة لوضع خطة للبيئة بأكملها في الإنتاج. نظرًا لحقيقة أننا نجحنا في كل شيء أساسي منفصل أننا لسنا عرضة للتغييرات المتكررة ، قللنا من الوقت لبناء خطة بمقدار النصف. لدينا فكرة عن كيفية تقليصه أكثر ، ليس فقط إلى قلب وغير أساسي ، ولكن أيضًا من خلال النظم الفرعية ، لأننا نربطهم ونتغير عادةً معًا. لذلك ، نقول ، سننتقل من 10 دقائق إلى 3 دقائق. لكننا ما زلنا بصدد تنفيذ مثل هذا الحل.
رمز أقل - أسهل في القراءة
رمز صغير هو أسهل للفهم وأكثر ملاءمة للعمل مع. إذا كان لديك فريق كبير وهناك أشخاص لديهم مستويات مختلفة من الخبرة في ذلك - فاستخرج ما نادراً ما تغيره ، ولكن على مستوى عالمي ، في لف منفصل ، وقم بإتاحة وصول أضيق له.
دعنا نفترض أن لديك صغارًا في فريقك ولا تمنحهم حق الوصول إلى المستودع العام الذي يصف إعدادات VPC - وبهذه الطريقة يمكنك تأمين نفسك ضد الأخطاء. إذا أخطأ مهندس في كتابة المثال ، وحدث خطأ ما - فهذا ليس مخيفًا. وإذا ارتكب خطأً في الخيارات المثبتة على جميع الأجهزة ، فواصل ، أو قام بشيء ما مع إعدادات الشبكات الفرعية ، مع التوجيه - هذا أكثر إيلامًا.
يتم اختيار مستودع التخزين الأساسي بعدة خطوات.
المرحلة 1 . إنشاء مستودع منفصل. قم بتخزين جميع الشفرات فيه ، بشكل منفصل - ووصف الكيانات التي يجب إعادة استخدامها في مستودع تابع لجهة خارجية باستخدام هذا الإخراج. لنفترض أننا ننشئ موردًا لشبكة AWS نصف فيه موقعه ، ومنطقة التوافر ، ومساحة العنوان.
resource "aws_subnet" "lab_pub1a" { vpc_id = "${aws_vpc.lab.id}" cidr_block = "10.10.10.0/24" Availability_zone = "us-east-1a" ... } output "sn_lab_pub1a-id" { value = "${aws_subnet.lab_pub1a.id}" }
ثم نقول أننا نرسل معرف هذا الكائن إلى الإخراج. يمكنك القيام بالإخراج لكل معلمة تحتاجها.
ما هي الحيلة هنا؟ عندما تصف قيمة ، يحفظ Terraform بشكل منفصل في قلب tfstate. وعندما تلجأ إليه ، لن يحتاج إلى المزامنة وإعادة فرز الأصوات - فسيكون قادرًا على تقديم هذا الأمر لك على الفور من هذه الحالة. علاوة على ذلك ، في المستودع ، غير الأساسي ، يمكنك وصف مثل هذا الاتصال بالحالة البعيدة: لديك حالة بعيدة كذا وكذا ، وتقع في دلو S3 كذا وكذا ، كذا وكذا وكذا المنطقة ومنطقة.
المرحلة 2 . في مشروع غير أساسي ، نقوم بإنشاء ارتباط لحالة المشروع الأساسي ، حتى نتمكن من الرجوع إلى المعلمات المصدرة من خلال الإخراج.
data "terraform_remote_state" "lab_core" { backend = "s3" config { bucket = "lab-core-terraform-state" key = "terraform.tfstate" region = "us-east-1" } }
المرحلة 3 . البدء! عندما أحتاج إلى نشر واجهة شبكة جديدة لمثيل في شبكة فرعية محددة ، أقول: ها هي حالة البيانات البعيدة ، ابحث عن اسم هذه الحالة فيها ، ابحث عن هذه المعلمة ، والتي ، في الواقع ، تتزامن مع هذا الاسم.
resource "aws_network_interface" "fwl01" { ... subnet_id = "${data.terraform_remote_state.lab_core.sn_lab_pub1a-id}" }
وعندما أقوم بإنشاء خطة تغييرات في مستودع التخزين غير الأساسي ، ستصبح هذه القيمة لـ Terraform ثابتة لها. إذا كنت ترغب في تغييرها ، فعليك القيام بذلك في مستودع هذا ، بالطبع ، الأساسية. لكن بما أن هذا نادرًا ما يتغير ، فهو لا يزعجك كثيرًا.
وحدات
اسمحوا لي أن أذكرك أن الوحدة النمطية هي تكوين قائم بذاته يتكون من واحد أو أكثر من الموارد ذات الصلة. تتم إدارته كمجموعة:
الوحدة النمطية هي شيء مريح للغاية نظرًا لحقيقة أنك نادراً ما تنشئ موردًا واحدًا تمامًا مثل ذلك ، في فراغ ، عادة ما يكون مرتبطًا منطقيًا بشيء ما.
module "AAA" { source = "..." count = "3" count_offset = "0" host_name_prefix = "XXX-YYY-AAA" ami_id = "${data.terraform_remote_state.lab_core.ami-base-ami_XXXX-id}" subnet_ids = ["${data.terraform_remote_state.lab_core.sn_lab_pub1a-id}", "${data.terraform_remote_state.lab_core.sn_lab_pub1b-id}"] instance_type = "t2.large" sgs_ids = [ "${data.terraform_remote_state.lab_core.sg_ssh_lab-id}", "${aws_security_group.XXX_lab.id}" ] boot_device = {volume_size = "50" volume_type = "gp2"} root_device = {device_name = "/dev/sdb" volume_size = "50" volume_type = "gp2" encrypted = "true"} tags = "${var.gas_tags}" }
على سبيل المثال: عندما ننشر مثيل EC2 جديدًا ، فإننا نصنع واجهة شبكة ومرفقًا لها ، وغالبًا ما نصنع عنوان IP مرنًا له ، ونعمل على تسجيل route-53 ، وشيء آخر. وهذا هو ، نحصل على 4 كيانات على الأقل.
في كل مرة ، وصفها في أربعة أجزاء من التعليمات البرمجية غير مريح. وعلاوة على ذلك ، فهي نموذجية جدا. يطرح - إنشاء قالب ، ثم فقط الرجوع إلى هذا القالب ، وتمرير المعلمات إليه: اسم ما ، في أي شبكة ليشق ، أي مجموعة أمان لتعلق عليه. انها مريحة جدا.
يحتوي Terraform على ميزة Count ، والتي تسمح لك بتقليل حالتك. يمكنك وصف حزمة كبيرة من الحالات مع رمز واحد. لنفترض أنني بحاجة إلى نشر 20 جهازًا من نفس النوع. لن أكتب 20 جزءًا من الشفرة حتى من القالب ، سأكتب جزءًا واحدًا من الكود ، وسأشير إلى العدد والرقم الموجود فيه - كم أحتاج إلى القيام به.
على سبيل المثال ، هناك بعض الوحدات التي تشير إلى قالب. أمرر معلمات محددة فقط: معرف الشبكة الفرعية. AMI للنشر مع ؛ نوع المثال ؛ إعدادات مجموعة الأمان ؛ أي شيء آخر ، وضح عدد هذه الأشياء التي يجب علي القيام بها. عظيم ، أخذهم وحولهم!
غدا يأتي إليّ المطورين ويقولون: "اسمع ، نريد أن نجرب العبء ، من فضلك أعطنا اثنين آخرين." ما أحتاج إلى فعله: أقوم بتغيير رقم واحد إلى 5. لا يزال مقدار الشفرة كما هو.
تقليديا ، يمكن تقسيم الوحدات إلى نوعين - الموارد والبنية التحتية. من وجهة نظر الكود ، لا يوجد فرق ، بل مفاهيم المستوى الأعلى التي يقدمها المشغل نفسه.
توفر وحدات الموارد مجموعة موحدة ومعلمة ذات صلة منطقية بالموارد. المثال أعلاه هو وحدة موارد نموذجية. كيفية العمل معهم:
- نشير إلى المسار إلى الوحدة النمطية - مصدر التكوين الخاص بها ، من خلال توجيه المصدر.
- نشير إلى الإصدار - نعم ، والتشغيل على مبدأ "الأحدث والأكبر" ليس الخيار الأفضل هنا. ألا تقوم بتضمين أحدث إصدار من المكتبة في كل مرة في مشروعك؟ ولكن أكثر على ذلك في وقت لاحق.
- نمرر الحجج لذلك.
نحن مرتبطون بإصدار الوحدة النمطية ، ونحن فقط نأخذ آخر واحد - يجب أن تكون البنية التحتية إصدارها (لا يمكن إصدار الموارد ، ولكن يمكن أن رمز). يمكن إنشاء مورد تم حذفه أو إعادة إنشائه. هذا كل شئ! يجب أيضًا أن نعرف بوضوح الإصدار الذي أنشأناه لكل جزء من البنية التحتية.
وحدات البنية التحتية بسيطة للغاية. وهي تتألف من موارد ، وتتضمن معايير الشركة (على سبيل المثال ، العلامات وقوائم القيم القياسية والافتراضات المقبولة وما إلى ذلك).
بالنسبة لمشروعنا وتجربتنا ، فقد تحولنا منذ فترة طويلة وثابتة إلى استخدام وحدات الموارد في كل ما هو ممكن من خلال عملية إصدار ومراجعة صارمة للغاية. ونحن الآن نقدم بنشاط ممارسة وحدات البنية التحتية على مستوى المختبر والتدريج.
توصيات لاستخدام الوحدات
- إذا كنت لا تستطيع الكتابة ، ولكن استخدام تلك الجاهزة ، لا تكتب. خاصة إذا كنت جديدا على هذا. ثق في الوحدات الجاهزة ، أو على الأقل انظر كيف فعلوها لك. ومع ذلك ، إذا كنت لا تزال بحاجة إلى كتابة اتصالك الخاص ، فلا تستخدم المكالمة لمقدمي الخدمة داخليًا وكن حذرًا مع مزودي الخدمة.
- تحقق من أن Terraform Registry لا يحتوي على وحدة موارد جاهزة.
- إذا كنت تكتب الوحدة النمطية الخاصة بك ، إخفاء التفاصيل تحت غطاء محرك السيارة. ليس لدى المستخدم النهائي ما يدعو للقلق بشأن كيفية تنفيذك داخليًا.
- هل معلمات الإدخال وقيم الإخراج من الوحدة النمطية الخاصة بك. والأفضل إذا كانت ملفات منفصلة. مريحة جدا.
- إذا كتبت الوحدات النمطية الخاصة بك ، قم بتخزينها في المستودع والنسخة. أفضل مستودع منفصل للوحدة.
- لا تستخدم الوحدات النمطية المحلية - لا يتم إصدارها أو إعادة استخدامها.
- تجنب استخدام أوصاف الموفر في الوحدة النمطية ، لأنه يمكن تكوين بيانات اعتماد الاتصال وتطبيقها بشكل مختلف لأشخاص مختلفين. يستخدم شخص ما متغيرات البيئة لهذا ، ويشير شخص ما إلى تخزين مفاتيحه وأسراره في الملفات مع تحديد مسارات لها. يجب الإشارة إلى ذلك على مستوى أعلى.
- استخدم المزود المحلي بعناية. يتم تنفيذه محليًا ، على الجهاز الذي تعمل عليه Terraform ، ولكن قد تختلف بيئة التنفيذ لمختلف المستخدمين. حتى تقوم بتضمينها في CI ، يمكنك مصادفة العديد من الأعمال الفنية: على سبيل المثال exec المحلي وتشغيل ansible. ولشخص ما توزيع مختلف أو غلاف آخر أو إصدار مختلف من ansible أو حتى Windows.
علامات على وحدة جيدة (هنا هو
أكثر تفصيلا قليلا ):
- وحدات جيدة لديها وثائق وأمثلة. إذا تم تصميم كل منها كمستودع منفصل ، فسيكون ذلك أسهل.
- ليس لديهم إعدادات مضغوطة (على سبيل المثال ، منطقة AWS).
- استخدم افتراضيات معقولة ، تم تصميمها كإعدادات افتراضية. على سبيل المثال ، لن تقوم الوحدة النمطية لنسخة EC2 افتراضيًا بإنشاء جهاز ظاهري من النوع m5d.24xlarge بالنسبة لك ، فهو يستخدم أحد أنواع t2 أو t3 الدنيا لهذا الغرض.
- الرمز "نظيف" - منظم ، مزود بتعليقات ، غير مرتبك بشكل غير ضروري ، مصمم بنفس الأسلوب.
- من المرغوب فيه بدرجة كبيرة أن تكون مجهزة بالاختبارات ، رغم أنها صعبة. لسوء الحظ ، لم نصل بعد إلى هذا.
علامات
العلامات مهمة.
وضع العلامات هو الفواتير. AWS لديها أدوات تتيح لك معرفة مقدار الأموال التي تنفقها على البنية التحتية الخاصة بك. وأرادت إدارتنا حقًا أن يكون لديها أداة يمكنهم من خلالها رؤيتها بشكل حاسم. على سبيل المثال ، مقدار الأموال التي تستهلكها هذه المكونات أو تلك ، أو كذا وكذا النظام الفرعي ، كذا وكذا الفريق ، وكذا وكذا البيئة

العلامات هي توثيق نظامك. مع ذلك ، يمكنك تبسيط بحثك. حتى في وحدة AWS ، حيث يتم عرض هذه العلامات بدقة على شاشتك ، يصبح من الأسهل بالنسبة لك فهم ما يشير إليه هذا النوع أو هذا النوع من المثيلات. إذا جاء زملاء جدد ، فمن الأسهل بالنسبة لك شرح ذلك من خلال إظهار: "انظر ، هذا هو - هنا". بدأنا في إنشاء العلامات على النحو التالي - أنشأنا مجموعة من العلامات لكل نوع من الموارد.
مثال:
variable "XXX_tags" { description = "The set of XXX tags." type = "map" default = { "TerminationDate" = "03.23.2018", "Environment" = "env_name_here", "Department" = "dev", "Subsystem" = "subsystem_name", "Component" = "XXX", "Type" = "application", "Team" = "team_name" } }
لقد حدث أن أكثر من فريق من فرقنا يستخدم AWS في شركتنا ، وهناك قائمة بالعلامات المطلوبة.
- Team - الفريق الذي يستخدم عدد الموارد.
- قسم - على غرار قسم.
- البيئة - تفوق الموارد في "البيئات" ، ولكن يمكنك ، على سبيل المثال ، استبدالها بمشروع أو شيء من هذا القبيل.
- النظام الفرعي - النظام الفرعي الذي ينتمي إليه المكون. يمكن أن تنتمي المكونات إلى نظام فرعي واحد. على سبيل المثال ، نريد أن نرى كم لدينا هذا النظام الفرعي وبدأت كياناته في الاستهلاك. فجأة ، على سبيل المثال ، في الشهر السابق ، نمت بشكل ملحوظ. نحتاج أن نذهب إلى المطورين ونقول: "يا شباب ، إنه مكلف. الميزانية قريبة بالفعل من بعضها البعض ، دعونا نحسن المنطق بطريقة أو بأخرى. "
- النوع - نوع المكون: الموازن ، التخزين ، التطبيق أو قاعدة البيانات.
- المكون - المكون نفسه ، اسمه في التدوين الداخلي.
- تاريخ الإنهاء - الوقت الذي يجب حذفه فيه ، في تنسيق التاريخ. إذا لم يكن إزالتها متوقعًا ، فاضبط على "دائم". قدمناه لأنه في بيئات التطوير ، وحتى في بعض بيئات المراحل ، لدينا مرحلة اختبار الإجهاد التي ترتفع خلال جلسات الإجهاد ، أي أننا لا نحتفظ بهذه الآلات بانتظام. نشير إلى التاريخ الذي يجب فيه إتلاف المورد. علاوة على ذلك ، يمكنك ربط الأتمتة استنادًا إلى lambda ، بعض البرامج النصية الخارجية التي تعمل من خلال واجهة سطر أوامر AWS ، والتي سوف تدمر هذه الموارد تلقائيًا.
الآن - كيفية وضع علامة.
قررنا أننا سنقوم بعمل خريطة علامات خاصة لكل مكون ، حيث سنقوم بإدراج جميع العلامات المحددة: متى يجب إنهاؤه ، ما يشير إليه. أدركوا بسرعة أنه كان غير مريح. لأن قاعدة الكود تنمو ، لأن لدينا أكثر من 30 مكونًا ، و 30 قطعة من الكود غير ملائمة. إذا كنت بحاجة إلى تغيير شيء ما ، فأنت تقوم بتشغيل وتغيير.
لوضع علامة جيدة ، نستخدم الكيان
المحلي .
locals { common_tags = {"TerminationDate" = "XX.XX.XXXX", "Environment" = "env_name", "Department" = "dev", "Team" = "team_name"} subsystem_1_tags = "${merge(local.common_tags, map("Subsystem", "subsystem_1_name"))}" subsystem_2_tags = "${merge(local.common_tags, map("Subsystem", "subsystem_2_name"))}" }
في ذلك يمكنك سرد مجموعة فرعية ، ثم استخدامها مع بعضها البعض.
على سبيل المثال ، أزلنا بعض العلامات الشائعة في مثل هذا الهيكل ، ثم قمنا بإزالة بعض العلامات حسب النظم الفرعية. نقول: "خذ هذه الكتلة وأضف ، على سبيل المثال ، النظام الفرعي 1. وللنظام الفرعي 2 ، أضف النظام الفرعي 2". نقول: "العلامات ، من فضلك ، خذ الكلمات العامة وأضف النوع والتطبيق والاسم والمكون ومن هو بالنسبة لهم." اتضح التغيير لفترة وجيزة جدا ، وبشكل واضح ومركزي ، إذا كان ذلك فجأة مطلوب.
module "ZZZ02" { count = 1 count_offset = 1 name = "XXX-YYY-ZZZ" ... tags = "${merge(local.core_tags, map("Type", "application", "Component", "XXX"))}" }

التحكم في الإصدار
يجب تخزين وحدات القالب الخاصة بك ، إذا كنت تستخدمها ، في مكان ما. أسهل طريقة يبدأ بها الجميع على الأرجح هي التخزين المحلي. فقط في نفس الدليل ، فقط بعض الأدلة الفرعية التي تصفها ، على سبيل المثال ، قالب لنوع من الخدمة. هذه ليست طريقة جيدة. إنه مناسب ، ويمكن إصلاحه بسرعة واختباره بسرعة ، ولكن من الصعب إعادة استخدامه لاحقًا ويصعب التحكم فيه
module "ZZZ02" { source = "./modules/srvroles/ZZZ" name = "XXX-YYY-ZZZ" }
لنفترض أن المطورين جاءوا إليك وقالوا: "لذلك ، نحن بحاجة إلى كيان كهذا وكذا في مثل هذا التكوين ، في بنيتنا الأساسية." لقد كتبت ذلك ، وجعلته في شكل وحدة محلية في مستودع مشروعهم. نشر - ممتاز. لقد اختبروا ، قال: "سوف! في الإنتاج. " نأتي إلى المرحلة ، اختبار الإجهاد ، الإنتاج. كل مرة Ctrl-C ، Ctrl-V ؛ Ctrl-C ، Ctrl-V. بينما وصلنا إلى البيع ، أخذ زميلنا ذلك ، ونسخ الرمز من بيئة المختبر ، ونقله إلى مكان آخر وتغييره هناك. وحصلنا على حالة غير متناسقة بالفعل. مع التحجيم الأفقي ، عندما يكون لديك العديد من البيئات المختبرية كما هو الحال لدينا ، فهذا مجرد هدف.
لذلك ، هناك طريقة جيدة لإنشاء مستودع Git منفصل لكل وحدة من وحداتك ، ثم قم بالإشارة إليه. نغير كل شيء في مكان واحد - جيد ، مريح ، مسيطر عليه.
module "ZZZ" { source = "git::ssh://git@GIT_SERVER_FQDN/terraform/modules/general-vm/2-disks.git" host_name_prefix = "XXX-YYY-ZZZ"
توقع السؤال ، كيف تصل الشفرة إلى الإنتاج. لهذا الغرض ، يتم إنشاء مشروع منفصل يعيد استخدام الوحدات التي تم إعدادها واختبارها.
رائع ، لدينا مصدر واحد للرمز يتغير مركزيا. أخذت وكتبت وأعدت نفسي في صباح الغد سأنشره في الإنتاج. بنيت خطة ، واختبارها - عظيم ، دعنا نذهب. في هذه اللحظة ، ذهب زميلي ، مسترشداً حصريًا بالنوايا الحسنة ، إلى تحسين شيء ما ، إضافة إلى هذه الوحدة. وحدث أن هذه التغييرات كسر التوافق إلى الوراء.
على سبيل المثال ، أضاف المعلمات الضرورية ، التي يجب أن يمر ، وإلا لن يتم تجميع الوحدة. أو قام بتغيير أسماء هذه المعلمات. لقد جئت في الصباح ، ولديّ وقت محدد للغاية للتغييرات ، وأبدأ في بناء خطة ، وسحب Terraform وحدات الحالة من Git ، ويبدأ في بناء خطة ويقول: "عفوًا لا أستطيع. لا يكفي بالنسبة لك ، أنت تسميته ". أنا مندهش: "لكنني لم أفعل ذلك ، كيف أتعامل معه؟" وإذا كان هذا موردًا تم إنشاؤه منذ فترة طويلة ، فبعد هذه التغييرات ، سيتعين عليك تشغيل جميع البيئات ، والتغيير بطريقة ما وتؤدي إلى نظرة واحدة. هذا غير مريح.
يمكن إصلاح هذا باستخدام علامات Git. قررنا لأنفسنا أن نستخدم
تدوين SemVer ووضعنا قاعدة بسيطة: بمجرد أن يصل تكوين وحدتنا إلى حالة مستقرة معينة ، أي أنه يمكننا استخدامها ، نضع علامة على هذا الالتزام. إذا قمنا بإجراء تغييرات ولم يكسروا التوافق مع الإصدارات السابقة ، فإننا نغير الرقم الثانوي في العلامة ، وإذا كسرنا ، فإننا نغير الرقم الرئيسي.
لذلك ، في العنوان المصدر ، قم بإرفاق علامة محددة وإذا كان على الأقل يوفر شيئًا ما كان لديك من قبل ، فسيتم جمعه دائمًا. دع إصدار الوحدة النمطية يمضي قدمًا ، ولكن في الوقت المناسب سنأتي ، وعندما نحتاج إليه حقًا ، سنغيره. وما كان يعمل قبل ذلك ، على الأقل لن ينكسر. هذا مريح. هذا هو ما يبدو عليه في GitLab لدينا.

تشعب
استخدام المتفرعة هو ممارسة أخرى مهمة. لقد طورنا قاعدة لأنفسنا يجب عليك إجراء تغييرات فقط من السيد. ولكن بالنسبة لأي تغيير تريد إجراؤه واختباره ، يرجى إنشاء فرع منفصل واللعب معه والتجربة ووضع الخطط ومعرفة كيف تسير الأمور. ثم قم بإجراء طلب دمج ودع زميلًا ينظر إلى التعليمات البرمجية وساعدها.

حيث لتخزين tfstate
يجب أن لا تخزن ولايتك محليا. يجب أن لا تخزن ولايتك في بوابة.
لقد أحرقنا هذا الأمر عندما يحصل شخص ما ، عند طرح أغصان غير ربحية ، على tfstate الخاص به ، حيث يتم حفظ الحالة - ثم يديرها من خلال الدمج ، ويضيف شخص ما بلده ، ويظهر تعارضات الدمج. أو اتضح بدونها ، لكن حالة غير متناسقة ، لأنه "لديه بالفعل ، لا أملكها بعد" ، ثم إصلاحها كلها ممارسة غير سارة. لذلك ، قررنا أننا سنخزنها في مكان آمن ، مع الإصدارات ، لكنها ستكون خارج Git.
S3 يناسب تماما تحت هذا: إنه متاح ، لديه HA ، بقدر ما أتذكر
أربعة تسع بالضبط ، ربما خمسة . يعطي إصدارًا من خارج الصندوق ، حتى إذا كسرت tfstate ، يمكنك دائمًا التراجع. كما أنه يعطي شيئًا مهمًا للغاية مع DynamoDB ، والذي ، في رأيي ، تعلم هذا Terraform منذ الإصدار 0.8. في DynamoDB ، لديك لوحة تسجّل فيها Terraform أنه يحظر الحالة.
وهذا هو ، لنفترض أنني أريد إجراء بعض التغييرات. لقد بدأت في إنشاء خطة أو البدء في تطبيقها ، ينتقل Terraform إلى DynamoDB ويقول إنه يجعل المعلومات في هذه اللوحة محظورة ؛ المستخدم ، الكمبيوتر ، الوقت. في هذه اللحظة ، قرر زميلي ، الذي يعمل عن بعد أو ربما على طاولتين مني ، لكنه ركز على العمل ولا يرى ما أفعله ، أن هناك حاجة إلى تغيير شيء ما. لقد وضع خطة ، لكنه أطلقها لاحقًا.
يذهب Terraform إلى الديناميات ، يرى - Lock ، ينهار ، يخبر المستخدم: "عذرًا ، tfstate محظور بشيء ما." يرى أحد الزملاء أنني أعمل الآن ، يمكنه أن يأتي إلي ويقول: "اسمع ، مغيري أكثر أهمية ، استسلم لي ، من فضلك". أقول: "جيد" ، ألغيت الخطة ، وأزل الكتلة ، بل حتى تتم إزالتها تلقائيًا إذا قمت بذلك بشكل صحيح ، دون مقاطعة Ctrl-C. زميل يذهب ويفعل. وبالتالي ، فإننا نؤمن أنفسنا ضد موقف عندما تقوم أنت اثنين بتغيير شيء.
دمج-الطلب
نحن نستخدم المتفرعة في بوابة. نقوم بتعيين طلبات الدمج الخاصة بنا إلى الزملاء. علاوة على ذلك ، في Gitlab ، نستخدم جميع الأدوات المتاحة لنا تقريبًا للعمل معًا أو لطلبات الدمج أو حتى بعض التجمعات: مناقشة التعليمات البرمجية الخاصة بك أو مراجعتها أو تحديد التقدم أو المشكلة أو شيء آخر مثل ذلك. انها مفيدة جدا ، فهي تساعد في العمل.
بالإضافة إلى ذلك ، في هذه الحالة ، يكون الاستعادة أسهل أيضًا ، يمكنك العودة إلى الالتزام السابق ، أو إذا قررت ، على سبيل المثال ، أنك لن تقوم فقط بتطبيق التغييرات من المعالج ، يمكنك التبديل ببساطة إلى فرع ثابت. على سبيل المثال ، لقد قمت بإنشاء فرع للميزات وقررت إجراء تغييرات أولاً من فرع الميزة. ثم التغييرات ، بعد كل شيء يعمل بشكل جيد ، وجعل للسيد. لقد طبقت التغييرات في فرعك ، وأدركت أن هناك شيئًا ما خطأ ، وانتقلت إلى السيد - لم يتم تطبيق أي تغييرات ، فقال تطبيق - عاد.
خط أنابيب

قررنا أننا نحتاج إلى استخدام عملية CI لتطبيق تغييراتنا. للقيام بذلك ، استنادًا إلى Gitlab CI ، نكتب خط أنابيب يعمل على تطبيق التغييرات تلقائيًا. حتى الآن ، لدينا نوعان:
- خط أنابيب للفرع الرئيسي (خط الأنابيب الرئيسي)
- خط أنابيب لجميع الفروع الأخرى (خط أنابيب الفرع)
ماذا خط أنابيب الغداء؟
يبدأ التحقق التلقائي من التعليمات البرمجية (التحقق من الأخطاء المطبعية بطريقة غبية ، على سبيل المثال). ثم تبدأ في بناء خطة. كما يمكن للزميل الذي سيشاهد طلب الدمج الخاص بك فتح الخطة التي تم إنشاؤها على الفور ورؤية ليس فقط الكود - ولكن أيضًا ما تضيفه. سوف يرى أيضًا كيف ستقع على البنية الأساسية الخاصة بك. انها واضحة ومفيدة.
في المعالج ، تتم إضافة خطوة أخرى هنا. الفرق هو أن خطتك لم يتم توليدها فقط ، بل يتم حفظها أيضًا كأداة. ميزة أخرى مفيدة للغاية من Terraform هي أنه يمكن حفظ الخطة كملف ، ثم تطبيقها. دعنا نفترض أنك قدمت طلب دمج ووضعته جانباً. وبعد شهر تذكروه وقرروا العودة. لقد مضى رمزك بالفعل إلى الأمام. نظرًا لحقيقة أنك تحافظ على أثر الخطة ، يمكنك تطبيقه على ما تريد في تلك اللحظة.
في حالتنا ، يتم بعد ذلك نقل هذه الأداة إلى الخطوة التالية ، والتي يتم تنفيذها باليد. وهذا هو ، نحصل على نقطة واحدة لتطبيق تغييراتنا.عيوب terraform
. Terraform , , .
, «» — , .
, , count — , , , , availability-. , , , . . , AZ . , count .
, 4 AZ 5 , AZ — 4, , . : « ». ! , . Terraform .
. —
. . - - If Else. , — , .
. , , , , Terraform- , CI.
CI . , , , — merge, . .
, . . , , Terraform , , tfstate Terraform : «, , ». , , .
CI, , pipeline — , .
, . , . , target , . , : «Terraform apply target instance», -. - (, - ), .
, . . CI — , Terraform , . , - . , , , . .
Terraform —
:
- Terraform , . , , . , , , . , , , .
, — Tfstate, , . . « , » — .
, -, , - — . , . , — . - Terraform , . Terraform . لماذا؟ , . . , , AZ - -. , North Virginia, 6 . . , , : «, ». — . — , , Terraform .
- Terraform . , — 200 , 198 , 5. . , API . للأسف.
- , . , S3 bucket. , — , - . Terraform – , , : «, - ». . - , .
, Terraform — , . , .