How to escape curly bracket in AWS CLI Bash - bash

I'm trying to use AWS CLI Lambda to replace environment variables. However the value I want to replace has a pair of curly braces in it and CLI complaints about json format even when I already put the whole thing in single quote. Here's my command:
aws lambda update-function-configuration --function-name myFunc --environment Variables={URL='http://example.com/api/{0}'}
Here's the error:
Error parsing parameter '--environment': Expected: ',', received: '}' for input:
The funny thing is that if I removed the closing bracket }, it worked:
aws lambda update-function-configuration --function-name myFunc --environment Variables={URL='http://example.com/api/{0'}
Please help!!!

Enclose in double quotes:
Variables="{URL='http://example.com/api/{0}'}"
aws lambda update-function-configuration --function-name myFunc --environment Variables="{URL='http://example.com/api/{0}'}"
An error occurred (ResourceNotFoundException) when calling the
UpdateFunctionConfiguration operation: Function not found:
arn:aws:lambda:us-west-1:1234567890:function:myFunc

aws lambda update-function-configuration --function-name myFunc --environment "Variables={URL='http://example.com/api/{0}'}"
Here is the detailed issue regarding double quotes in aws cli
https://github.com/aws/aws-cli/issues/2638

This worked, my command is different though.
aws apigateway update-resource \
--rest-api-id <rest_api_id> \
--resource-id <resource_id> \
--patch-operations 'op=replace,path=/pathPart,value="{something}"'
The points are:
Single quote to for the whole argument,
Double quote to for the outer curly bracket.

Related

AWS CLI: How to use variable to filter EFS

I want to use the value of the DOMAIN_ID variable to filter the EFS to get a FileSystemId. I used the commands below. The first command works and it stores the domain ID. The second one returns an empty list, even though the DOMAIN_ID variable is present.
DOMAIN_ID=$(aws sagemaker list-domains --query 'Domains[0].DomainId')
aws efs describe-file-systems --query 'FileSystems[?CreationToken==`$DOMAIN_ID`].FileSystemId'
Output:
[]
Expected output:
<Some EFS identifier>
This works (escaping backticks) -
aws efs describe-file-systems --query "FileSystems[?CreationToken==\`$DOMAIN_ID\`].FileSystemId"
You can also use describe-domain command instead -
$ DOMAIN_ID=$(aws sagemaker list-domains --query 'Domains[0].DomainId' | tr -d '"')
$ aws sagemaker describe-domain --domain-id $DOMAIN_ID --query 'HomeEfsFileSystemId'

AWS EC2 and AMI tags with spaces using CLI

I try to create an instance using CLI, first like described in the doc (https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/run-instances.html, Example 4):
aws ec2 run-instances ... --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=val}]' 'ResourceType=volume,Tags=[{Key=Name,Value=val}]'
and it works well. The problem starts when I try to move whole tag-specifications in a separate bash variable, I need it because in fact there are many tags and they are built during the script run. So I do, but first use :
tags="--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=val}]' 'ResourceType=volume,Tags=[{Key=Name,Value=val}]'"
aws ec2 run-instances ... $tags
and it fails:
Error parsing parameter '--tag-specifications': Expected: '=', received: ''' for input:
'ResourceType=instance,Tags=[{Key=Name,Value=val}]'
^
If I remove single quotes then it works:
tags="--tag-specifications ResourceType=instance,Tags=[{Key=Name,Value=val_no_spaces}] ResourceType=volume,Tags=[{Key=Name,Value=val_no_spaces}]" # just works.
Despite it works, it's not good to me because if the values have spaces it stops working again:
tags="--tag-specifications ResourceType=instance,Tags=[{Key=Name,Value=val with spaces}] ResourceType=volume,Tags=[{Key=Name,Value=val with spaces}]"
Error parsing parameter '--tag-specifications': Expected: ',', received: 'EOF' for input:
ResourceType=instance,Tags=[{Key=Name,Value=val
^
I tried to wrap val into \", \' - neither works to me.
The same behavior is if you run very similar command aws ec2 create-image.
So, how can I add tags with spaces in the value and having them in a separate variable?
I had the same problem with aws cli. I solved it using arrays. In your case I would do the following:
tags=(
--tag-specifications
'ResourceType=instance,Tags=[{Key=Name,Value=val}]'
'ResourceType=volume,Tags=[{Key=Name,Value=val with spaces}]'
)
aws ec2 run-instances ... "${tags[#]}"

Error while creating AWS DynamoDB Table using CLI

I am trying to create table in DynamoDB using CLI.
I am using below command:
aws dynamodb create-table \ --table-name my_table \--attribute-definitions 'AttributeName=Username, AttributeType=S' 'AttributeName=Timestamp, AttributeType=S' \--key-schema 'AttributeName=Username, KeyType=HASH' 'AttributeName=Timestamp, KeyType=RANGE' \--provisioned-throughput 'ReadCapacityUnits=5, WriteCapacityUnits=5' \--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \--region us-east-1
On running above, I am getting below error:
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: the following arguments are required: --attribute-definitions, --key-schema
I am new to AWS, in my command I am declaring the attributes and key-schema, what is the error?
The backlashes on the command you typed are used for telling the cmd, when there is a line break, that the command continues on the next line.
Based on the screenshot and command you typed, you are trying to execute it in a single line.
As a solution you could remove the backslashes from your command or copy the original command (the one from the tutorial) as it is (including line breaks).
Without line breaks:
aws dynamodb create-table --table-name my_table --attribute-definitions 'AttributeName=Username, AttributeType=S' 'AttributeName=Timestamp, AttributeType=S' --key-schema 'AttributeName=Username, KeyType=HASH' 'AttributeName=Timestamp, KeyType=RANGE' --provisioned-throughput 'ReadCapacityUnits=5, WriteCapacityUnits=5' --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES --region us-east-1
With line breaks:
aws dynamodb create-table \
--table-name my_table \
--attribute-definitions AttributeName=Username,AttributeType=S AttributeName=Timestamp,AttributeType=S \
--key-schema AttributeName=Username,KeyType=HASH AttributeName=Timestamp,KeyType=RANGE \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
--region us-east-1
I would try using a json file for both the key schema and the attribute definitions. See https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html for the json syntax and examples. You shouldn’t need any other arguments other than the table to get your table running.

AWS CLI Script to add security groups

I've a script that I'm using to run authorize-security-group-ingress AWS CLI command.
IP = 10.10.10.10
CIDR = 32
Variable = sudo aws ec2 authorize-security-group-ingress --group-id sg-xxxxxx --ip-permissions FromPort=10,ToPort=23,IpProtocol=tcp,IpRanges='[{CidrIp=$((IP / 32))}]'
$Variable
But I get an error CIDR block $((IP / 32)) is malformed. I tried changing the $((IP / 32)) block to $IP/32 , ($(IP) / $(CIDR)) but I still seem to get the same error. Can someone tell me what I'm doing wrong? The main issue is converting to a valid IP CIDR.
You could do as Siddarth mentioned. Or, fix your query. The issue with your code is that you are using a single-quote (') instead of double-quotes (") for IpRanges. As per this SO question, Single quotes won't interpolate anything, but double quotes will.
Once you replace it, your script will fail again because $((...)) is an arithmetic expansion. Remove the (()) in your script and it should work fine.
Final solution:
aws ec2 authorize-security-group-ingress --group-id sg-xxxxxx --ip-permissions FromPort=10,ToPort=23,IpProtocol=tcp,IpRanges="[{CidrIp=$IP/$CIDR}]"
Have you tried it like this
'[{"IpProtocol":"tcp","IpRanges": [{"CidrIp": "10.10.10.10/32"}]}]'
Replacing your line of code with this worked for me.

Shorthand syntax for message-attributes in the send-message command in aws-cli for sqs

When trying to send a message using AWS CLI for SQS, I cannot get the shorthand syntax for the --message-attributes parameter to work.
Specifying a json file works fine, and the reference doesn't show an example for the shorthand option.
Here is the reference for this command which specifies the shorthand I'm trying to use but I can't get it to work: http://docs.aws.amazon.com/cli/latest/reference/sqs/send-message.html
Here's the command I've tried:
aws sqs send-message \
--queue-url https://sqs.us-east-1.amazonaws.com/0000000000/aa_queue_name \
--message-body "message body goes here" \
--message-attributes firstAttribute={DataType=String,StringValue="hello world"},secondAttribute={DataType=String,StringValue="goodbye world"}
I keep getting error messages:
Parameter validation failed: Invalid type for parameter
MessageAttributes.contentType, value: StringValue=Snapshot, type:
, valid types:
Anyone ever managed sending attributes for message using the shorthand?
Currently, the documentation of the short-hand syntax for the --message-attributes option is incorrect and the short-hand syntax does not work.
Instead, you can use the JSON file (as you mentioned). You can also use the inline JSON:
aws sqs send-message
--queue-url https://sqs.us-east-1.amazonaws.com/0000000000/aa_queue_name
--message-body "message body goes here"
--message-attributes '{ "firstAttribute":{ "DataType":"String","StringValue":"hello world" }, "secondAttribute":{ "DataType":"String","StringValue":"goodbye world"} }'
Your Shorthand Syntax format is correct:
MY_KEY={DataType=String, StringValue=MY_VALUE}
You just forgot to enclose the commandline option with single or double quotes:
aws sqs send-message \
--queue-url https://sqs.us-east-1.amazonaws.com/0000000000/aa_queue_name \
--message-body "message body goes here" \
--message-attributes 'firstAttribute={DataType=String, StringValue="hello world"}, secondAttribute={DataType=String,StringValue="goodbye world"}'
The above shortcut syntax should correctly produce a message with 2 extra headers, a.k.a. Message Attributes:
firstAttribute=hello world
secondAttribute=goodbye world
NOTE:
an attribute is a <class 'dict'>, so every attribute looks like a dictionary: {DataType=String, StringValue=MY_VALUE},
where supported DataTypes are String, Number, or
Binary.
each DataType value can contain an optional custom extention, that is ignored by AWS. For example: String.uuid, Number.int,
Binary.pdf.
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-attributes.html#message-attribute-components

Resources