我们如何使用Java编写的AWS Lambda函数访问和响应CloudFormation定制资源? [英] How do we access and respond to CloudFormation custom resources using an AWS Lambda function written in Java?

查看:76
本文介绍了我们如何使用Java编写的AWS Lambda函数访问和响应CloudFormation定制资源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用Java编写的AWS Lambda函数,我想将其用作对AWS CloudFormation函数的响应的一部分。亚马逊提供,该自定义资源基于Node.js中编写的AWS Lambda函数返回其值,但是我一直难以将Lambda示例转换为Java。我们如何设置AWS Java函数,以便它从CloudFormation读取作为参数传递给Lambda函数的预签名S3 URL的值,并将我们所需的响应发送回等待的CloudFormation模板?

I have am AWS Lambda function written in Java that I would like to use as part of a response to an AWS CloudFormation function. Amazon provides two detailed examples on how to create a CloudFormation custom resource that returns its value based on an AWS Lambda function written in Node.js, however I have been having difficulty translating the Lambda examples into Java. How can we setup our AWS Java function so that it reads the value of the pre-signed S3 URL passed in as a parameter to the Lambda function from CloudFormation and send back our desired response to the waiting CloudFormation template?

推荐答案

与AWS来回交流后,下面是一些我创建的代码示例。

After back and forth conversation with AWS, here are some code samples I've created that accomplish this.

首先,假设您要利用预定义的接口创建处理程序,您可以实现RequestsHandler并定义HandleRequest方法,如下所示:

First of all, assuming you want to leverage the predefined interfaces for creating Handlers, you can implement RequestsHandler and define the HandleRequest methods like so:

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

Map< ; String,Object> 是从CloudFormation资源发送到Lambda函数的值的映射。 CF资源示例:

The Map<String, Object>is a Map of the values sent from your CloudFormation resource to the Lambda function. An example CF resource:

"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"]
  }
}

可以使用以下代码进行分析

can be analyzed with the following code

    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文档中的

The key things to point out here, beyond what is explained in the NodeJS examples in the AWS documentation are


  • (String)input.get( ResponseURL)是您需要回复的预先签名的S3 URL(稍后会对此进行详细介绍)

  • (Map< String,Object>)input.get( ResourceProperties)返回从CF模板传递到Lambda函数的CloudFormation定制资源 Properties的映射。我提供了String和ArrayList作为可以返回的对象类型的两个示例,尽管还有其他几种可能。

  • (String)input.get("ResponseURL") is the pre-signed S3 URL that you need to respond back to (more on this later)
  • (Map<String,Object>)input.get("ResourceProperties") returns the map of your CloudFormation custom resource "Properties" passed into the Lambda function from your CF template. I provided a String and ArrayList as two examples of object types that can be returned, though several others are possible

对于CloudFormation模板自定义资源实例化,您需要执行一个HTTP PUT调用,以返回到前面提到的ResponseURL,并在变量 cloudFormationJsonResponse 中包括以下大多数字段。下面是我的操作方法

In order to respond back to the CloudFormation template custom resource instantiation, you need to execute an HTTP PUT call back to the ResponseURL previously mentioned and include most of the following fields in the variable cloudFormationJsonResponse. Below is how I've done this

    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]}

Of particular note is the node "Data" above which references an additional com.amazonaws.util.json.JSONObject in which I include any attributes that are required in my CloudFormation template. In this case, it would be retrieved in CF template with something like { "Fn::GetAtt": [ "MyCustomResource", "CFAttributeRefName" ] }

最后,您可以简单地返回空值,因为此函数不会返回任何内容,因为它是 HTTPUrlConnection

Finally, you can simply return null since nothing would be returned from this function as it's the HTTPUrlConnection that actually responds to the CF call.

这篇关于我们如何使用Java编写的AWS Lambda函数访问和响应CloudFormation定制资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆