Terraformer - โครงสร้างพื้นฐานในการเขียนโค้ด

Terraformer - โครงสร้างพื้นฐานในการเขียนโค้ด
ฉันอยากจะบอกคุณเกี่ยวกับเครื่องมือ CLI ใหม่ที่ฉันเขียนเพื่อแก้ไขปัญหาเก่า

ปัญหา

Terraform เป็นมาตรฐานในชุมชน Devops/Cloud/IT มาอย่างยาวนาน สิ่งนี้สะดวกและมีประโยชน์มากในการจัดการกับโครงสร้างพื้นฐานในรูปแบบโค้ด Terraform มีความเพลิดเพลินมากมาย เช่นเดียวกับส้อม มีดคมๆ และคราดมากมาย
ด้วย Terraform สะดวกในการสร้างสิ่งใหม่ๆ แล้วจัดการ เปลี่ยนแปลง หรือลบสิ่งเหล่านั้น ผู้ที่มีโครงสร้างพื้นฐานขนาดใหญ่ในระบบคลาวด์และไม่ได้สร้างผ่าน Terraform ควรทำอย่างไร การเขียนใหม่และการสร้างระบบคลาวด์ทั้งหมดใหม่มีราคาแพงและไม่ปลอดภัย
ฉันพบปัญหานี้ในงาน 2 งาน ตัวอย่างที่ง่ายที่สุดคือเมื่อคุณต้องการให้ทุกอย่างอยู่ใน Git ในรูปแบบของไฟล์ Terraform แต่คุณมีบัคเก็ตมากกว่า 250+ บัคเก็ต และมีหลายสิ่งที่ต้องเขียนเป็น Terraform ด้วยมือ
มี ปัญหา ตั้งแต่ปี 2014 ใน terrafom ซึ่งปิดตัวลงในปี 2016 ด้วยความหวังว่าจะมีการนำเข้า

โดยทั่วไปทุกอย่างจะเป็นตามภาพจากขวาไปซ้ายเท่านั้น

คำเตือน: ผู้เขียนไม่ได้อาศัยอยู่ในรัสเซียเป็นเวลาครึ่งชีวิตและเขียนเป็นภาษารัสเซียเพียงเล็กน้อย ระวังการสะกดผิด

โซลูชั่น

1. มีโซลูชันสำเร็จรูปและเก่าสำหรับ AWS การจัดพื้นผิว. เมื่อฉันพยายามเอาถังมากกว่า 250 ถังผ่านไป ฉันก็รู้ว่าทุกอย่างที่นั่นแย่ไปหมด AWS ได้แนะนำตัวเลือกใหม่ ๆ มากมายมานานแล้ว แต่การสร้างพื้นผิวไม่รู้เกี่ยวกับตัวเลือกเหล่านี้ และโดยทั่วไปแล้วมันคือ Ruby เทมเพลตดูเบาบาง. บ่าย 2 โมงก็ส่งครับ ดึงคำขอ เพื่อเพิ่มคุณสมบัติเข้าไปอีกและตระหนักว่าโซลูชันดังกล่าวไม่เหมาะเลย
วิธีการทำงานของการจัดรูปแบบพื้นผิว: ใช้ข้อมูลจาก AWS SDK และสร้าง tf และ tfstate ผ่านเทมเพลต
มี 3 ปัญหาที่นี่:
1. จะมีการอัพเดตล่าช้าอยู่เสมอ
2. ไฟล์ tf บางครั้งออกมาเสีย
3. tfstate ถูกรวบรวมแยกจาก tf และไม่ได้มาบรรจบกันเสมอไป
โดยทั่วไป เป็นเรื่องยากที่จะได้ผลลัพธ์โดยที่ `แผนพื้นผิว` บอกว่าไม่มีการเปลี่ยนแปลง

2. `การนำเข้า Terraform` เป็นคำสั่งในตัวใน Terraform มันทำงานอย่างไร?
คุณเขียนไฟล์ TF เปล่าพร้อมชื่อและประเภทของทรัพยากร จากนั้นเรียกใช้ `terraform import` และส่งรหัสทรัพยากร Terraform ติดต่อผู้ให้บริการ รับข้อมูล และสร้างไฟล์ tfstate
มี 3 ปัญหาที่นี่:
1. เราได้รับไฟล์ tfstate เท่านั้น และ tf ว่างเปล่า คุณต้องเขียนมันด้วยตนเองหรือแปลงจาก tfstate
2. สามารถทำงานกับทรัพยากรได้ครั้งละหนึ่งรายการเท่านั้นและไม่รองรับทรัพยากรทั้งหมด แล้วฉันควรทำอย่างไรอีกครั้งกับถังมากกว่า 250+?
3. คุณจำเป็นต้องทราบ ID ของทรัพยากร - นั่นคือ คุณต้องล้อมมันด้วยโค้ดที่ได้รับรายการทรัพยากร
โดยทั่วไปแล้ว ผลลัพธ์ที่ได้จะเป็นเพียงบางส่วนและไม่ได้ขยายขนาดอย่างเหมาะสม

การตัดสินใจของฉัน

คุณสมบัติผู้สมัคร:
1. ความสามารถในการสร้างไฟล์ tf และ tfstate สำหรับทรัพยากร ตัวอย่างเช่น ดาวน์โหลดที่เก็บข้อมูล/กลุ่มความปลอดภัย/โหลดบาลานเซอร์ทั้งหมด และ `แผนภูมิประเทศ' นั้นส่งคืนว่าไม่มีการเปลี่ยนแปลง
2. คุณต้องมีคลาวด์ GCP + AWS 2 อัน
3. Global Solution ที่อัพเดทได้ง่ายทุกครั้งและไม่เสียเวลากับทรัพยากรแต่ละอย่างเป็นเวลา 3 วันในการทำงาน
4. ทำให้เป็น Open Source - ทุกคนก็ประสบปัญหาเดียวกัน

ภาษา Go คือเหตุผลที่ฉันชอบ และมีไลบรารีสำหรับสร้างไฟล์ HCL ที่ใช้ใน Terraform + โค้ดจำนวนมากใน Terraform ที่มีประโยชน์

เส้นทาง

พยายามก่อน
ฉันเริ่มต้นด้วยเวอร์ชันที่เรียบง่าย ติดต่อคลาวด์ผ่าน SDK สำหรับทรัพยากรที่ต้องการและแปลงเป็นฟิลด์สำหรับ Terraform ความพยายามนี้หยุดลงในกลุ่มความปลอดภัยทันทีเพราะฉันไม่ชอบเวลา 1.5 วันในการแปลงเฉพาะกลุ่มความปลอดภัย (และมีทรัพยากรมากมาย) เป็นเวลานานแล้วจึงสามารถเปลี่ยน/เพิ่มฟิลด์ได้

ความพยายามครั้งที่สอง
ตามแนวคิดที่อธิบายไว้ ที่นี่. เพียงใช้และแปลง tfstate เป็น tf ข้อมูลทั้งหมดอยู่ที่นั่นและฟิลด์ก็เหมือนกัน วิธีรับ tfstate แบบเต็มสำหรับทรัพยากรจำนวนมาก ?? นี่คือจุดที่คำสั่ง `terraform Refresh` เข้ามาช่วยเหลือ terraform รับทรัพยากรทั้งหมดใน tfstate และดึงข้อมูลออกมาและเขียนทุกอย่างลงใน tfstate ตาม ID นั่นคือ สร้าง tfstate ว่างที่มีเพียงชื่อและ ID เรียกใช้ `terraform Refresh` จากนั้นเราจะได้ tfstate แบบเต็ม ไชโย!
ตอนนี้เรามาทำภาพอนาจารแบบเรียกซ้ำในการเขียนตัวแปลงสำหรับ tfstate เป็น tf สำหรับผู้ที่ไม่เคยอ่าน tfstate มาก่อน มันคือ JSON แต่พิเศษ
นี่คือคุณลักษณะส่วนสำคัญ

 "attributes": {
                            "id": "default/backend-logging-load-deployment",
                            "metadata.#": "1",
                            "metadata.0.annotations.%": "0",
                            "metadata.0.generate_name": "",
                            "metadata.0.generation": "24",
                            "metadata.0.labels.%": "1",
                            "metadata.0.labels.app": "backend-logging",
                            "metadata.0.name": "backend-logging-load-deployment",
                            "metadata.0.namespace": "default",
                            "metadata.0.resource_version": "109317427",
                            "metadata.0.self_link": "/apis/apps/v1/namespaces/default/deployments/backend-logging-load-deployment",
                            "metadata.0.uid": "300ecda1-4138-11e9-9d5d-42010a8400b5",
                            "spec.#": "1",
                            "spec.0.min_ready_seconds": "0",
                            "spec.0.paused": "false",
                            "spec.0.progress_deadline_seconds": "600",
                            "spec.0.replicas": "1",
                            "spec.0.revision_history_limit": "10",
                            "spec.0.selector.#": "1",

มี:
1. ไอดี - สตริง
2. ข้อมูลเมตา - อาร์เรย์ขนาด 1 และมีออบเจ็กต์ที่มีช่องต่างๆ อยู่ในนั้น ซึ่งอธิบายไว้ด้านล่าง
3. ข้อมูลจำเพาะ - แฮชขนาด 1 และคีย์ ค่าในนั้น
สรุปก็คือ รูปแบบที่สนุก ทุกอย่างสามารถมีความลึกได้หลายระดับ

                   "spec.#": "1",
                            "spec.0.min_ready_seconds": "0",
                            "spec.0.paused": "false",
                            "spec.0.progress_deadline_seconds": "600",
                            "spec.0.replicas": "1",
                            "spec.0.revision_history_limit": "10",
                            "spec.0.selector.#": "1",
                            "spec.0.selector.0.match_expressions.#": "0",
                            "spec.0.selector.0.match_labels.%": "1",
                            "spec.0.selector.0.match_labels.app": "backend-logging-load",
                            "spec.0.strategy.#": "0",
                            "spec.0.template.#": "1",
                            "spec.0.template.0.metadata.#": "1",
                            "spec.0.template.0.metadata.0.annotations.%": "0",
                            "spec.0.template.0.metadata.0.generate_name": "",
                            "spec.0.template.0.metadata.0.generation": "0",
                            "spec.0.template.0.metadata.0.labels.%": "1",
                            "spec.0.template.0.metadata.0.labels.app": "backend-logging-load",
                            "spec.0.template.0.metadata.0.name": "",
                            "spec.0.template.0.metadata.0.namespace": "",
                            "spec.0.template.0.metadata.0.resource_version": "",
                            "spec.0.template.0.metadata.0.self_link": "",
                            "spec.0.template.0.metadata.0.uid": "",
                            "spec.0.template.0.spec.#": "1",
                            "spec.0.template.0.spec.0.active_deadline_seconds": "0",
                            "spec.0.template.0.spec.0.container.#": "1",
                            "spec.0.template.0.spec.0.container.0.args.#": "3",

โดยทั่วไปแล้ว หากใครต้องการปัญหาการเขียนโปรแกรมสำหรับการสัมภาษณ์ ก็ขอให้เขียน parser สำหรับงานนี้ได้เลย :)
หลังจากพยายามเขียน parser โดยไม่มีจุดบกพร่องอยู่หลายครั้ง ฉันพบส่วนหนึ่งของมันในโค้ด Terraform และส่วนที่สำคัญที่สุด และทุกอย่างดูเหมือนจะทำงานได้ดี

พยายามสาม
ผู้ให้บริการ Terraform คือไบนารีที่มีโค้ดพร้อมทรัพยากรและตรรกะทั้งหมดสำหรับการทำงานกับ Cloud API คลาวด์แต่ละแห่งมีผู้ให้บริการของตัวเอง และ Terraform เองก็เรียกพวกเขาผ่านโปรโตคอล RPC ระหว่างสองกระบวนการเท่านั้น
ตอนนี้ฉันตัดสินใจติดต่อผู้ให้บริการ Terraform โดยตรงผ่านการโทร RPC มันออกมาสวยงามและทำให้สามารถเปลี่ยนผู้ให้บริการ Terraform เป็นผู้ให้บริการที่ใหม่กว่าและรับคุณสมบัติใหม่โดยไม่ต้องเปลี่ยนรหัส ปรากฎว่าไม่ใช่ทุกฟิลด์ใน tfstate ที่ควรจะเป็น tf แต่คุณจะทราบได้อย่างไร เพียงถามผู้ให้บริการของคุณเกี่ยวกับเรื่องนี้ จากนั้นภาพอนาจารแบบเรียกซ้ำอีกครั้งของการรวบรวมนิพจน์ทั่วไปก็เริ่มต้นขึ้น โดยค้นหาฟิลด์ภายใน tfstate ในทุกระดับในเชิงลึก

ในที่สุด เราก็มีเครื่องมือ CLI ที่มีประโยชน์ซึ่งมีโครงสร้างพื้นฐานทั่วไปสำหรับผู้ให้บริการ Terraform ทั้งหมด และคุณสามารถเพิ่มผู้ให้บริการใหม่ได้อย่างง่ายดาย นอกจากนี้ การเพิ่มทรัพยากรยังใช้โค้ดเพียงเล็กน้อยอีกด้วย แถมสารพัดทุกประเภท เช่น การเชื่อมต่อระหว่างทรัพยากร แน่นอนว่ามีปัญหามากมายที่ไม่สามารถอธิบายได้ทั้งหมด
ฉันตั้งชื่อสัตว์ตัวนี้ว่า Terrafomer

ฉากสุดท้ายของละคร

เมื่อใช้ Terrafomer เราสร้างโค้ด tf + tfstate จำนวน 500-700 บรรทัดจากคลาวด์สองแห่ง เราสามารถนำสิ่งเก่าๆ และเริ่มสัมผัสสิ่งเหล่านั้นผ่าน Terraform เท่านั้น เช่นเดียวกับในโครงสร้างพื้นฐานที่ดีที่สุดในฐานะแนวคิดโค้ด เป็นเรื่องมหัศจรรย์เมื่อคุณนำคลาวด์ขนาดใหญ่และรับผ่านทีมในรูปแบบของไฟล์ Terraform Worker จากนั้น grep/replace/git และอื่นๆ

ฉันหวีมันออกมาและเรียงตามลำดับได้รับอนุญาต เผยแพร่บน GitHub สำหรับทุกคนในวันพฤหัสบดี (02.05.19/XNUMX/XNUMX) github.com/GoogleCloudPlatform/terraformer
ได้รับ 600 ดาวแล้ว คำขอดึง 2 รายการเพื่อเพิ่มการรองรับ openstack และ kubernetes ข้อเสนอแนะที่ดี โดยทั่วไปแล้วโครงการนี้จะเป็นประโยชน์ต่อประชาชน
ฉันแนะนำทุกคนที่ต้องการเริ่มทำงานกับ Terraform และไม่เขียนทุกอย่างใหม่เพื่อสิ่งนี้
ยินดีดึงคำขอประเด็นดาว

การสาธิต
Terraformer - โครงสร้างพื้นฐานในการเขียนโค้ด

ที่มา: will.com

เพิ่มความคิดเห็น