Skip to main content

AWS-AMI-IDs in Terraform mit Regula und Open Policy Agent überprüfen

Artikel von
blog hero iac drift purple

7. Oktober 2021

0 Min. Lesezeit

Letzte Woche haben wir Fugue IaC angekündigt. Damit können Cloud-Engineering-Teams ihre Infrastructure as Code (IaC) und Cloud-Runtime-Umgebungen mit denselben Richtlinien schützen. Für lokale IaC-Prüfungen hat Fugue Regula entwickelt, ein Open-Source-Tool auf Basis von Open Policy Agent (OPA).

Regula lässt sich mit oder ohne Fugue verwenden. Das Tool umfasst Hunderte sofort einsatzbereite Regeln, mit denen Terraform- und CloudFormation-Infrastructure-as-Code (IaC) sowie Kubernetes-Manifeste geprüft werden. Die Regeln sind den CIS Benchmarks zugeordnet und decken zahlreiche Sicherheitslücken ab.

Manchmal möchten Sie jedoch organisationsspezifische Richtlinien durchsetzen – zum Beispiel, dass Amazon EC2-Instanzen nur genehmigte AMIs verwenden. In solchen Fällen können Sie mit der OPA-Sprache Rego eine benutzerdefinierte Regel schreiben, die Regula auf Ihre IaC anwendet. Wenn Ihre IaC dann ein nicht genehmigtes AMI festlegt, schlägt die Regula-Prüfung fehl.

In diesem Blogbeitrag:

  • Wir schreiben eine benutzerdefinierte Regel, um in Terraform deklarierte AWS-EC2-AMIs zu prüfen, und erläutern den Rego-Code Zeile für Zeile.

  • Wir testen die Regel mit unserem Open-Source-Tool Regula anhand einer nicht konformen Terraform-Datei.

  • Wir korrigieren das nicht konforme Terraform.

Beachten Sie: In diesem Blogbeitrag verwenden wir Regula für die Prüfung von Terraform-HCL. Sie können dieselbe benutzerdefinierte Regel aber auch mit der Fugue-SaaS-Lösung verwenden, um Cloud-Runtime-Ressourcen zu prüfen. Möglich macht dies Fugues Unified Policy Engine, die dieselben Regeln für IaC und Runtime unterstützt.

Den gesamten Code finden Sie in diesem GitHub-Gist.

Los geht's!

Erste Schritte

Codedateien herunterladen

Wählen Sie in unserem GitHub-Gist die Schaltfläche „Download ZIP“ und entpacken Sie anschließend die Dateien. Es gibt zwei Dateien:

  • approved_ami.rego – eine benutzerdefinierte Regel in Rego

  • ami.tf – eine Terraform-HCL-Datei, in der zwei EC2-Instanzen deklariert sind: eine konforme und eine nicht konforme

Regula installieren

Als Nächstes installieren Sie Regula, falls Sie das noch nicht getan haben. Homebrew-Nutzer können die folgenden Befehle im Terminal ausführen:

brew tap fugue/regula
brew install regula

Alternativ können Sie eine vorkompilierte Binärdatei für Ihre Plattform installieren oder Regula mit Docker ausführen.

Die benutzerdefinierte Regel schreiben

Zunächst legen wir fest, welche Art von Regel wir schreiben. In Regula gibt es zwei Regeltypen: einfache und erweiterte Regeln. Einfache Regeln eignen sich, wenn Sie einen einzelnen Ressourcentyp prüfen. Erweiterte Regeln sind besser für komplexere Logik, die mehrere Ressourcen umfasst oder auf fehlende Ressourcen prüft.

Wir prüfen nur einen Terraform-Ressourcentyp, aws_instance, und schreiben daher eine einfache Regel.

Paketdeklaration

Beginnen wir mit den Grundlagen. Alle Regula-Regeln müssen eine Paketdeklaration enthalten, die mit rules. beginnt und mit einer kurzen Kennung endet (Zeile 4):

package rules.approved_ami

Metadaten

Optional können wir Metadaten hinzufügen (Zeilen 6–18):

__rego__metadoc__ := {
  "id": "CUSTOM_0002",
  "title": "AWS EC2 instances must use approved AMIs",
  "description": "Per company policy, EC2 instances may only use AMI IDs from a pre-approved list",
  "custom": {
    "controls": {
      "CORPORATE-POLICY": [
        "CORPORATE-POLICY_1.2"
      ]
    },
    "severity": "High"
  }
}

Das ist zwar nicht erforderlich, macht die Berichtsausgabe von Regula aber noch informativer.

Ressourcentyp

Als Nächstes geben wir an, welchen Terraform-Ressourcentyp wir prüfen möchten (Zeile 20):

resource_type = "aws_instance"

Diese Syntax bedeutet, dass die Eingabe eine einzelne AWS-EC2-Instanz ist. Wenn Regula die Regel auf unser Terraform anwendet, prüft es jeweils eine einzelne Instanz.

Genehmigte AMIs

Der Einfachheit halber nehmen wir an, dass Ihr Unternehmen die folgenden beiden AMI-IDs genehmigt hat:

  • ami-09e67e426f25ce0d7

  • ami-03d5c68bab01f3496

(Falls Sie neugierig sind: Dies sind die IDs für Ubuntu Server 20.04 LTS HVM, SSD Volume Type in us-east-1 beziehungsweise us-west-2.)

Nun erstellen wir ein Set mit den genehmigten AMI-IDs. Wir nennen es approved_amis (Zeilen 22–26):

approved_amis = {
  # Ubuntu Server 20.04 LTS (HVM), SSD Volume Type
  "ami-09e67e426f25ce0d7", # us-east-1
  "ami-03d5c68bab01f3496" # us-west-2 
}

Die deny-Regel

Zum Schluss schreiben wir eine deny-Regel. Hier steckt die Hauptlogik! Die deny-Regel legt fest, unter welchen Bedingungen eine Ressource die Prüfung nicht besteht.

Wir gehen hier noch einen Schritt weiter und geben eine benutzerdefinierte Fehlermeldung aus, die die nicht genehmigte AMI-ID aufführt, wenn eine Instanz die Regula-Prüfung nicht besteht.

Unsere deny-Regel soll prüfen, ob die AMI-ID der gerade bewerteten Instanz im genehmigten Set enthalten ist. Ist dies nicht der Fall, soll deny eine Fehlermeldung für diese Ressource zurückgeben (also ein negatives Regelergebnis erzeugen). deny ist in Zeilen 28–31 definiert:

deny[msg] {
  not approved_amis[input.ami]
  msg = sprintf("%s is not an approved AMI ID", [input.ami])
}

Sehen wir uns die Logik genauer an:

not approved_amis[input.ami]

input.ami steht für das Attribut ami jeder EC2-Instanz im Eingabedokument (Ihrer Terraform-HCL-Datei – genauer gesagt einer JSON-Darstellung, die Regula im Hintergrund erstellt).

not approved_amis[input.ami] ergibt true, wenn das Attribut ami der aktuellen Instanz kein Mitglied des Sets ist.

Zusammengefasst besagt die deny-Regel: „Wenn input.ami nicht in approved_amis enthalten ist, schlägt die Regula-Prüfung fehl und gibt eine Fehlermeldung zurück.“

Die Fehlermeldung definieren wir in dieser Zeile:

msg = sprintf("%s is not an approved AMI ID", [input.ami])

Hier wird die integrierte Rego-Funktion sprintf verwendet, um das ami der gerade bewerteten Ressource auszugeben.

Damit ist unsere benutzerdefinierte Regel fertig! Hier sehen Sie den vollständigen Code. Jetzt probieren wir Regula aus!

Die benutzerdefinierte Regel mit Regula ausführen

Testen wir die Regel nun mit einer einfachen Terraform-Datei. Die Terraform-HCL-Datei in unserem GitHub-Gist definiert zwei EC2-Instanzen: eine „gute“ Instanz mit der genehmigten AMI-ID ami-09e67e426f25ce0d7 und eine „schlechte“ Instanz mit der überhaupt nicht verdächtigen AMI-ID ami-totallylegitamiid.

Regula ausführen

Wechseln Sie in Ihrem Terminal mit cd in das Verzeichnis mit den Codedateien und führen Sie den folgenden Befehl aus:

regula run ami.tf --include approved_ami.rego --user-only

Mit diesem Befehl wird unsere benutzerdefinierte Regel auf die Terraform-Datei angewendet. Das Flag --user-only gibt an, dass nur die benutzerdefinierte Regel ausgeführt werden soll. Für diesen Blogbeitrag lassen wir die Bibliothek integrierter Regeln von Regula außen vor. (Es empfiehlt sich allerdings, die standardmäßig enthaltenen integrierten Regeln zu verwenden, die bei Ausführung von regula run automatisch angewendet werden.)

Die Ausgabe sieht folgendermaßen aus:

Terminalausgabe mit einer AWS-EC2-AMI-Richtlinienverletzung: Die AMI-ID ist nicht freigegeben.

Wie Sie sehen, hat unsere Terraform-Datei die Regelprüfung nicht bestanden. Die Meldung lautet ami-totallylegitamiid is not an approved AMI ID. Das ist ein gutes Zeichen: Unsere benutzerdefinierte Regel funktioniert! Regula hat angezeigt, dass die Instanz aws_instance.bad (Zeile 13, Spalte 1) keine genehmigte AMI-ID verwendet.

Einen ausführlicheren Bericht anzeigen

Weitere Einzelheiten finden Sie im vollständigen Bericht, der als JSON formatiert ist:

regula run ami.tf --include approved_ami.rego --user-only --format json

Hier sehen Sie die vollständige Ausgabe mit allen Regelergebnissen. Beachten Sie unten, dass aws_instance.bad erneut das Ergebnis FAIL hat, während aws_instance.good die Prüfung BESTANDEN hat:

{
  "rule_results": [
    {
      "controls": [
        "CORPORATE-POLICY_1.2"
      ],
      "filepath": "ami.tf",
      "input_type": "tf",
      "provider": "aws",
      "resource_id": "aws_instance.bad",
      "resource_type": "aws_instance",
      "rule_description": "Per company policy, EC2 instances may only use AMI IDs from a pre-approved list",
      "rule_id": "CUSTOM_0002",
      "rule_message": "ami-totallylegitamiid is not an approved AMI ID",
      "rule_name": "approved_ami",
      "rule_result": "FAIL",
      "rule_severity": "High",
      "rule_summary": "AWS EC2 instances must use approved AMIs",
      "source_location": [
        {
          "path": "ami.tf",
          "line": 13,
          "column": 1
        }
      ]
    },
    {
      "controls": [
        "CORPORATE-POLICY_1.2"
      ],
      "filepath": "ami.tf",
      "input_type": "tf",
      "provider": "aws",
      "resource_id": "aws_instance.good",
      "resource_type": "aws_instance",
      "rule_description": "Per company policy, EC2 instances may only use AMI IDs from a pre-approved list",
      "rule_id": "CUSTOM_0002",
      "rule_message": "",
      "rule_name": "approved_ami",
      "rule_result": "PASS",
      "rule_severity": "High",
      "rule_summary": "AWS EC2 instances must use approved AMIs",
      "source_location": [
        {
          "path": "ami.tf",
          "line": 8,
          "column": 1
        }
      ]
    }
  ],
  "summary": {
    "filepaths": [
      "ami.tf"
    ],
    "rule_results": {
      "FAIL": 1,
      "PASS": 1,
      "WAIVED": 0
    },
    "severities": {
      "Critical": 0,
      "High": 1,
      "Informational": 0,
      "Low": 0,
      "Medium": 0,
      "Unknown": 0
    }
  }
}

Außerdem sehen Sie die übrigen Metadaten, die wir zuvor in der Regel definiert haben.

Terraform korrigieren

Wenn Sie Terraform konform machen möchten, bearbeiten Sie ami.tf, ersetzen Sie ami-totallylegitamiid durch ami-09e67e426f25ce0d7 und führen Sie Regula erneut aus. Dieses Mal verwenden wir das standardmäßige Textformat:

regula run ami.tf --include approved_ami.rego --user-only

Die Ausgabe sieht dann so aus:

No problems found.

Geschafft! Wir haben unser Terraform-IaC abgesichert, indem wir ausschließlich genehmigte AMIs verwenden. Regula bestätigt das.

Weiterführende Informationen

In diesem Blogbeitrag haben wir eine benutzerdefinierte Regel in Rego geschrieben, sie mit Regula anhand einer Terraform-HCL-Datei geprüft und Terraform konform gemacht.

Weitere Informationen zu Regula finden Sie auf der Regula-Dokumentationsseite. Die folgenden Ressourcen könnten für Sie hilfreich sein:

IaC-Sicherheit für Entwickler

Snyk schützt Ihre Infrastructure as Code vom SDLC bis zur Laufzeit in der Cloud mit einer einheitlichen Policy-as-Code-Engine, damit jedes Team sicher entwickeln, bereitstellen und betreiben kann.

Weiterlesen

feature customer snowflake
Article

Sicherheit von Anfang an: Die Snyk Studio-Integration für Snowflake Cortex Code

Snyk Studio ist in Snowflake Cortex Code integriert und scannt KI-generierten Code, Abhängigkeiten und Container während der Entwicklung auf Schwachstellen.

Article

Miasma-Supply-Chain-Angriff: Schadcode in npm-Paketen von @redhat-cloud-services entdeckt

Der als Miasma bekannte Supply-Chain-Wurm wurde in Dutzenden npm-Releases von @redhat-cloud-services entdeckt. Der schädliche Preinstall-Hook stiehlt Zugangsdaten, sondiert Cloud-Identitäten und kann weitere Pakete erneut veröffentlichen.

Blog

Qinglong-Aufgabenplaner: RCE-Schwachstellen werden für Kryptomining ausgenutzt

Zwei Schwachstellen zur Umgehung der Authentifizierung (CVE-2026-3965, CVE-2026-4047) im Qinglong-Aufgabenplaner wurden in freier Wildbahn ausgenutzt, um Kryptomining-Malware einzuschleusen. Erfahren Sie, was passiert ist, wie die Angriffe abliefen und was Betreiber selbst gehosteter Anwendungen aus diesem Vorfall lernen sollten.