How do I see which user that invoked a Lambda function - amazon-web-services

Need some help with Lambda invocation and authentication. I have an AWS Lambda function that is invoked from AWS IoT MQTT feed based on a specific topic. The invocation happens when an authenticated IoT Thing publishes to MQTT on that topic. My question is how do I see who has invoked it? I need this information so I know under what user to store the published information to database. I'm guessing there should be some environment variables that carry this information but I haven't found it. Maybe I been looking in all the wrong places:/
Many thanks,
Marcus

You should be able to modify the Lambda trigger in your IoT configuration to include the client ID by using something like the following SQL statement:
select clientId() as clientId, *

How are you?
You could send the user on the topic message. Is it not easier? Not sure how to get it from env var.

Related

AWS IOT - RegisterThing fails -- InvalidCertificateOwnershipToken

This is a real challenge. I have been successful in everything up to this point in Fleet provisioning on an embedded device. I have subscribed and published to topics and received new certificates and keys. But, when I take the certificateOwnershipToken that has been given to me and I try to trigger a DeviceRegistration, I get:
{"statusCode":400,"errorCode":"InvalidCertificateOwnershipToken","errorMessage":"Certificate ownership token cannot be empty."}
My token is 466 characters long and I send it with 2 other items in this string:
{"certificateOwnershipToken":"eyF1ZXJzaW9uIjoiMjAxOTEwMjMiLCJjaXBoZXIiOiJBaURqMUdYMjBiVTUwQTFsTUV4eEJaM3ZXREU1dXZSSURoTy80cGpLS1o1VkVHdlZHQm81THNaS1VydG0zcTdoZGtVR0l1cmJZS0dLVkx2dTZNL2ViT2pkVFdIeDEwU3o3aFZPeExERkxWVlJ4OUIvL2RzcXRIeVp1WVo2RXZoU1k0L0txQ0doZ1lyRklwZGlLK05pUlNHMXlLQXJUSGJXSkNlVUxHcHRPWHJtdHJaNWJMUyt1MHFUcjNJVnlVLzNpcGZVVm1PanpmL3NCYzdSNkNyVGJPZ05Nc2xmOXdHSVRWM0tPUjd1aFFSbnZySnY0S1ZtU2hYc2REODI4K1crRE1xYnRYZGUxSXlJU29XZTVTSHh6NVh2aFF3OGl3V09FSzBwbG15Zi82dUgyeERoNjB1WS9lMD0ifQ==","parameters":{"SerialNumber":"82B910","CertificateId":"175b43a3d605f22d30821c4a920a6231978e5d846d3f2e7a15d2375d2fd5098c"}}
My templates looks right, my policy looks correct. The role which is attached to my template seem to cover my needs. I just don't know how AWS is failing without more information.
Does anyone have ideas on how to proceed?
I found my problem. In C/C++ aws iot sdk -- there is a data structure where you must specify the payload string and a few other things. One of those data elements is the length of the payload and I forgot to set that length before sending my payload to the $aws/provisioning-templates//provision/json topic. Once I set that length, then the submission worked and the template was acted upon and the thing was created

AWS Step Function manual approval process

I am working on the requirement where the data entered in the form needs to be validated manually and once validated , a approval mail be be sent out and then data will be stored in the database.I plan to use AWS step function for this with token.
https://aws.amazon.com/blogs/compute/implementing-serverless-manual-approval-steps-in-aws-step-functions-and-amazon-api-gateway/
I plan to use a similar design like in the link above.However is there a way not to use API Gateway for sending back the task token to step function to resume processing.Did anybody worked on the similar requirement and how the functionality was achieved. Thank you.
Step function can be invoked by the AWS Lambda function as well.
Once the form is validated and stored in database, you can trigger the Lambda function based on the database events(ex- if DynamoDB used then based on the DynamDB streams), and the lambda can start the step function.

How to subscribe Lambda to an AWS Iot Jobs topic in Serverless Framework

I'm using the Serverless Framework and I need to subscribe my Lambda function to an AWS Iot Jobs topic, more specifically the "start-next/#" topic. I already have another Lambda function subscribed to another topic of the AWS Iot tools, using this piece of code in the serverless.yml file:
events:
- iot:
sql: "SELECT topic() AS topic, * FROM '$aws/things/+/shadow/update'"
This works just fine, the Lambda function is triggered and I'm able to process what I need, but when I try to use this piece of code:
events:
- iot:
sql: "SELECT topic() AS topic, * FROM '$aws/things/+/jobs/start-next/#'"
it simply will not work no matter what I try to do.
Could someone give me any sugestions of what I can do to trigger my Lambda function when new messages are published to the '$aws/things/+/jobs/start-next' topic?
Using the wildcard # at the end of the query you make your rule subscribes to any topic beginning with
'$aws/things/thingName/jobs/start-next/[...]'
'$aws/things/thingName/jobs/start-next/[...]/[...]'
'...'
If you are publishing a message to a topic like this by any chance (with nothing after /start-next)
$aws/things/thingName/jobs/start-next
Then it won't match your rule. In such scenario, you should query without the '#' wildcard at the end. Something like this
'sql: "SELECT topic() AS topic, * FROM '$aws/things/+/jobs/start-next'"'
You can find more details about such wildcards and its coverage right here
So... Reading the MQTT Client Help on the IOT page, I've actually found this part:
Reserved topics
Topics beginning with $ are considered reserved and are not supported for publishing and
subscribing except when working with the Thing Shadows service. To learn more,
see Thing Shadows.
which would explain why the shadows topic triggers the Lambda as I mentioned in the question, but not my other Lambda based on the jobs topics.
I guess I'll have to find another way to make this work, but thanks to who tried to help :)

Send S3 document to Textract using Go

I'm trying to use Go to send objects in a S3 bucket to Textract and collect the response.
I'm using the aws go sdk package and able to connect to my S3 bucket and list all the objects contained within. So far so good. I now need to be able to send one of those objects (a .pdf file) to Textract and collect the response(s).
The AWS Go SDK content for interacting with Textract seem to be quite extensive but I cannot find a good example for how to do this.
I would be very grateful for a sample or advice on how to do this.
To start a job, you invoke StartDocumentTextDetection, using a DocumentLocation to specify the file, and you specify a SNS topic where Textract will publish a notification when it has finished to process your job.
You have now two possibilities:
Subscribe to the SNS topic, and when you receive a message retrieve the result
Create a lambda function triggered by the SNS topic, which retrieves the result.
The second option is IMO better 'cause it use less computation time (doesn't run until the job hasn't finished).
To retrieve the job, you use GetDocumentTextDetection
If anyone else reaches this site searching for an answer:
I understood the documentation as if I could just call the StartDocumentAnalysis function through the textract SDK but in fact what was missing is the fact that you need to create a new Session first and do the calls based on the session:
https://docs.aws.amazon.com/sdk-for-go/api/service/textract/#New

Query AWS SNS Endpoints by User Data

Simple question, but I suspect it doesn't have a simple or easy answer. Still, worth asking.
We're creating an implementation for push notifications using AWS with our Web Server running on EC2, sending messages to a queue on SQS, which is dealt with using Lambda, which is sent finally to SNS to be delivered to the iOS/Android apps.
The question I have is this: is there a way to query SNS endpoints based on the custom user data that you can provide on creation? The only way I see to do this so far is to list all the endpoints in a given platform application, and then search through that list for the user data I'm looking for... however, a more direct approach would be far better.
Why I want to do this is simple: if I could attach a User Identifier to these Device Endpoints, and query based on that, I could avoid completely having to save the ARN to our DynamoDB database. It would save a lot of implementation time and complexity.
Let me know what you guys think, even if what you think is that this idea is impractical and stupid, or if searching through all of them is the best way to go about this!
Cheers!
There isn't the ability to have a "where" clause in ListTopics. I see two possibilities:
Create a new SNS topic per user that has some identifiable id in it. So, for example, the ARN would be something like "arn:aws:sns:us-east-1:123456789:know-prefix-user-id". The obvious downside is that you have the potential for a boat load of SNS topics.
Use a service designed for this type of usage like PubNub. Disclaimer - I don't work for PubNub or own stock but have successfully used it in multiple projects. You'll be able to target one or many users this way.
According the the [AWS documentation][1] if you try and create a new Platform Endpoint with the same User Data you should get a response with an exception including the ARN associated with the existing PlatformEndpoint.
It's definitely not ideal, but it would be a round about way of querying the User Data Endpoint attributes via exception.
//Query CustomUserData by exception
CreatePlatformEndpointRequest cpeReq = new CreatePlatformEndpointRequest().withPlatformApplicationArn(applicationArn).withToken("dummyToken").withCustomUserData("username");
CreatePlatformEndpointResult cpeRes = client.createPlatformEndpoint(cpeReq);
You should get an exception with the ARN if an endpoint with the same withCustomUserData exists.
Then you just use that ARN and away you go.