我有用Java编写的AWS Lambda函数,我想用它作为对AWS CloudFormation函数的响应的一部分。亚马逊提供two detailed examples关于如何创建CloudFormation自定义资源,该自定义资源基于Node.js中编写的AWS Lambda函数返回其值,但是我一直难以将Lambda示例转换为Java。我们如何设置我们的AWS Java函数,以便它从CloudFormation中读取作为参数传递给Lambda函数的预签名S3 URL的值,并将我们期望的响应发送回等待的CloudFormation模板?我们如何使用用Java编写的AWS Lambda函数访问和响应CloudFormation自定义资源?
回答
经过与AWS的来回对话,以下是我创建的一些代码示例来完成此操作。
首先,假设你想leverage the predefined interfaces for creating Handlers,可以实现RequestsHandler和定义的handleRequest方法,像这样:
public class MyCloudFormationResponder implements RequestHandler<Map<String, Object>, Object>{
public Object handleRequest(Map<String,Object> input, Context context) {
...
}
}
的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"]
}
}
可以用下面的代码进行分析
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);
}
关键的东西在这里指出,超出了在的NodeJS实例的AWS文档中解释的
(String)input.get("ResponseURL")
是您需要回复的预签名S3 URL(稍后会详细介绍)(Map<String,Object>)input.get("ResourceProperties")
返回从CF模板传递到Lambda函数的CloudFormation自定义资源“Properties”的映射。我提供的字符串和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();
}
尤其值得注意的是节点“数据”上面它引用的附加com.amazonaws.util.json.JSONObject
,其中包括我所需要的,我CloudFormation模板中的任何属性。在这种情况下,它会在CF模板被检索的东西,如{ "Fn::GetAtt": [ "MyCustomResource", "CFAttributeRefName" ] }
最后,你可以简单地return null
因为没有得到此功能,因为它是实际响应CF调用HTTPUrlConnection
返回。
Neil,
我真的很感谢你在这里的优秀文档。我会添加一些我认为有用的东西:
input.get(“RequestType”) - 这会返回为“创建”,“删除”等。您可以使用此值确定如何执行堆栈被创建,删除等。
就安全性而言,我上传了Lambda函数并手动设置了VPC,子网和安全组(默认),这样我就可以在多个cloudformationn脚本中重复使用它。这似乎工作正常。
我创建了一个由CF脚本调用的Lambda函数,另一个我可以在第一个失败的情况下手动运行。
这款出色的gradle aws插件可以轻松将Java Lambda函数上传到AWS。
- 1. 无法通过自定义的cloudformation资源调用lambda函数
- 2. DependsOn和Cloudformation自定义资源
- 3. 如何在Lambda函数中使用CloudFormation资源?
- 4. 如何使用S3和Slack集成编写AWS lambda函数
- 5. 让AWS Lambda访问私有S3资源
- 6. 从AWS Lambda JS SDK访问EC2资源
- 7. 如何动态授予AWS Lambda函数访问资源的权限?
- 8. ServiceStack:如何使用自定义OAuthProvider访问Azure资源
- 9. 我们可以编写AWS Lambda函数来查询Kinesis Streams
- 10. 如何使用Lambda函数响应JSON
- 11. 如何从CloudFormation AWS :: Lambda :: Alias获取函数名称和别名?
- 12. 使用CloudFormation映射为自定义资源拉姆达
- 13. 如何在自定义CloudFormation资源中指定依赖关系?
- 14. 无法使用CloudFormation将代码添加到AWS Lambda函数
- 15. 我可以在AWS CloudFormation中使用自定义AMI吗?
- 16. AWS CloudFormation:使用显式API作为事件源的Lambda事件
- 17. 在AWS上用AWS Lambda函数读取SNS消息用C#编写的函数
- 18. 从java访问s3 aws lambda
- 19. 如何定义一个函数AWS LAMBDA在Java开始?
- 20. 如何编写自定义函数CNTK
- 21. 使用自定义数据资源
- 22. 使用跨账户和IAC设置的AWS访问资源
- 23. 如何访问Java中的阅读和写作资源
- 24. 如何确定AWS资源属于哪个CloudFormation堆栈?
- 25. 如何从自定义Kendo UI数据源访问Javascript函数
- 26. aws Lambda函数访问策略
- 27. 如何编写自定义厨师资源的回归测试?
- 28. java中的AWS Lambda函数
- 29. CloudFormation - 是否可以为通用和重用资源定义定义映射?
- 30. AWS Lambda函数写入S3
你给了地方,因为我有从自定义资源读取响应回来时,我将它发送到水桶的问题响应发送桶任何权限?我的lambda正确地发送数据,然后CloudFormation挂起,因为它似乎永远不会收到通知。 –
对responseURL的请求很尴尬,因为我找不到一个错误:我们计算的请求签名与您提供的签名不匹配。检查你的密钥和签名方法。 你有没有遇到过这个,你知道它到底是什么意思吗? –