我们如何使用用 Java 编写的 AWS Lambda 函数访问和响应 CloudFormation 自定义资源?

2024-04-13

我有一个用 Java 编写的 AWS Lambda 函数,我想将其用作对 AWS CloudFormation 函数的响应的一部分。亚马逊提供两个详细的例子 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html关于如何创建一个 CloudFormation 自定义资源,该资源根据用 Node.js 编写的 AWS Lambda 函数返回其值,但是我在将 Lambda 示例转换为 Java 时遇到了困难。我们如何设置 AWS Java 函数,以便它读取作为参数从 CloudFormation 传递给 Lambda 函数的预签名 S3 URL 的值,并将我们所需的响应发送回等待的 CloudFormation 模板?


在与 AWS 反复交谈之后,以下是我创建的一些用于完成此任务的代码示例。

首先,假设你想要利用预定义的接口来创建处理程序 http://docs.aws.amazon.com/lambda/latest/dg/java-handler-using-predefined-interfaces.html,您可以实现 RequestsHandler 并定义 HandleRequest 方法,如下所示:

public class MyCloudFormationResponder implements RequestHandler<Map<String, Object>, Object>{
    public Object handleRequest(Map<String,Object> input, Context context) {
        ...
    }
}

The 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);
    }

除了 AWS 文档中的 NodeJS 示例中解释的内容之外,这里需要指出的关键事项是

  • (String)input.get("ResponseURL")是您需要响应的预签名 S3 URL(稍后会详细介绍)
  • (Map<String,Object>)input.get("ResourceProperties")返回从 CF 模板传递到 Lambda 函数的 CloudFormation 自定义资源“属性”的映射。我提供了 String 和 ArrayList 作为可以返回的对象类型的两个示例,尽管其他几种也是可能的

为了响应 CloudFormation 模板自定义资源实例化,您需要对前面提到的 ResponseURL 执行 HTTP PUT 回调,并在变量中包含以下大部分字段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();
    }

特别值得注意的是上面的节点“Data”,它引用了一个附加的com.amazonaws.util.json.JSONObject其中我包含了 CloudFormation 模板中所需的所有属性。在这种情况下,它将在 CF 模板中检索,类似于{ "Fn::GetAtt": [ "MyCustomResource", "CFAttributeRefName" ] }

最后,您可以简单地return null因为该函数不会返回任何内容,因为它是HTTPUrlConnection实际上响应 CF 调用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我们如何使用用 Java 编写的 AWS Lambda 函数访问和响应 CloudFormation 自定义资源? 的相关文章

随机推荐