Nei*_*eil 6 amazon-web-services aws-cloudformation aws-lambda
我有用Java编写的AWS Lambda函数,我想将其用作对AWS CloudFormation函数的响应的一部分.Amazon提供了两个关于如何创建CloudFormation自定义资源的详细示例,该资源根据Node.js编写的AWS Lambda函数返回其值,但是我一直难以将Lambda示例转换为Java.我们如何设置我们的AWS Java函数,以便它从CloudFormation读取作为参数传递给Lambda函数的预签名S3 URL的值,并将所需的响应发送回等待的CloudFormation模板?
在与AWS进行来回对话之后,以下是我创建的一些代码示例.
首先,假设您想利用预定义的接口来创建处理程序,您可以实现RequestsHandler并定义HandleRequest方法,如下所示:
public class MyCloudFormationResponder implements RequestHandler<Map<String, Object>, Object>{
public Object handleRequest(Map<String,Object> input, Context context) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
这Map<String, Object>是从CloudFormation资源发送到Lambda函数的值的映射.示例CF资源:
"MyCustomResource": {
"Type" : "Custom::String",
"Version" : "1.0",
"Properties": {
"ServiceToken": "arn:aws:lambda:us-east-1:xxxxxxx:function:MyCloudFormationResponderLambdaFunction",
"param1": "my value1",
"param2": ["t1.micro", "m1.small", "m1.large"]
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用以下代码进行分析
String responseURL = (String)input.get("ResponseURL");
context.getLogger().log("ResponseURLInput: " + responseURL);
context.getLogger().log("StackId Input: " + input.get("StackId"));
context.getLogger().log("RequestId Input: " + input.get("RequestId"));
context.getLogger().log("LogicalResourceId Context: " + input.get("LogicalResourceId"));
context.getLogger().log("Physical Context: " + context.getLogStreamName());
@SuppressWarnings("unchecked")
Map<String,Object> resourceProps = (Map<String,Object>)input.get("ResourceProperties");
context.getLogger().log("param 1: " + resourceProps.get("param1"));
@SuppressWarnings("unchecked")
List<String> myList = (ArrayList<String>)resourceProps.get("param2");
for(String s : myList){
context.getLogger().log(s);
}
Run Code Online (Sandbox Code Playgroud)
除了AWS文档中的NodeJS示例中解释的内容之外,这里要指出的关键事项是
(String)input.get("ResponseURL") 是您需要回复的预先签名的S3 URL(稍后会详细介绍)(Map<String,Object>)input.get("ResourceProperties")返回从CF模板传递到Lambda函数的CloudFormation自定义资源"Properties"的映射.我提供了一个String和ArrayList作为可以返回的对象类型的两个示例,尽管其他几个是可能的为了响应CloudFormation模板自定义资源实例化,您需要执行HTTP PUT回调到之前提到的ResponseURL,并在变量中包含以下大部分字段cloudFormationJsonResponse.以下是我如何做到这一点
try {
URL url = new URL(responseURL);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
JSONObject cloudFormationJsonResponse = new JSONObject();
try {
cloudFormationJsonResponse.put("Status", "SUCCESS");
cloudFormationJsonResponse.put("PhysicalResourceId", context.getLogStreamName());
cloudFormationJsonResponse.put("StackId", input.get("StackId"));
cloudFormationJsonResponse.put("RequestId", input.get("RequestId"));
cloudFormationJsonResponse.put("LogicalResourceId", input.get("LogicalResourceId"));
cloudFormationJsonResponse.put("Data", new JSONObject().put("CFAttributeRefName", "some String value useful in your CloudFormation template"));
} catch (JSONException e) {
e.printStackTrace();
}
out.write(cloudFormationJsonResponse.toString());
out.close();
int responseCode = connection.getResponseCode();
context.getLogger().log("Response Code: " + responseCode);
} catch (IOException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
特别值得注意的是上面的节点"数据"引用了一个附加节点com.amazonaws.util.json.JSONObject,其中我包含了我的CloudFormation模板中所需的任何属性.在这种情况下,它将在CF模板中检索,例如{ "Fn::GetAtt": [ "MyCustomResource", "CFAttributeRefName" ] }
最后,你可以简单地return null从因为它HTTPUrlConnection实际上响应CF调用而没有从这个函数返回任何内容.
| 归档时间: |
|
| 查看次数: |
2990 次 |
| 最近记录: |