×

AWS CLI aliases: shorten your most used commands

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!

Picture of Martijn van Dongen
Martijn van Dongen
Chief AWS