Terraform: Richtige Methode zum Anhängen von verwalteten AWS-Richtlinien an eine Rolle?

76

Ich möchte eine der bereits vorhandenen AWS-verwalteten Rollen an eine Richtlinie anhängen. Hier ist mein aktueller Code:

resource "aws_iam_role_policy_attachment" "sto-readonly-role-policy-attach" {
  role       = "${aws_iam_role.sto-test-role.name}"
  policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}

Gibt es eine bessere Möglichkeit, die verwaltete Richtlinie zu modellieren und dann zu referenzieren, anstatt die ARN fest zu codieren? Es scheint nur so, als ob ich immer dann, wenn ich ARNs / Pfade oder ähnliches fest codiere, später herausfinde, dass es einen besseren Weg gibt.

Gibt es in Terraform bereits etwas, das verwaltete Richtlinien modelliert? Oder ist das Hardcodieren des ARN der "richtige" Weg, dies zu tun?

Geschoren
quelle
7
Ja, Hardcore mit bereits vorhandenen AWS-verwalteten Rollen ist der richtige Weg. Andernfalls können Sie die ähnliche Richtlinie definieren und anhängen.
BMW

Antworten:

115

Die IAM-Richtliniendatenquelle ist hierfür hervorragend geeignet. Eine Datenressource wird verwendet, um Daten oder Ressourcen zu beschreiben, die nicht aktiv von Terraform verwaltet werden, auf die Terraform jedoch verweist.

In Ihrem Beispiel würden Sie eine Datenressource für die verwaltete Richtlinie wie folgt erstellen:

data "aws_iam_policy" "ReadOnlyAccess" {
  arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}

Der Name der Datenquelle liegt ReadOnlyAccessin diesem Fall ganz bei Ihnen. Für verwaltete Richtlinien verwende ich aus Gründen der Konsistenz denselben Namen wie den Richtliniennamen, aber Sie können ihn genauso einfach benennen, readonlywenn dies zu Ihnen passt.

Sie würden dann die IAM-Richtlinie wie folgt an Ihre Rolle anhängen:

resource "aws_iam_role_policy_attachment" "sto-readonly-role-policy-attach" {
  role       = "${aws_iam_role.sto-test-role.name}"
  policy_arn = "${data.aws_iam_policy.ReadOnlyAccess.arn}"
}
Jorelli
quelle
1
Es gibt eine service-linkedRolle, zum Beispiel die Stichprobe arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole. Eine Feature-Anfrage wurde bereits von jemandem gestellt: github.com/terraform-providers/terraform-provider-aws/issues/…
Bill
1
Sie können die ARN in eine Zeile mit nur einem Block für den Anhang einfügen: Ressource "aws_iam_role_policy_attachment" "sto-readonly-role-policy-attach" {role = "$ {aws_iam_role.sto-test-role.name}" policy_arn = " arn: aws: iam :: aws: policy / ReadOnlyAccess "}
Arcones
1
Ich kann bestätigen, dass es funktioniert mitAWSLambdaVPCAccessExecutionRole
Daniel
1
Können Sie bitte erklären, warum dies besser ist, als die Arne fest zu codieren aws_iam_role_policy_attachment? Sie codieren es in beiden Fällen fest.
Ikar Pohorský
3
@ IkarPohorský es macht keinen Unterschied für Ihre Infrastruktur, aber es macht einen Unterschied für Werkzeuge, die auf Terraform aufgebaut sind. Wenn Sie ein Datenobjekt erstellen, wird die Abhängigkeit zusammen mit all Ihren anderen Ressourcen in Terraform verfolgt. Intern erstellt Terraform ein Diagramm Ihrer Infrastruktur. Sie können dieses Diagramm mit sichern terraform graph. Das Datenobjekt wird in der Ausgabe angezeigt, wenn es als Datenabhängigkeit verfolgt wird, nicht jedoch, wenn Sie eine Zeichenfolge fest codieren. Wenn Sie GraphViz installiert haben, visualisieren Sie es mit terraform graph | dot -Tsvg > graph.svg.
Jorelli
14

Wenn Sie Werte verwenden, die Terraform selbst nicht direkt verwaltet, haben Sie einige Optionen.

Die erste, einfachste Option besteht darin, den Wert wie hier fest zu codieren. Dies ist eine einfache Antwort, wenn Sie erwarten, dass sich der Wert niemals ändert. Da diese "vordefinierten Richtlinien" dokumentiert sind, entsprechen die integrierten AWS-Funktionen wahrscheinlich diesen Kriterien.

Die zweite Option ist es, ein Modul Terraform und Festcode den Wert in zu schaffen , dass , und dann dieses Modul aus mehreren anderen Modulen verweisen. Auf diese Weise können Sie den Wert zentral verwalten und mehrfach verwenden. Ein Modul, das nur Ausgaben enthält, ist ein gängiges Muster für diese Art von Dingen. Sie können jedoch auch ein Modul erstellen, das eine aws_iam_role_policy_attachmentRessource mit der aus einer Variablen festgelegten Rolle enthält .

Die dritte Option besteht darin, den Wert an einer Stelle zu platzieren, von der Terraform Werte abrufen kann, z. B. Consul, und ihn dann mithilfe einer Datenquelle von dort abzurufen. Wenn nur Terraform im Spiel ist, entspricht dies weitgehend der zweiten Option. Dies bedeutet jedoch, dass Terraform sie bei jeder Aktualisierung erneut liest und nicht nur, wenn Sie das Modul mit aktualisieren. terraform init -upgradeDies könnte daher eine bessere Option für Werte sein, die dies tun oft ändern.

Die vierte Option besteht darin, eine spezielle Datenquelle zu verwenden, die den Wert direkt aus der Quelle der Wahrheit lesen kann. Terraform verfügt derzeit nicht über eine Datenquelle zum Abrufen von Informationen zu verwalteten AWS-Richtlinien. Dies ist daher keine Option für Ihre aktuelle Situation, kann jedoch zum Abrufen anderer AWS-definierter Daten wie AWS-IP-Adressbereiche, Service-ARNs usw. Verwendet werden .

Welche davon für eine bestimmte Situation geeignet ist, hängt davon ab, wie häufig sich der Wert ändert, wer Änderungen daran verwaltet und ob spezielle Terraform-Datenquellen verfügbar sind.

Martin Atkins
quelle