Terraformer - Kodlama Altyapısı

Terraformer - Kodlama Altyapısı
Sizlere eski bir sorunu çözmek için yazdığım yeni CLI aracından bahsetmek istiyorum.

Sorun

Terraform, Devops/Cloud/IT topluluğunda uzun süredir bir standarttır. Bu şey, altyapıyı kod olarak ele almak için çok kullanışlı ve kullanışlıdır. Terraform'da pek çok lezzetin yanı sıra pek çok çatal, keskin bıçak ve tırmık da mevcut.
Terraform ile yeni şeyler oluşturmak ve bunları yönetmek, değiştirmek veya silmek çok kolaydır. Bulutta devasa bir altyapıya sahip olan ve Terraform üzerinden oluşturulamayanlar ne yapmalı? Bulutun tamamını yeniden yazmak ve yeniden oluşturmak bir şekilde pahalı ve güvensizdir.
Bu sorunla 2 işte karşılaştım, en basit örnek, her şeyin Git'te terraform dosyaları biçiminde olmasını istediğinizde, ancak 250'den fazla kovanız var ve bunları terraform'da elle yazmak çok fazla.
Var konu 2014 yılında ithalat olur umuduyla kapatılan terrafom'da 2016 yılından bu yana faaliyet gösteriyoruz.

Genel olarak her şey resimdeki gibidir sadece sağdan sola

Uyarılar: Yazar hayatının yarısını Rusya'da yaşamıyor ve çok az Rusça yazıyor. Yazım hatalarına dikkat edin.

Çözümler

1. AWS için hazır ve eski çözümler mevcut terraforming. 250'den fazla kovamı içinden geçirmeye çalıştığımda orada her şeyin kötü olduğunu fark ettim. AWS uzun zamandır pek çok yeni seçenek sunuyor ancak dünyalaştırmanın bunlardan haberi yok ve genel olarak yakut şablon seyrek görünüyor. Akşam saat 2'den sonra gönderdim Çekme isteği oraya daha fazla özellik eklemek ve böyle bir çözümün hiç de uygun olmadığını fark etmek.
Dünyalaştırma nasıl çalışır: AWS SDK'dan veri alır ve bir şablon aracılığıyla tf ve tfstate oluşturur.
Burada 3 sorun var:
1. Güncellemelerde her zaman bir gecikme olacaktır
2. tf dosyaları bazen bozuk çıkıyor
3. tfstate, tf'den ayrı olarak toplanır ve her zaman yakınsamayabilir
Genel olarak 'terraform planı'nda hiçbir değişiklik olmadığını söyleyen bir sonuç almak zordur.

2. 'terraform import' terraform'da yerleşik bir komuttur. O nasıl çalışır?
Kaynağın adını ve türünü içeren boş bir TF dosyası yazarsınız, ardından "terraform import"u çalıştırırsınız ve kaynak kimliğini iletirsiniz. terraform sağlayıcıyla iletişim kurar, verileri alır ve bir tfstate dosyası oluşturur.
Burada 3 sorun var:
1. Sadece bir tfstate dosyası alıyoruz ve tf boş, onu manuel olarak yazmanız veya tfstate'ten dönüştürmeniz gerekiyor
2. Aynı anda yalnızca bir kaynakla çalışabilir ve tüm kaynakları desteklemez. Peki 250'den fazla kovayla tekrar ne yapmalıyım?
3. Kaynakların kimliğini bilmeniz gerekir; yani, bunu kaynakların listesini alan koda sarmanız gerekir.
Genel olarak sonuç kısmidir ve iyi ölçeklenmez

Benim kararım

Gereksinimler:
1. Kaynaklar için tf ve tfstate dosyaları oluşturma yeteneği. Örneğin, tüm paketleri/güvenlik grubunu/yük dengeleyiciyi indirin ve "terraform planı" hiçbir değişiklik olmadığını döndürdü
2. 2 GCP + AWS bulutuna ihtiyacınız var
3. Her seferinde güncellenmesi kolay ve 3 günlük çalışma boyunca her kaynakta zaman kaybetmeyen global çözüm
4. Açık Kaynak Yapın – herkes aynı sorunu yaşıyor

Go dilini bu yüzden seviyorum ve terraform'da kullanılan HCL dosyaları oluşturmak için bir kütüphaneye ve terraform'da yararlı olabilecek birçok koda sahip.

Yol

İlk girişim
Basit bir versiyonla başladım. Gerekli kaynak için SDK aracılığıyla bulutla iletişime geçilmesi ve bu kaynağın terraform alanlarına dönüştürülmesi. Güvenlik grubundaki girişim anında sonuçsuz kaldı çünkü yalnızca güvenlik grubunu dönüştürmek için geçen 1.5 günden hoşlanmadım (ve çok fazla kaynak var). Uzun bir süre boyunca alanlar değiştirilebilir/eklenebilir

İkinci deneme
Açıklanan fikirden yola çıkarak burada. Sadece tfstate'i alıp tf'ye dönüştürün. Tüm veriler orada ve alanlar aynı. Birçok kaynak için tam tfstate nasıl alınır? Burası 'terraform yenileme' komutunun imdada yetiştiği yer. terraform, tfstate'teki tüm kaynakları alır ve ID'ye göre bunlarla ilgili verileri çeker ve her şeyi tfstate'e yazar. Yani, yalnızca adları ve kimlikleri içeren boş bir tfstate oluşturun, "terraform yenilemeyi" çalıştırın ve ardından tam tfstate'leri elde ederiz. Yaşasın!
Şimdi tfstate'i tf'ye dönüştürücü yazmanın özyinelemeli pornografisini yapalım. Hiç tfstate okumamış olanlar için JSON'dur ama özeldir.
İşte önemli parça özellikleri

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

Orada:
1. kimlik - dize
2. meta veriler - 1 boyutunda bir dizi ve içinde aşağıda açıklanan alanları içeren bir nesne
3. spec - boyut 1 ve anahtarın karma değeri, içindeki değer
Kısacası eğlenceli bir format, her şey birkaç seviye derinliğinde olabilir

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

Genel olarak, eğer birisi bir röportaj için programlama problemi isterse, ondan bu görev için bir ayrıştırıcı yazmasını isteyin :)
Hatasız bir ayrıştırıcı yazmaya yönelik birçok denemeden sonra, bunun bir kısmını ve en önemli kısmını terraform kodunda buldum. Ve her şey yolunda gidiyor gibi görünüyordu

Üçünü dene
Terraform sağlayıcıları, bulut API ile çalışmaya yönelik tüm kaynakları ve mantığı içeren kodu içeren ikili dosyalardır. Her bulutun kendi sağlayıcısı vardır ve terraform'un kendisi bunları yalnızca iki işlem arasındaki RPC protokolü aracılığıyla çağırır.
Artık terraform sağlayıcılarıyla doğrudan RPC çağrıları aracılığıyla iletişime geçmeye karar verdim. Çok güzel bir sonuç verdi ve terraform sağlayıcılarını daha yenileriyle değiştirmeyi ve kodu değiştirmeden yeni özellikler almayı mümkün kıldı. Ayrıca tfstate'teki tüm alanların tf'de olmaması gerektiği ortaya çıktı, ancak bunu nasıl öğrenebilirsiniz? Bunu sağlayıcınıza sormanız yeterli. Daha sonra, tfstate içindeki alanları derinlemesine her seviyede arayarak, düzenli ifadeleri birleştirmeye yönelik başka bir özyinelemeli pornografi başladı.

Sonuçta tüm terraform sağlayıcıları için ortak altyapıya sahip, kullanışlı bir CLI aracına sahip olduk ve kolayca yenisini ekleyebilirsiniz. Ayrıca kaynak eklemek çok az kod gerektirir. Ayrıca kaynaklar arasındaki bağlantılar gibi her türlü güzellik. Elbette hepsi anlatılmayacak kadar farklı sorunlar vardı.
Hayvana Terrafomer adını verdim.

final

Terrafomer kullanarak iki buluttan 500-700 bin satır tf+tfstate kodu ürettik. Eski şeyleri alıp, kod fikirleri olarak en iyi altyapıda olduğu gibi, yalnızca terraform aracılığıyla onlara dokunmaya başlayabildik. Devasa bir bulutu alıp bir ekip aracılığıyla dünyasal işçi dosyaları biçiminde aldığınızda bu gerçekten sihirdir. Ve sonra grep/replace/git vb.

Taradım, düzene koydum, izin aldım. Perşembe (02.05.19/XNUMX/XNUMX) günü herkes için GitHub'da yayınlandı. github.com/GoogleCloudPlatform/terraformer
Openstack ve kubernetes desteği eklemek için halihazırda 600 yıldız ve 2 çekme isteği alındı. İyi geri bildirim. Genel olarak proje insanlar için faydalıdır
Terraform ile çalışmaya başlamak isteyen herkese bunun için her şeyi yeniden yazmamalarını tavsiye ediyorum.
İstekleri, sorunları, yıldızları çekmekten memnuniyet duyacağım.

Demo
Terraformer - Kodlama Altyapısı

Kaynak: habr.com

Yorum ekle