AWS IoT Core Integration with Google Cloud Function with HTTP Rule Action

0

I have created a simple Google Cloud Function with HTTP Trigger and have given necessary permissions to listen to outside requests.

I'm using MQTT test client for Publishing a topic, ( as of now I do not have device registered in IoT Core) under a specific topic name. What I'm trying to achieve here is republish this message with help of Rules Engine.

So I first create a Rule with HTTP endpoint as the action for IoT Rule and attach all the policies and provide required permissions for this rule. The HTTP endpoint is the URL of the Google Cloud Function mentioned above. I have confirmed and activated the endpoint with the token that is sent by AWS to GCFunction.

I have generated an authentication token from GCFunction which is required by AWS for accessing the resource and saved it in the IoT Rule under Headers as 'Authorization: Bearer[$token]'.

Expected Result: When I publish a message from the test client, it should show the message in the logs of GCFunction.

Actual Result: I see 403 and 401 errors. Stating the request is not authorized to invoke this service.

I think everything from the GCFunction end is fine since I tested it with Postman and got the expected result. But doesn't work with AWS IoT Rule. Is it that this kind of integration is not possible or there is no provision from AWS at the moment. Or I'm I missing something.

Can someone please help me understand this? Thanks!

  • Realized I read this wrong and you already have activated the endpoint. Your AWS IoT rule is in ENABLED state, correct? Can you post a sample Postman query (obfuscating private details)? The HTTP action will do a POST to the HTTP destination with the headers from the rule action and payload as the body.

  • Here is the post request I'm trying to send from postman and it works!

    "https://xxxxx-test-function-invoked-b-xxxxx-xx.x.run.app" (x = obfuscated data) - this is the url of google cloud function which I need to trigger.

    Apart from this I'm using Bearer token for authorization ; Body = {"Hello": "from postman"}; 7 automatically generated headers including Content-Type ; Content-Length ; Host ; User-Agent ; Accept ; Acceept-Encoding ; Connection.

    Let me know if I answered your question!

Hem
asked a year ago291 views
1 Answer
0
Accepted Answer

Based on your working Postman example (below from your comment above-thanks!):

"https://xxxxx-test-function-invoked-b-xxxxx-xx.x.run.app" (x = obfuscated data) - this is the url of google cloud function which I need to trigger.

Apart from this I'm using Bearer token for authorization ; Body = {"Hello": "from postman"}; 7 automatically generated headers including Content-Type ; Content-Length ; Host ; User-Agent ; Accept ; Acceept-Encoding ; Connection.

Most likely it's the I'm using Bearer token for authorization causing the issue. The AWS IoT Core Rule HTTP action will need to include the bearer token as part of the rule. This is problematic since access token will have a lifetime and need to be renewed. The HTTP Action can pull a value from the message payload, but I assume the devices won't have that available.

Is there a reason not to use AWS Lambda for the serverless aspect? That is also an available Rules Action. If Google Cloud Functions are needed, you can put the function behind a Google API Gateway and then secure with an API Key that hits that endpoint which in turn would invoke the Cloud Function. You will still have to setup a second method for validating the URL via the confirmationUrl parameter. Ssee Working with HTTP topics for more details.

Edit: details from comment below:

static_header_key and substitutable_header_key are placeholders. For instance, Authorization: Bearer token_contents would be look like this in the rule:

        "actions": [
            { 
                "http": { 
                    "url": "https://www.example.com/subpath",
                    "headers": [
                        { 
                            "key": "Authorization", 
                            "value": "Bearer token_contents" 
                        }
                    ] 
                } 
            }
        ]

the Substitution key would be used if wanted to use values from the payload as a modified key name or key value. Try changing to what you see in Postman's Request header (may only need the one key/value pair).

If that works with a fresh token, then the next step would be to determine how to include a API key in your rule definition via the Google API Gateway->Google Cloud Function, and also to understand the security concerns if the key is exposed.

I'm not well-versed with Google Cloud in general, :), but I would probably start here with Google's docs. Then you can generate an API key for the function.

Hope this helps, please reply back with any clarifications needed.

AWS
Gavin_A
answered a year ago
  • "The AWS IoT Core Rule HTTP action will need to include the bearer token as part of the rule. This is problematic since access token will have a lifetime and need to be renewed" ------- Yes, I was aware of this and did include the token under headers at the time of Rule creation, in the similar fashion like I did in postman. And also aware that tokens expire so I'm constantly updating with new token generated from google cloud functions, every time I want to test my request.

    However according to the documentation Headers are shown in a different structure under examples. Like below: "headers": [{ "key": "static_header_key", "value": "static_header_value" },{ "key": "substitutable_header_key", "value": "${value_from_payload}"}] I have not been able to figure out what 'static_header_key' is. Is this is what creating problem? And I think 'substitutable_header_key' is optional.

    Reason:- I have a direct provision of triggering a GCFunction HTTP endpoint from AWS IoT Rule Action and so want to use that. If this is not the case I will try out your suggestion API gateway (can you please elaborate this procedurally). Lambda function might have some latency and is not the best case for end nodes when they need some quick response. Just for testing purpose I performed with Lambda Rule Action as well and still same result.

    Note: I'm performing all this on AWS Console.

  • One other thing, is this part of a migration of IoT devices to AWS? I can help get your account team involved to help if that's the case.

  • Yes we are exploring possible options for a migration strategy. I did not get your point "I can help get your account team involved to help if that's the case."?

    I'll look into your above answer edit thank you! But your explanation for headers should it be used the same way in console as well? There is 'Header key' : 'Header value'. so these would be => 'Authorization' : 'Bearer[token_value]'?

  • I got it working from the console, I was sending the right headers but the structure was wrong [not including the square braces for token did the job]. Here is how you include the headers in console: under 'Header key' = 'Authorization'. and under 'Header value' = 'Bearer token_contents'.

    But this is for when you choose 'No Authentication' while creating the Rule. When I choose the 'SV4' authentication I again have this problem. We need to provide details like 'signing region' = 'region_of_GCF' (I believe both clouds should operate in same region) and 'Service name' = 'not sure but gave it as google cloud function' and 'IAM role' = 'aws-iot-role(which is created by aws aws iot)'. Is there something wrong in this approach?

  • Glad you got it working from the console. It's hard to abstract the underlying API call sometimes. As for Authentication, this won't work in this case. The SigV4 authentication is specific to AWS services based on our IAM setup. You will have to use the security approaches used by Google (OAUTH or API access key). As for an IoT migration, if you open a support case from the AWS console and request contact details, an account manager will reach out to setup a meeting where they can go into more details.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions