Terraform, Mono-Repositories und Compliance als Code

Hallo alle zusammen. OTUS eröffnete die Rekrutierung für eine neue Gruppe im Kurs „Infrastrukturplattform basierend auf Kubernetes“ . In diesem Zusammenhang haben wir eine Übersetzung von interessantem Material zu diesem Thema vorbereitet.




Möglicherweise gehören Sie zu denjenigen, die terraform for Infrastructure als Code verwenden, und Sie fragen sich, wie Sie es produktiver und sicherer verwenden können. Im Allgemeinen hat dies in letzter Zeit viele gestört. Wir alle schreiben Konfiguration und Code mit verschiedenen Tools und Sprachen und verbringen viel Zeit damit, sie lesbarer, erweiterbarer und skalierbarer zu machen.


Vielleicht liegt das Problem bei uns selbst?

Geschriebener Code sollte Wert schaffen oder ein Problem lösen sowie für die Deduplizierung wiederverwendbar sein. Typischerweise wird diese Art von Diskussion endet mit „Lassen Sie uns die Verwendung Module . Wir alle verwenden Terraform-Module, oder? Ich könnte viele Geschichten mit Problemen aufgrund übermäßiger Modularität schreiben, aber dies ist eine völlig andere Geschichte, und ich werde es nicht tun.


Nein, werde ich nicht. Bestehen Sie nicht darauf, nein ... Okay, vielleicht später.

Es ist allgemein bekannt, Code zu kennzeichnen, wenn Module zum Sperren des Root-Moduls verwendet werden, um dessen Funktion auch beim Ändern des Modulcodes zu gewährleisten. Dieser Ansatz sollte zu einem Teamprinzip werden, bei dem die entsprechenden Module gekennzeichnet und entsprechend verwendet werden.

... aber was ist mit Abhängigkeiten? Was ist, wenn ich 120 Module in 120 verschiedenen Repositorys habe und das Ändern eines Moduls 20 andere Module betrifft ? Bedeutet dies, dass wir 20 + 1 Pull-Anfragen ausführen müssen? Wenn die Mindestanzahl von Gutachtern 2 beträgt, bedeutet dies 21 x 2 = 44Rezension. Ernsthaft! Wir lähmen den Befehl einfach, indem wir „ein Modul ändern“, und jeder beginnt, Meme oder Gifs des Herrn der Ringe zu senden, und der Rest des Tages geht verloren.


Eine PR, um alle zu benachrichtigen, eine PR, um alle zusammenzubringen, zu fesseln und in die Dunkelheit zu stürzen.

Lohnt es sich zu arbeiten? Sollten wir die Anzahl der Gutachter reduzieren? Oder machen Sie vielleicht eine Ausnahme für die Module und benötigen Sie keine PR, wenn die Änderung große Auswirkungen hat. "Ja wirklich?" Möchtest du blind in einem tiefen dunklen Wald gehen? Oder sie alle zusammenbringen, langweilen und in die Dunkelheit eintauchen ?

Nein, ändern Sie nicht die Reihenfolge der Überprüfung. Wenn Sie der Meinung sind, dass die Arbeit mit PR richtig ist, bleiben Sie dabei. Wenn Sie intelligente Pipelines haben oder auf Master drängen, bleiben Sie bei diesem Ansatz.

In diesem Fall ist das Problem nicht "Wie arbeiten Sie?" , Sondern "Wie ist die Struktur Ihrer Git-Repositorys?" .



Dies ähnelt dem, was ich fühlte, als ich den folgenden Vorschlag zum ersten Mal anwendete.

Kehren wir zu den Grundlagen zurück. Was sind die allgemeinen Anforderungen an ein Repository mit Terraform-Modulen?

  1. Es muss markiert sein, damit keine wesentlichen Änderungen vorgenommen werden.
  2. Jede Änderung sollte getestet werden können.
  3. Änderungen müssen einer gegenseitigen Überprüfung unterzogen werden.

Dann schlage ich Folgendes vor: Verwenden Sie KEINE Mikro-Repositorys für Terraform-Module. Verwenden Sie ein Mono-Repository .

  • Sie können das gesamte Repository mit Tags versehen, wenn eine Änderung / Anforderung vorliegt
  • Jede Änderung, PR oder Push kann getestet werden.
  • Jede Änderung kann durch die Überprüfung gehen.


Ich habe Kraft!

Ok, aber wie wird dieses Repository aufgebaut sein? In den letzten vier Jahren hatte ich viele Fehler im Zusammenhang damit und bin zu dem Schluss gekommen, dass ein separates Verzeichnis für das Modul die beste Lösung wäre.


Beispiel für eine Verzeichnisstruktur für ein Mono-Repository. Siehe die Änderung tags_override?

Ein Modulwechsel, der 20 andere Module betrifft, ist also nur 1 PR ! Selbst wenn Sie dieser PR 5 Reviewer hinzufügen, ist die Review im Vergleich zu Micro-Repositories sehr schnell. Wenn Sie Github verwenden, ist dies sogar noch besser! Sie können CODEOWNERS für Module verwenden, die Betreuer / Eigentümer haben. Alle Änderungen an diesen Modulen MÜSSEN von diesem Eigentümer genehmigt werden.

Großartig, aber wie benutzt man ein solches Modul, das sich im Mono-Repository-Verzeichnis befindet?

Einfach:

module "from_mono_repo" {
 source = "git::ssh://.../<org>/<repo>.git//<my_module_dir>"
 ...
}
module "from_mono_repo_with_tags" {
  source = "git::ssh://..../<org>/<repo>.git//<mod_dir>?ref=1.2.4"
  ...
}
module "from_micro_repo" {
  source = "git::ssh://.../<org>/<mod_repo>.git"
  ...
}
module "from_micro_repo_with_tags" {
  source = "git::ssh://.../<org>/<mod_repo>.git?ref=1.2.4"
  ...
}

Was sind die Nachteile dieser Art von Struktur? Wenn Sie versuchen, "jedes Modul" mit PR / change zu testen, erhalten Sie 1,5 Stunden CI-Pipelines. Sie müssen die geänderten Module in PR finden. So mach ich es:

changed_modules=$(git diff --name-only $(git rev-parse origin/master) HEAD | cut -d "/" -f1 | grep ^aws- | uniq)

Es gibt noch einen weiteren Nachteil: Wenn Sie "terraform init" ausführen, wird das gesamte Repository in das Verzeichnis .terraform geladen. Ich hatte jedoch nie ein Problem damit, da ich meine Pipes in skalierbaren AWS CodeBuild-Containern ausführe. Wenn Sie Jenkins und persistente Jenkins-Slaves verwenden, liegt möglicherweise dieses Problem vor.


Bring uns nicht zum Weinen.

Mit einem Mono-Repository haben Sie immer noch alle Vorteile von Mikro-Repositorys, aber als Bonus reduzieren Sie die Kosten für die Wartung Ihrer Module.

Ehrlich gesagt sollte nach der Arbeit in diesem Modus der Vorschlag, Mikro-Repositories für Terraform-Module zu verwenden, als Straftat angesehen werden.

Großartig, was ist mit Unit-Tests? Benötigen Sie das wirklich? ... Was genau meinen Sie im Allgemeinen mit Unit-Tests? Überprüfen Sie wirklich, ob die AWS-Ressource korrekt erstellt wurde? Wessen Verantwortung ist dies: Terraform oder eine API, die die Ressourcenerstellung übernimmt? Vielleicht sollten wir uns mehr auf negative Tests und die Idempotenz des Codes konzentrieren .

Um die Idempotenz des Codes zu überprüfen, bietet terraform einen hervorragenden Parameter namens -detailed-exitcode. Renn einfach:

> terraform plan -detailed-exitcode

Danach laufen terraform applyund fertig. Zumindest werden Sie sicher sein, dass Ihr Code idempotent ist und keine neuen Ressourcen aufgrund einer zufälligen Zeichenfolge oder etwas anderem erstellt.

Was ist mit negativen Tests? Was sind negative Tests im Allgemeinen? In der Tat unterscheidet sich dies nicht sehr von Unit-Tests, aber Sie achten auf negative Situationen.

Beispielsweise darf niemand einen unverschlüsselten und öffentlichen S3-Bucket erstellen .

Anstatt zu überprüfen, ob tatsächlich ein S3-Bucket erstellt wird, überprüfen Sie anhand einer Reihe von Richtlinien, ob Ihr Code eine Ressource erstellt. Wie kann man das machen? Terraform Enterprise bietet hierfür ein großartiges Tool, Sentinel .

... aber es gibt auch Open Source Alternativen. Derzeit gibt es viele Tools zur statischen Analyse von HCL-Code. Mit diesen Tools, die auf gängigen Best Practices basieren, können Sie keine unerwünschten Aktionen ausführen. Was ist jedoch, wenn Sie nicht den erforderlichen Test haben? Oder, noch schlimmer, wenn Ihre Situation etwas anders ist? Sie möchten beispielsweise zulassen, dass einige S3-Buckets unter bestimmten Bedingungen veröffentlicht werden. Dies ist in der Tat ein Sicherheitsfehler für diese Tools.

Hier erscheint die Terraform-Konformität. Mit diesem Tool können Sie nicht nur Ihre eigenen Tests schreiben, in denen Sie bestimmen können, WAS Sie als Unternehmensrichtlinie wünschen, sondern auch Sicherheit und Entwicklung voneinander trennen, indem Sie die Sicherheit nach links verschieben. Klingt ziemlich kontrovers, oder? Nein. Während?


Terraform-Compliance-Logo Bei

Terraform-Compliance wird zunächst Behavior Driven Development (BDD) verwendet.

Feature: Ensure that we have encryption everywhere.

    Scenario: Reject if an S3 bucket is not encrypted
        Given I have aws_s3_bucket defined
        Then it must contain server_side_encryption_configuration

Überprüfen Sie, ob die Verschlüsselung aktiviert ist.

Wenn dies für Sie nicht ausreicht, können Sie detaillierter schreiben:

Feature: Ensure that we have encryption everywhere.

    Scenario: Reject if an S3 bucket is not encrypted with KMS
        Given I have aws_s3_bucket defined
        Then it must contain server_side_encryption_configuration
        And it must contain rule
        And it must contain apply_server_side_encryption_by_default
        And it must contain sse_algorithm
        And its value must match the "aws:kms" regex

Wir gehen tiefer und überprüfen, ob KMS für die Verschlüsselung verwendet wird.

Der Terraform-Code für diesen Test:

resource "aws_kms_key" "mykey" {
 description             = "This key is used to encrypt bucket objects"
 deletion_window_in_days = 10
}

resource "aws_s3_bucket" "mybucket" {
 bucket = "mybucket"

 server_side_encryption_configuration {
   rule {
     apply_server_side_encryption_by_default {
       kms_master_key_id = "${aws_kms_key.mykey.arn}"
       sse_algorithm     = "aws:kms"
     }
   }
 }
}

Somit werden die Tests von ALLES in Ihrer Organisation verstanden. Hier können Sie das Schreiben dieser Tests an einen Sicherheitsdienst oder an Entwickler mit ausreichenden Sicherheitskenntnissen delegieren. Mit diesem Tool können Sie auch BDD-Dateien in einem anderen Repository speichern. Dies hilft dabei, die Verantwortung zu differenzieren, wenn Änderungen am Code und Änderungen an den Sicherheitsrichtlinien, die Ihrem Code zugeordnet sind, zwei verschiedene Einheiten sind. Dies können verschiedene Teams mit unterschiedlichen Lebenszyklen sein. Erstaunlich, oder? Zumindest für mich war es das.

Weitere Informationen zur Terraform-Konformität finden Sie in dieser Präsentation .

Wir haben viele Probleme mit der Einhaltung von Terraforms gelöstDies gilt insbesondere dann, wenn Sicherheitsdienste von den Entwicklungsteams weit entfernt sind und möglicherweise nicht verstehen, was die Entwickler tun. Sie raten bereits, was in solchen Organisationen passiert. Normalerweise beginnt der Sicherheitsdienst, alles zu blockieren, was für sie verdächtig ist, und baut ein Sicherheitssystem auf, das auf der Sicherheit des Perimeters basiert. Oh Gott ...

In vielen Situationen hat die Verwendung von Terraform und Terraform-Compliance für Teams, die die Infrastruktur entwerfen (oder / und begleiten), dazu beigetragen, dass diese beiden unterschiedlichen Teams am selben Tisch sitzen. Wenn Ihr Sicherheitsteam anfängt, etwas mit sofortigem Feedback von allen Entwicklungspipelines zu entwickeln, bekommt es normalerweise die Motivation, immer mehr zu tun. Normalerweise ...

Wenn wir Terraform verwenden, strukturieren wir Git-Repositorys daher wie folgt:



Natürlich ist dies ziemlich arrogant. Aber ich hatte Glück (oder nicht Glück?), In mehreren Organisationen mit einer detaillierteren Struktur zu arbeiten. Leider endete das alles nicht sehr gut. Das Happy End sollte in Nummer 3 versteckt sein.

Lassen Sie mich wissen, wenn Sie Erfolgsgeschichten mit Mikro-Repositories haben, ich bin wirklich interessiert!



Wir laden Sie zu einer kostenlosen Lektion ein, in der wir die Komponenten einer zukünftigen Infrastrukturplattform betrachten und sehen, wie unsere Anwendung korrekt bereitgestellt wird .

All Articles