How to make AWS CLI commands easy to run with generate-cli-skeleton
Using the AWS CLI is very useful because it helps you see how each service or command works and increases your chances to pass AWS certification exams.
Often times though the CLI command is quite cumbersome: you would need to write JSON-format in the command line or there are simply just too many parameters involved for the specific command.
This will increase that probability of me making a typo somewhere in the four-line command and then I’ll spend a few seconds (minutes) debugging what causes the error message.
1. Use help
I can definitely use help
.
Each command comes with a help
section. It can be brought up like this:
aws dynamodb create-table help
Please note that unlike many other CLI commands, there is no --
before help
.
This will bring up the same help section that you can find in the CLI page of the relevant service. For DynamoDB CreateTable
, this page will be displayed to the console. It’s the same document as I’d read in the browser.
Unfortunately, using the help
parameter doesn’t prevent me from writing long commands.
1. generate-cli-skeleton
There is a cool feature that I started to use to reduce the number of these cases. It’s called generate-cli-skeleton
.
This command will return a JSON object with all available parameters. I can write the content of the response to a JSON file and now I’ll have the template for the command.
I can then edit the JSON in the editor of my choice, remove the parameters I don’t need and add the values to the ones I do need.
2. Example
I’ll create a DynamoDB table and add an item to it using the generate-cli-skeleton
parameter. This is a very common task and DynamoDB’s CLI commands can be quite complex.
The table will be called Pets
and I will upload an item (a pet) to the table.
2.1. Create the table
Let’s start with saving the CreateTable
template:
aws dynamodb create-table --generate-cli-skeleton > create-table.json
A file called create-table.json
will be created in the folder from where the command was run. The content of the file looks like this:
{
"AttributeDefinitions": [
{
"AttributeName": "",
"AttributeType": "N"
}
],
"TableName": "",
"KeySchema": [
{
"AttributeName": "",
"KeyType": "RANGE"
}
],
"LocalSecondaryIndexes": [
{
"IndexName": "",
"KeySchema": [
{
"AttributeName": "",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL",
"NonKeyAttributes": [
""
]
}
}
],
"GlobalSecondaryIndexes": [
{
"IndexName": "",
"KeySchema": [
{
"AttributeName": "",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "KEYS_ONLY",
"NonKeyAttributes": [
""
]
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 0,
"WriteCapacityUnits": 0
}
}
],
"BillingMode": "PROVISIONED",
"ProvisionedThroughput": {
"ReadCapacityUnits": 0,
"WriteCapacityUnits": 0
},
"StreamSpecification": {
"StreamEnabled": true,
"StreamViewType": "NEW_IMAGE"
},
"SSESpecification": {
"Enabled": true,
"SSEType": "AES256",
"KMSMasterKeyId": ""
},
"Tags": [
{
"Key": "",
"Value": ""
}
]
}
The JSON proves that create-table
is a command that is difficult to submit from the CLI: it has a couple of array and object values.
Next, I’ll remove the parameters I don’t need.
I’ll keep the TableName
(Pets
) as well as the partition key and sort key parameters (AttributeDefinitions
and KeySchema
). I’ll also provision 2-2 read and write capacity units (BillingMode
and ProvisionedThroughput
) and will enable server-side encryption (SSESpecification
) with the default AWS managed KMS customer master key (CMK), because I want the data about my pets to be secure.
After I have entered the values for the parameters I want and removed the ones I don’t want, my create-table.json
looks like this:
{
"AttributeDefinitions": [
{
"AttributeName": "Id",
"AttributeType": "S"
},
{
"AttributeName": "Name",
"AttributeType": "S"
}
],
"TableName": "Pets",
"KeySchema": [
{
"AttributeName": "Id",
"KeyType": "HASH"
},
{
"AttributeName": "Name",
"KeyType": "RANGE"
}
],
"BillingMode": "PROVISIONED",
"ProvisionedThroughput": {
"ReadCapacityUnits": 2,
"WriteCapacityUnits": 2
},
"SSESpecification": {
"Enabled": true,
"SSEType": "KMS"
}
}
I have chosen the Id
to be the partition key (it’s a good choice because it will be a UUID) and the Name
of the pet will be the sort key.
I can now run the command and create the table:
aws dynamodb create-table --cli-input-json file://create-table.json
As a result, the Pets
table will be created:
aws dynamodb list-tables
The response is
{
"TableNames": [
"Pets"
]
}
Great!
2.2. Add an item to the table
The table has been created and I can now add a pet to the table.
I’ll do the same as I did above with the PutItem
API command:
aws dynamodb put-item --generate-cli-skeleton > put-item.json
I want to add a goldfish called Goldie who is one year old and doesn’t remember anything that happens around him in the world.
I also want to make sure that Goldie doesn’t exist in the table and I won’t override him accidentally, so I will conditionally write him to the table (attribute_not_exists
). I also want to see how many write capacity units will Goldie consume.
After removing the unnecessary parameters and adding my values to it, the put-item.json
file looks like this:
{
"TableName": "Pets",
"Item": {
"Id": {
"S": "6663f471-7247-4868-8faf-b42ecc35c7dd"
},
"Name": {
"S": "Goldie"
},
"Type": {
"S": "fish"
},
"Age": {
"N": "1"
},
"Remembers": {
"BOOL": false
}
},
"ReturnConsumedCapacity": "TOTAL",
"ConditionExpression": "attribute_not_exists(Id)"
}
Let’s run the command:
aws dynamodb put-item --cli-input-json file://put-item.json
The response will show the write capacity units used:
{
"ConsumedCapacity": {
"TableName": "Pets",
"CapacityUnits": 1.0
}
}
It’s only 1.0
WCU, so the provisioned 2
write capacity units have been proved to be enough.
If I quickly run a scan
command (without generate-cli-skeleton
):
aws dynamodb scan --table-name Pets
I can see that Goldie has been successfully written to the table:
{
"Items": [
{
"Id": {
"S": "6663f471-7247-4868-8faf-b42ecc35c7dd"
},
"Type": {
"S": "fish"
},
"Age": {
"N": "1"
},
"Remembers": {
"BOOL": false
},
"Name": {
"S": "Goldie"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
And he really doesn’t remember anything.
3. Summary
Some CLI commands require parameter values of complex structure or have lots of compulsory parameters.
The generate-cli-skeleton
parameter returns all available parameters with some default values. These parameters can be redirected to a JSON file, which can be modified in an editor. By referring to this file instead of typing the parameter values to the terminal will make running commands faster and less error prone.
Thanks for reading and see you next time.