One of the best kept secrets of the AWS CLI should be the ‘alias’ feature. It’s a native feature of AWS. In this blog post I’ll describe how to get started and show you a couple of my most used aliases so far.
cat > ~/.aws/cli/alias <<!
[toplevel]
whoami = sts get-caller-identity
cf = cloudformation
cfls =
!f() {
aws cloudformation list-stacks
}; f
!
Now try your new aliases. First up is the alias for aws sts get-caller-identity
.
$ aws whoami
{
"UserId": "A3H342JJLKJ24H23KL42:session",
"Account": "112233445566",
"Arn": "arn:aws:sts::985363061363:assumed-role/admin/session"
}
Next up are both aliases for aws cloudformation list-stacks
. Both examples just save a few keystrokes, but it is a good start.
$ aws cf list-stacks
{
"StackSummaries": [
{
"StackId": "arn:aws:cloudformation:eu-west-1:112233445566:stack/stack/129...",
"StackName": "stack",
"CreationTime": "2019-06-26T14:38:32.984Z",
...
$ aws cfls
{
"StackSummaries": [
{
"StackId": "arn:aws:cloudformation:eu-west-1:112233445566:stack/stack/129...",
"StackName": "stack",
"CreationTime": "2019-06-26T14:38:32.984Z",
...
Now you have a basic understanding of how to use aliases for single words and short commands, but there is much more to get.
Most CLI commands I use are with CloudFormation. S3 CLI commands like aws s3 ls <bucket>
is an alias for aws s3api list-objects --bucket <bucket>
. These commands are default available in the AWS CLI. I created a few aliases for CloudFormation in a similar way. The first set of example are just informational queries you’ll often run to get current information or status about your stacks.
* List. should just list the active AWS stacks. Without a parameter, it shows all stacks for the region you’re in, but you can also enter the first character of the stack.
* Describe. shows some details of the stack in JSON, because you want to see everything.
* Resources. shows a table of resources in a table view.
* Outputs. shows the outputs in a table view.
* Events and Errors. Lists recent events or errors of a stack.
Add the following code to your ~/.aws/cli/alias.
list =
!f() {
aws cloudformation list-stacks \
--query "StackSummaries[?StackStatus != 'DELETE_COMPLETE' && starts_with(StackName, '${1}')].{StackName: StackName, StackStatus: StackStatus, UpdateTime: LastUpdatedTime}" \
--output table
}; f
describe =
!f() {
if [ -z "$1" ]; then
echo "usage: aws describe <stack_name>"
else
aws cloudformation describe-stacks --stack-name $1
fi
}; f
outputs =
!f() {
if [ -z "$1" ]; then
echo "usage: aws outputs <stack_name>"
else
aws cloudformation describe-stacks \
--stack-name $1 \
--query "Stacks[].Outputs[].{OutputKey: OutputKey, OutputValue: OutputValue}" \
--output table
fi
}; f
resources =
!f() {
if [ -z "$1" ]; then
echo "usage: aws resources <stack_name>"
else
aws cloudformation describe-stack-resources \
--stack-name $1 \
--query "StackResources[].{ResourceStatus: ResourceStatus, LogicalResourceId: LogicalResourceId, PhysicalResourceId: PhysicalResourceId}" \
--output table
fi
}; f
events =
!f() {
if [ -z "$1" ]; then
echo "usage: aws events <stack_name>"
else
aws cloudformation describe-stack-events \
--stack-name $1 \
--query "StackEvents[].[Timestamp,ResourceStatus,LogicalResourceId,ResourceStatusReason]" \
--output table
fi
}; f
errors =
!f() {
if [ -z "$1" ]; then
echo "usage: aws errors <stack_name>"
else
aws cloudformation describe-stack-events \
--stack-name $1 \
--query "StackEvents[?ResourceStatus=='CREATE_FAILED' || ResourceStatus=='UPDATE_FAILED'].[Timestamp,ResourceStatus,LogicalResourceId,ResourceStatusReason]" \
--output table
fi
}; f
Also a few commands to quickly create, update and delete stacks.
* Deploy. Deploys a stack, by default searching for the template.yml, because that’s what I often use. Also, the –capabilities parameter is already set.
* Package. This command can package a SAM template and produces a new template file to deploy: packaged.yml (which can be overriden of course). Consider using the Launch command, because it performs a package & deploy at once.
* Launch. Creates a package by uploading to an S3bucket, again uses template.yml by default.
* Delete. Deletes a stack.
Now add the following code snippet to your ~/.aws/cli/alias.
package =
!f() {
if [ -z "$2" ]; then
template="template.yml"
else
template=$2
fi
if [ -z "$3" ]; then
packaged="packaged.yml"
else
packaged=$3
fi
if [ -z "$1" ]; then
echo "usage: aws package <s3bucket> [<source_template>] [<target_template>]"
else
aws cloudformation package \
--template $template \
--s3-bucket $1 \
--output-template-file $packaged
fi
}; f
deploy =
!f() {
if [ -z "$2" ]; then
template="template.yml"
else
template=$2
fi
if [ -z "$1" ]; then
echo "usage: aws package <stack_name> [<template>]"
else
aws cloudformation deploy \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--stack-name $1 \
--template $template
fi
}; f
delete =
!f() {
if [ -z "$1" ]; then
echo "usage: aws delete <stack_name>"
else
aws cloudformation delete-stack \
--stack-name $1
fi
}; f
launch =
!f() {
if [ -z "$3" ]; then
template="template.yml"
else
template=$3
fi
if [ "$template" == "packaged.yml" ]; then
echo "template should not be packaged.yml"
exit 1
fi
if [ -z "$1" ]; then
echo "usage: aws delete <s3bucket> <stack_name> [<template>]"
else
aws cloudformation package \
--template $template \
--s3-bucket $1 \
--output-template-file packaged.yml
aws cloudformation deploy \
--stack-name $2 \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--template packaged.yml
fi
}; f
Conclusion
To conclude this blog post I want to show you the deployment of the following stack. It will fail first, because the BucketName already exists. Then I’ll delete the stack, remove the BucketName so CloudFormation creates a new one, which I’ll find with outputs. During this example I’ll use a couple of alias commands, such as: deploy, errors, delete, outputs, resources. I think it will save hundreds of keystrokes.
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: "aws"
Outputs:
S3Bucket:
Value: !Ref S3Bucket
$ aws deploy test
Waiting for changeset to be created..
Waiting for stack create/update to complete
Failed to create/update the stack.
$ aws errors test
---------------------------------------------------------------------------------
| DescribeStackEvents |
+---------------------------+----------------+-----------+----------------------+
| 2019-07-01T13:22:01.076Z | CREATE_FAILED | S3Bucket | aws already exists |
+---------------------------+----------------+-----------+----------------------+
$ aws delete test
$ aws deploy test
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - test
$ aws resources test
-------------------------------------------------------------------------
| DescribeStackResources |
+-------------------+-------------------------------+-------------------+
| LogicalResourceId | PhysicalResourceId | ResourceStatus |
+-------------------+-------------------------------+-------------------+
| S3Bucket | test-s3bucket-1jsdfaabenntt | CREATE_COMPLETE |
+-------------------+-------------------------------+-------------------+
$ aws outputs test
----------------------------------------------
| DescribeStacks |
+------------+-------------------------------+
| OutputKey | OutputValue |
+------------+-------------------------------+
| S3Bucket | test-s3bucket-1jsdfaabenntt |
+------------+-------------------------------+
I hope you use these aliases feature, and share your examples too!