Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Contoh makro pengganti string sederhana
Contoh berikut memandu Anda melalui proses menggunakan makro, dari mendefinisikan makro dalam template, hingga membuat fungsi Lambda untuk makro, dan kemudian menggunakan makro dalam template.
Dalam contoh ini, kita membuat makro sederhana yang menyisipkan string yang ditentukan di tempat konten target yang ditentukan dalam templat yang diproses. Kemudian kita akan menggunakannya untuk menyisipkan WaitHandleCondition
kosong di lokasi yang ditentukan dalam templat yang diproses.
Membuat makro
Sebelum menggunakan makro, pertama-tama kita harus menyelesaikan dua hal: membuat fungsi Lambda yang melakukan pemrosesan template yang diinginkan, dan kemudian membuat fungsi Lambda itu tersedia dengan membuat definisi CloudFormation makro.
Contoh template berikut berisi definisi untuk contoh makro kita. Untuk membuat makro tersedia secara spesifik Akun AWS, buat tumpukan dari template. Definisi makro menentukan nama makro, deskripsi singkat, dan referensi fungsi Lambda ARN yang CloudFormation dipanggil ketika makro ini digunakan dalam template. (Kami belum menyertakan LogRoleARN
properti LogGroupName
atau untuk pencatatan kesalahan.)
Dalam contoh ini, asumsikan bahwa tumpukan yang dibuat dari template ini diberi namaJavaMacroFunc
. Karena Name
properti makro diatur ke nama tumpukan, makro yang dihasilkan dinamai JavaMacroFunc
juga.
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'
Menggunakan makro
Untuk menggunakan makro kami, kami memasukkannya ke dalam template menggunakan fungsi Fn::Transform
intrinsik.
Ketika kita membuat tumpukan menggunakan template di bawah ini, CloudFormation memanggil contoh makro kita. Fungsi Lambda yang mendasari menggantikan satu string tertentu dengan string lain yang ditentukan. Dalam hal ini, hasilnya kosong AWS::CloudFormation::WaitConditionHandle
dimasukkan ke dalam template yang diproses.
Parameters: ExampleParameter: Type: String Default: 'SampleMacro' Resources: 2a: Fn::Transform: Name: "JavaMacroFunc" Parameters: replacement: 'AWS::CloudFormation::WaitConditionHandle' target: '$$REPLACEMENT$$' Type: '$$REPLACEMENT$$'
-
Makro untuk memanggil ditentukan sebagai
JavaMacroFunc
, yang berasal dari contoh definisi makro sebelumnya. -
Makro melewati dua parameter,
target
danreplacement
, yang mewakili string target dan nilai penggantian yang diinginkan. -
Makro dapat beroperasi pada konten simpul
Type
karena merupakanType
saudara dari fungsiFn::Transform
yang mereferensikan makro. -
Hasilnya
AWS::CloudFormation::WaitConditionHandle
dinamai2a
. -
Template juga berisi parameter template,
ExampleParameter
, yang juga dapat diakses oleh makro (tetapi tidak digunakan dalam hal ini).
Data masukan Lambda
Saat CloudFormation memproses contoh template kami selama pembuatan tumpukan, ia meneruskan pemetaan peristiwa berikut ke fungsi Lambda yang direferensikan dalam JavaMacroFunc
definisi makro.
-
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" }
fragment
berisi JSON mewakili fragmen template yang dapat diproses oleh makro. Fragmen ini terdiri dari saudara dari panggilan fungsi Fn::Transform
, tetapi bukan fungsi panggilan itu sendiri. Juga, params
berisi JSON mewakili parameter makro. Dalam hal ini, penggantian dan target. Demikian pula, templateParameterValues
berisi JSON mewakili parameter yang ditentukan untuk template secara keseluruhan.
Kode fungsi Lambda
Berikut ini adalah kode aktual untuk fungsi Lambda yang mendasari JavaMacroFunc
contoh makro. Ini mengulangi fragmen templat yang disertakan dalam respons (baik dalam format string, daftar, maupun peta), mencari string target yang ditentukan. Jika menemukan string target yang ditentukan, fungsi Lambda menggantikan string target dengan string pengganti yang ditentukan. Jika tidak, fungsi membiarkan fragmen template tidak berubah. Kemudian, fungsi mengembalikan peta properti yang diharapkan, dibahas secara rinci di bawah ini, ke CloudFormation.
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; } }
Respon fungsi Lambda
Berikut ini adalah pemetaan yang fungsi Lambda kembali CloudFormation untuk diproses.
-
requestId
:5dba79b5-f117-4de0-9ce4-d40363bfb6ab
-
status
:SUCCESS
-
fragment
:{ "Type": "AWS::CloudFormation::WaitConditionHandle" }
requestId
Pencocokan yang dikirim dari CloudFormation, dan status
nilai SUCCESS
menunjukkan bahwa fungsi Lambda berhasil memproses fragmen template yang disertakan dalam permintaan. Dalam tanggapan ini, fragment
berisi JSON mewakili konten untuk dimasukkan ke dalam template yang diproses sebagai pengganti cuplikan template asli.
Template yang diproses yang dihasilkan
Setelah CloudFormation menerima respons yang berhasil dari fungsi Lambda, ia menyisipkan fragmen template yang dikembalikan ke dalam template yang diproses.
Di bawah ini adalah templat yang diproses yang dihasilkan untuk contoh kita. Panggilan fungsi Fn::Transform
intrinsik yang mereferensikan JavaMacroFunc
makro tidak lagi disertakan. Fragmen template yang dikembalikan oleh fungsi Lambda disertakan di lokasi yang sesuai, dengan hasil bahwa "Type": "$$REPLACEMENT$$"
konten telah diganti. "Type": "AWS::CloudFormation::WaitConditionHandle"
{ "Parameters": { "ExampleParameter": { "Default": "SampleMacro", "Type": "String" } }, "Resources": { "2a": { "Type": "AWS::CloudFormation::WaitConditionHandle" } } }