Test AWS lambda function via cli - bash

I want to test a lambda function via CLI instead of the AWS Management console. (Looking to automate function testing by making a bash script)
I've read the documentation: http://docs.aws.amazon.com/cli/latest/reference/lambda/invoke.html
I am trying to invoke the lambda function with a json event payload. My bashcode looks like this:
#!/bin/bash
name="arn:aws:lambda:euwest1:100000000000:function:foo"
invoketype="Event"
payload="{'account':'100261334439', 'region':'eu-west-1', 'detail-type':'Scheduled Event', 'source':'aws.events', 'time':'2017-07-16T03:00:00Z', 'id':'178710aa-6871-11e7-b6ef-e9b95183cfc9', 'resources':['arn:aws:events:eu-west-1:100000000000:rule/run_everyday']}"
aws lambda invoke --function-name "$name" --invocation-type "$invoketype" --payload "$payload" testresult.log
I am getting the error:
An error occurred (InvalidRequestContentException) when calling the Invoke operation: Could not parse request body into json: Unexpected character ('a'
(code 97)): was expecting double-quote to start field name at [Source: [B#7ac4c2fa; line: 1, column: 3]
I believe I am providing the payload in wrong format, but the documentation has no example, it just says that the datatype is 'blob'. I did some searching but only found info on BLOB (binary large object), but I'm pretty sure this is not what the documentation is referring to.
I have tried without the outer double quotes and replacing all the single quotes with double quotes, but all of these give the same error.

tl;dr
Correct (normally): $ aws lambda invoke --function-name myFunction --payload '{"key1":"value1"}' outputfile.txt
Correct (Windows): aws lambda invoke --function-name myFunction --payload "{""key1"": ""value1""}" outputfile.txt
OP's specific question is already answered correctly; this answer is for the benefit of those ending up here with slightly different circumstances from OP. What OS are you using? If its Windows, then you are likely pulling your hair out over single and double quote issues.
Windows command line does not understand single quotes, and double
quotes within a quoted string must be escaped as two double quotes
("").
Credit (normal): AWS documentation
Credit (Windows): Hail Reddit!

valid JSon should have key and value between double quotes
so you should have the payload attribute written as
payload='{"account":"100261334439", "region":"eu-west-1", "detail-type":"Scheduled Event", "source":"aws.events", "time":"2017-07-16T03:00:00Z", "id":"178710aa-6871-11e7-b6ef-e9b95183cfc9", "resources":["arn:aws:events:eu-west-1:100000000000:rule/run_everyday"]}'

Related

aws cli command in PowerShell gives Missing argument in parameter list

What specific syntax needs to be changed in the aws s3api put-object-tagging --bucket bucketName --key fileName.tar.gz --tagging TagSet={Key=public,Value=yes} command to prevent the error shown below when the command is run in PowerShell?
Note that the aws s3api put-object-tagging --bucket bucketName --key fileName.tar.gz --tagging TagSet={Key=public,Value=yes} command syntax works perfectly when run in windows cmd on the very same computer.
Here is the PowerShell log including the command and the error message on the same computer where this command works in windows cmd:
PS C:\Users\userName> aws s3api put-object-tagging --bucket bucketName --key fileName.tar.gz --tagging TagSet={Key=public,Value=yes}
At line:1 char:129
+ ... --key fileName.tar.gz --tagging TagSet={Key=public,Value=ye ...
+ ~
Missing argument in parameter list.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingArgument
PS C:\Users\userName>
Also note that I am new to PowerShell. I just sometimes now need to translate short scripts from other languages into PowerShell.
Update:
The answer below addresses your question as asked, based on your (seemingly incorrect) claim that the first command mentioned in your question worked as-is from cmd.exe. The points made below generally apply to the syntax of arguments passed to commands in PowerShell.
Based on a later comment, you state that what solved your problem was to pass a JSON string to the aws CLI's --tagging parameter:
You state that '{\"TagSet\": [{\"Key\":\"public\",\"Value\":\"yes\"}]}' worked for you (which represents the following verbatim JSON string: {"TagSet": [{"Key":"public","Value":"yes"}]).
Here too it is the quoting ('...') that makes the argument work, as discussed in the bottom section.
As an aside: This strange need to manually \-escape " characters embedded in an argument passed to external programs is indeed an - unfortunate - requirement in PowerShell up to at least v7.2.x, due to a long-standing bug. It may get fixed in a future version, which may require opt-in: see this answer.
However, apart from the PowerShell syntax problem that is the subject of your question, it looks like your original command simply used incorrect aws shorthand syntax (a shorter alternative to passing JSON): according to the docs for the put-object-tagging subcommand, the following should work - in addition to the required quoting ('...') for PowerShell's sake, note the [...] around {...} which were missing from your own original command: 'TagSet=[{Key=public,Value=yes}]'
Replace:
TagSet={Key=public,Value=yes}
with:
'TagSet={Key=public,Value=yes}'
That is, quote your argument, which prevents PowerShell from interpreting {...} as a script block, which is what caused your problem.
Note the use of a '...', i.e a single-quoted verbatim string, which is the best choice if an argument contains no embedded variable references or subexpression (for the latter, you need string interpolation in the form of "...", i.e., a double-quoted expandable string).
PowerShell differs from other shells in two notable respects:
its escape character is ` (the so-called backtick), not \ (as in POSIX-compatible shells such as Bash) or ^ (as in cmd.exe)
it has more metacharacters than other shells, such as {, }, and #
See this answer for more information.
As for the specific error message you saw:
The content of a script block ({ ... }) is parsed as PowerShell code, and the content in your case, Key=public,Value=yes, is parsed as a command, whose syntax happens to be invalid:
Key=public is interpreted as a command name
,Value=yes is parsed as its argument, which - due to the , - is parsed as an array, but a literal array passed as an argument must not start with ,, which is what the error message is trying to say: it's missing an array element before ,
You can more easily provoke this error by submitting the following on the command line:
foo , bar # -> Error "Missing argument in parameter list."

AWS CLI on Windows won't work though using double quotes and escapes

I made an Amazon Event Bridge rule and I wanted to attach targets on it using AWS CLI.
I knew that when you use json string in aws cli on windows 10 command prompt, you need to
Use double quotes.(Single quotes are now allowed.)
Put back slashes before double quotes except for the first and the last one.
so, I call this on command prompt
aws events put-targets --rule xxxxxxxxxxxxxxxxxxxxxxxxx --targets "{\"Arn\":\"arn:aws:ssm:ap-northeast-1:awsaccountid:automation-definition/AWS-StartEC2Instance\",\"Input\":\"{\"InstanceId\":[\"i-xxxxxxxxxxxxxxxxx\"]}\",\"Id\":\"aaaaaaaa\",\"RoleArn\":\"arn:aws:iam::awsaccountid:role/some-ssm-role\"}"
but got error:
Error parsing parameter '--targets': Invalid JSON: Expecting ',' delimiter: line 1 column 104 (char 103)
JSON received: {"Arn":"arn:aws:ssm:ap-northeast-1:awsaccountid:automation-definition/AWS-StartEC2Instance","Input":"{"InstanceId":["i-xxxxxxxxxxxxxxxxx"]}","Id":"aaaaaaaa","RoleArn":"arn:aws:iam::awsaccountid:role/some-ssm-role"}
any suggestion?
p.s.
I made sure command below succeeded on Linux terminal.
aws events put-targets --rule xxxxxxxxxxxxxxxxxxxxxxxxx --targets '{"Arn": "arn:aws:ssm:ap-northeast-1:awsaccountid:automation-definition/AWS-StopEC2Instance","Input":"{\"InstanceId\":[\"i-xxxxxxxxxxxxxxxxx\"]}","Id":"aaaaaaaa","RoleArn":"arn:aws:iam::awsaccountid:role/some-ssm-role"}'
Could you try the following:
aws events put-targets --rule xxxxxxxxxxxxxxxxxxxxxxxxx --targets "{\"Arn\":\"arn:aws:ssm:ap-northeast-1:awsaccountid:automation-definition/AWS-StartEC2Instance\",\"Input\":\"{\\\"InstanceId\\\":[\\\"i-xxxxxxxxxxxxxxxxx\\\"]}\",\"Id\":\"aaaaaaaa\",\"RoleArn\":\"arn:aws:iam::awsaccountid:role/some-ssm-role\"}"
Or, same thing but marginally more readable this time with caret continuation markers:
aws events put-targets ^
--rule xxxxxxxxxxxxxxxxxxxxxxxxx ^
--targets "{\"Arn\":\"arn:aws:ssm:ap-northeast-1:awsaccountid:automation-definition/AWS-StartEC2Instance\",\"Input\":\"{\\\"InstanceId\\\":[\\\"i-xxxxxxxxxxxxxxxxx\\\"]}\",\"Id\":\"aaaaaaaa\",\"RoleArn\":\"arn:aws:iam::awsaccountid:role/some-ssm-role\"}"
The key thing to recognize is that the Input attribute in the JSON is itself a string containing JSON, so it needs to be double-escaped. This at least passes the initial format validation for me.

aws-cli won't work with a variable I created in bash

I'm trying to write a bash script for creating an AWS SQS queue and then check that the queue is empty. For that I created the following script that should return "null":
aws sqs create-queue --queue-name MessagesQueue
queue_url=$(aws sqs list-queues --query QueueUrls[0])
queue_check=$(aws sqs get_queue_attributes --queue_url $queue_url --attribute-names ApproximateNumberOfMessages --query Attributes[0].ApproximateNumberOfMessages
And I receive this error message instead:
An error occurred (InvalidAddress) when calling the GetQueueAttributes operation: The address "https://eu-west-3.queue.amazonaws.com/XXXXXXXXXXXX/MessagesQueue" is not valid for this endpoint.
But if I explicitly write the same address in the command instead of using $queue_url it works fine and returns 'null' as it should.
Why isn't it accepting $queue_url but accepts the same URL address if I explicitly write it?
Edit: It seems like the aws-cli command reads the variable $queue_url as the URL between single and double-quotes, and when I write it explicitly it reads the URL with no quotes so that's why it accepts it. How can I use the bash variable I created so the aws-cli reads it with no quotes?
I solved it, I just had to remove the quotes from the output and I did it like this:
queue_url=$(aws sqs list-queues --query QueueUrls[0])
queue_url="${queue_url%\"}"
queue_url="${queue_url#\"}"
This other stackoverflow question helped: Shell script - remove first and last quote (") from a variable
Once I tried to run your code, part by part (started with aws sqs list_queues
), I have noticed:
aws: error: argument operation: Invalid choice, valid choices are:
...
Invalid choice: 'list_queues', maybe you meant:
* list-queues
Try out list-queues instead list_queues and let know how it goes.

Shell/Bash - extra characters in string variable after assigning cli result

In one of my variables I store result (string) from aws cli command.
When echoing the value it is displayed in " " but injecting it as a parameter shows that extra characters (&#34) are added at the beginning and end of the string.
How to eliminate these? What do they represent?
Code and error log:
dms_arn=$(aws dms describe-replication-tasks --filter Name=replication-task-id,Values="$dms_name" `--query=ReplicationTasks[0].ReplicationTaskArn --region us-east-1)`
echo Stopping Task "$dms_arn"
build 02-Nov-2021 18:52:01 Stopping Task "arn:aws:dms:us-east-1:account:task:XYZ"
error 02-Nov-2021 18:52:02
error 02-Nov-2021 18:52:02 An error occurred (InvalidParameterValueException) when calling the StopReplicationTask operation: Invalid task ARN: "arn:aws:dms:us-east-1:account:task:XYZ"
&#34 is the html code for double quote ("). The double quotes are being converted to html code.
Try using the —output text option with your aws command (so you don’t get quotes). See the documentation about output format: https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-output-format.html
If necessary, you can remove wrapping double quotes using shell parameter expansion:
dms_arn=${dms_arn%\"}
dms_arn=${dms_arn#\"}
echo "$dms_arn"
# quotes are gone
&#34 is the HTML entity corresponding to the double quotation marks.
See: entity
To convert them check: Short way to escape HTML in Bash? and Bash script to convert from HTML entities to characters

How to pass JSON object as parameter in wsk (openwhisk)

I have OpenWhisk evironment in my laptop, setup through Vagrant. I have an action that accepts parameter, that is used to take JSON data. I followed the information given in the following URL for passing parameters.
https://console.bluemix.net/docs/openwhisk/parameters.html#working-with-parameters
Based on the information given in the above web site I executed the following command.
wsk action -i invoke addcoins -p coindata '{"name": "coin1", "price": "3" }'
When I execute this I am getting the following error:
error: Invalid argument(s): asfsds,, price:, 3, }'. An action name is required.
Run 'wsk --help' for usage.
I do not understand how should I pass an JSON object as parameter in wsk.
This is because of the single outer quotes when using the CLI from a Windows client. Try double quotes (and escaping the internal quotes). See https://github.com/apache/incubator-openwhisk/issues/1291.
wsk action -i invoke addcoins -p coindata "{\"name\": \"coin1\", \"price\": 3 }"

Resources