Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Makrobeispiel: Erstellen und Verwenden eines Makros
Im folgenden Beispiel werden Sie durch die Verwendung von Makros geführt – von der Definition des Makros in einer Vorlage über die Erstellung einer Lambda-Funktion für das Makro bis hin zur Verwendung des Makros in einer Vorlage.
In diesem Beispiel erstellen wir ein einfaches Makro, das die angegebene Zeichenfolge anstelle des angegebenen Zielinhalts in die verarbeitete Vorlage einfügt. Dann fügen wir damit ein leeres WaitHandleCondition
an der angegebenen Stelle in der bearbeiteten Vorlage ein.
Makro-Beispiel: Makro-Definitionsvorlage
Bevor wir ein Makro verwenden, müssen wir zunächst zwei Dinge tun: die Lambda-Funktion erstellen, die die gewünschte Vorlagenverarbeitung durchführt, und dann diese Lambda-Funktion durch Erstellen einer Makrodefinition für CloudFormation zur Verfügung stellen.
Anmerkung
Wir werden den aktuellen Code für die Lambda-Funktion später in diesem Thema untersuchen.
Die folgende Beispielvorlage enthält die Definition für unser Beispielmakro. Um das Makro in einem bestimmten CloudFormation-Konto verfügbar zu machen, erstellen wir einen Stack aus der Vorlage. Die Makrodefinition gibt den Makronamen, eine Kurzbeschreibung und Verweise auf den ARN der Lambda-Funktion an, die CloudFormation aufruft, wenn dieses Makro in einer Vorlage verwendet wird. (Wir haben keine LogGroupName- oder LogRoleARN-Eigenschaft für die Fehlerprotokollierung aufgenommen.) Weitere Informationen finden Sie unter AWS::CloudFormation::Macro.
In diesem Beispiel gehen wir davon aus, dass der aus dieser Vorlage erstellte Stack den Namen JavaMacroFunc trägt. Da die Makro-Eigenschaft Name
auf den Stack-Namen festgelegt ist, wird das resultierende Makro ebenfalls JavaMacroFunc heißen.
AWSTemplateFormatVersion: 2010-09-09 Resources: Macro: Type: AWS::CloudFormation::Macro Properties: Name:
!Sub '${AWS::StackName}'
Description:Adds a blank WaitConditionHandle named 'WaitHandle'
FunctionName:"arn:aws:lambda:us-east-1:012345678910:function:JavaMacroFunc"
Makro-Beispiel: Makro-Verwendungsvorlage
Um unser Makro in diesem Fall zu verwenden, werden wir es mit der intrinsischen Fn::Transform-Funktion in eine Vorlage aufnehmen.
Wenn wir einen Stack mit der untenstehenden Vorlage erstellen, ruft CloudFormation unser Beispielmakro auf. Die zugrundeliegende Lambda-Funktion ersetzt eine angegebene Zeichenfolge durch eine andere angegebene Zeichenfolge. In diesem Fall wird als Ergebnis ein leerer AWS::CloudFormation::WaitConditionHandle in die verarbeitete Vorlage eingefügt.
Beachten Sie Folgendes:
-
Das aufzurufende Makro wird als JavaMacroFunc angegeben, was dem vorherigen Beispiel für Makrodefinitionen entspricht.
-
Dem Makro werden zwei Parameter,
target
undreplacement
, übergeben, die die Zielzeichenfolge und ihren gewünschten Ersatzwert darstellen. Das Makro kann auf den Inhalt des
Type
-Knotens zugreifen, daType
ein Geschwisterelement derFn::Transform
-Funktion ist, das sich auf das Makro bezieht.Der resultierende AWS::CloudFormation::WaitConditionHandle heißt
2a
.Die Vorlage enthält auch einen Vorlagenparameter (
ExampleParameter
), auf den das Makro ebenfalls Zugriff hat (in diesem Fall aber nicht verwendet wird).
Parameters: ExampleParameter: Type: String Default: 'SampleMacro' Resources: 2a: Fn::Transform: Name: "JavaMacroFunc" Parameters: replacement: 'AWS::CloudFormation::WaitConditionHandle' target: '$$REPLACEMENT$$' Type: '$$REPLACEMENT$$'
Makro-Beispiel: Ereigniszuweisung anfordern
Wenn CloudFormation unsere Beispielvorlage während der Stack-Erstellung verarbeitet, übergibt es die folgende Ereigniszuordnung an die Lambda-Funktion, auf die in der Makrodefinition JavaMacroFunc verwiesen wird.
fragment
enthält JSON, das das Vorlagenfragment darstellt, das das Makro verarbeiten kann. Dieses Fragment besteht aus den Geschwistern des Fn::Transform
-Funktionsaufrufs, nicht aber aus dem Funktionsaufruf selbst. Außerdem enthält params
JSON, das die Makroparameter repräsentiert. In diesem Fall Ersatz und Ziel. Ebenso enthält templateParameterValues
JSON, das die für die gesamte Vorlage angegebenen Parameter repräsentiert.
region
us-east-1
accountId
012345678910
fragment
{ "Type": "$$REPLACEMENT$$" }
transformId
012345678910::JavaMacroFunc
params
{ "replacement": "AWS::CloudFormation::WaitConditionHandle", "target": "$$REPLACEMENT$$" }
requestId
5dba79b5-f117-4de0-9ce4-d40363bfb6ab
templateParameterValues
{ "ExampleParameter": "SampleMacro" }
Makro-Beispiel: Lambda-Funktionscode
Es folgt der aktuelle Code für die Lambda-Funktion, die dem Beispielmakro JavaMacroFunc zugrundeliegt. Es durchläuft das in der Antwort enthaltene Vorlagenfragment (als Zeichenfolge, Liste oder Zuordnung) und sucht nach der angegebenen Zielzeichenfolge. Wenn die angegebene Zeichenfolge gefunden wird, ersetzt die Lambda-Funktion die Zielzeichenfolge durch die angegebene Ersatzzeichenfolge. Wenn nicht, lässt die Funktion das Vorlagenfragment unverändert. Anschließend gibt die Funktion eine Zuordnung der erwarteten Eigenschaften an CloudFormation zurück, die im Folgenden ausführlich erläutert wird.
package com.macroexample.lambda.demo; import java.util.List; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; public class LambdaFunctionHandler implements RequestHandler<Map<String, Object>, Map<String, Object>> { private static final String REPLACEMENT = "replacement"; private static final String TARGET = "target"; private static final String PARAMS = "params"; private static final String FRAGMENT = "fragment"; private static final String REQUESTID = "requestId"; private static final String STATUS = "status"; private static final String SUCCESS = "SUCCESS"; private static final String FAILURE = "FAILURE"; @Override public Map<String, Object> handleRequest(Map<String, Object> event, Context context) { // TODO: implement your handler final Map<String, Object> responseMap = new HashMap<String, Object>(); responseMap.put(REQUESTID, event.get(REQUESTID)); responseMap.put(STATUS, FAILURE); try { if (!event.containsKey(PARAMS)) { throw new RuntimeException("Params are required"); } final Map<String, Object> params = (Map<String, Object>) event.get(PARAMS); if (!params.containsKey(REPLACEMENT) || !params.containsKey(TARGET)) { throw new RuntimeException("replacement or target under Params are required"); } final String replacement = (String) params.get(REPLACEMENT); final String target = (String) params.get(TARGET); final Object fragment = event.getOrDefault(FRAGMENT, new HashMap<String, Object>()); final Object retFragment; if (fragment instanceof String) { retFragment = iterateAndReplace(replacement, target, (String) fragment); } else if (fragment instanceof List) { retFragment = iterateAndReplace(replacement, target, (List<Object>) fragment); } else if (fragment instanceof Map) { retFragment = iterateAndReplace(replacement, target, (Map<String, Object>) fragment); } else { retFragment = fragment; } responseMap.put(STATUS, SUCCESS); responseMap.put(FRAGMENT, retFragment); return responseMap; } catch (Exception e) { e.printStackTrace(); context.getLogger().log(e.getMessage()); return responseMap; } } private Map<String, Object> iterateAndReplace(final String replacement, final String target, final Map<String, Object> fragment) { final Map<String, Object> retFragment = new HashMap<String, Object>(); final List<String> replacementKeys = new ArrayList<>(); fragment.forEach((k, v) -> { if (v instanceof String) { retFragment.put(k, iterateAndReplace(replacement, target, (String)v)); } else if (v instanceof List) { retFragment.put(k, iterateAndReplace(replacement, target, (List<Object>)v)); } else if (v instanceof Map ) { retFragment.put(k, iterateAndReplace(replacement, target, (Map<String, Object>) v)); } else { retFragment.put(k, v); } }); return retFragment; } private List<Object> iterateAndReplace(final String replacement, final String target, final List<Object> fragment) { final List<Object> retFragment = new ArrayList<>(); fragment.forEach(o -> { if (o instanceof String) { retFragment.add(iterateAndReplace(replacement, target, (String) o)); } else if (o instanceof List) { retFragment.add(iterateAndReplace(replacement, target, (List<Object>) o)); } else if (o instanceof Map) { retFragment.add(iterateAndReplace(replacement, target, (Map<String, Object>) o)); } else { retFragment.add(o); } }); return retFragment; } private String iterateAndReplace(final String replacement, final String target, final String fragment) { System.out.println(replacement + " == " + target + " == " + fragment ); if (fragment != null AND_AND fragment.equals(target)) return replacement; return fragment; } }
Makro-Beispiel: Lambda-Funktionsantwort
Es folgt die Zuweisung, welche die Lambda-Funktion zur Verarbeitung an AWS CloudFormation zurückgibt. Die requestId
stimmt mit der von CloudFormation gesendeten überein und ein status
-Wert von SUCCESS
bedeutet, dass die Lambda-Funktion das in der Anfrage enthaltene Vorlagenfragment erfolgreich verarbeitet hat. In dieser Antwort enthält fragment
JSON, das den Inhalt darstellt, der anstelle des ursprünglichen Vorlagenausschnitts in die verarbeitete Vorlage eingefügt werden soll.
requestId
5dba79b5-f117-4de0-9ce4-d40363bfb6ab
status
SUCCESS
fragment
{ "Type": "AWS::CloudFormation::WaitConditionHandle" }
Makro-Beispiel: Resultierende verarbeitete Vorlage
Nachdem CloudFormation eine erfolgreiche Antwort von der Lambda-Funktion erhalten hat, fügt es das zurückgegebene Vorlagenfragment in die bearbeitete Vorlage ein.
Nachfolgend sehen Sie die resultierende verarbeitete Vorlage für unser Beispiel. Der intrinsische Fn::Transform
-Funktionsaufruf, der auf das Makro JavaMacroFunc verweist, ist nicht mehr enthalten. Das von der Lambda-Funktion zurückgegebene Vorlagenfragment wird an der entsprechenden Stelle eingefügt, sodass der Inhalt "Type": "$$REPLACEMENT$$"
durch "Type":
"AWS::CloudFormation::WaitConditionHandle"
ersetzt wurde.
{ "Parameters": { "ExampleParameter": { "Default": "SampleMacro", "Type": "String" } }, "Resources": { "2a": { "Type": "AWS::CloudFormation::WaitConditionHandle" } } }
Weitere Makro-Beispiele
Zusätzlich zum Walkthrough in diesem Handbuch finden Sie Beispielmakros, einschließlich Quellcode und Vorlagen, im Abschnitt Makro-Beispiele