aws / aws/aws-cli

Add support for aliases in sub-command namespaces

Open
#7,386 2 comments 0 reactions 0 assignees View on GitHub
feature-request p2
Dominant language
Python
Stars
17.3k
Forks
4.6k
Avg merge
1d 2h
Merged PRs (30d)
13

Description

### Describe the feature

The AWS CLI has support for creating aliases at the "service command" level [(original PR)](https://github.com/aws/aws-cli/pull/2287), [user docs](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-alias.html). This is a proposal to add aliases at any level of a command space, e.g. `aws ec2 `, `aws ec2 wait `, etc.

### Use Case

Initially, we chose not to support aliases at any other level within the command hierarchy, primarily for scope. However, there are a few issues with aliases as they exist today:

* We have 300+ services which makes the top level namespace incredibly cluttered with increasing likelihood that an alias you define could overwrite an existing service or prevent a newly launched service from being accessible because a pre-existing alias overwrites it.
* It's hard to quickly find which top level commands are service commands vs. your aliases (ignoring the fact that user defined aliases are explicitly excluded from help/documentation).
* It creates an inconsistent usage between user defined aliases and built-in commands, e.g. `aws ec2-regions` could be a valid command that invokes a service specific API, but `aws ec2` or `aws iam`, which are built-in, are not valid (specifically incomplete) commands. Being able to create aliases as the "operation" level of the command hierarchy makes aliases more consistent with built in commands, e.g. `aws cloudformation list-stacks` vs. `aws cloudformation list`.
* You have to rely on a naming convention to be able to easily group aliases for a service together, i.e. `aws iam-roles`, `aws iam-`.

### Proposed Solution

In addition to the `[toplevel]` key, you can now specify additional sections in the alias file. The sections are denoted as:

`[command (\s+)+]`

or in other words `command` followed by one or more whitespace separated command names. For example:

* `[command ec2]`
* `[command iam]`
* `[command cloudformation wait]`

The contents of each section are the same as defined in the existing `[toplevel]` section.

## Replacement rules

For internal aliases (alias values without the `!` prefix), the alias value is replaced relative to the existing command hierarchy. In other words, the command namespace is prefixed to the alias value. For example, given:

```
[command ec2]
regions = describe-regions --query Regions[].RegionName
```

Then the following invocations are replaced as follows:

```
# Running:

aws ec2 regions

# Is (conceptually) replaced with:
aws ec2 describe-regions --query Regions[].RegionName
```

If you want to "break out" of the defined command namespace, you can use an external alias that invokes the AWS CLI:

```
[command ec2]
instance-profiles = !aws iam list-instance-profiles
```

Additional constraints/notes:

* You can't create a brand new command namespace, you can only add to existing command namespaces. In other words creating a section `[command james]` will not create any aliases if the `aws james` namespace does not already exist. I like the idea, but I'm not sure we should go down that path just yet.
* A namespace (in terms of implementation) specifically refers to having a command table of subcommands. So, for example, `aws cloudformation list-stacks` is *not* a namespace (there are no subcommands under that command, only arguments), so you couldn't create any aliases under `[command cloudformation list-stacks]`. FWIW this wouldn't be hard to implement, but I'm not sure it's a good idea. It would enable you to create pre configured sets of options that you can reference by an alias name, so you could do crazy stuff like:

```
[command cloudformation list-stacks]
# Note the alias value contains only options, no commands.
created = --stack-status-filter CREATE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text
deleted = --stack-status-filter DELETE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text
```

Invoked as:

```
aws cloudformation list-stacks created
aws cloudformation list-stacks deleted
```

which if you really wanted to customize, you could combine this with the recursive replacement of aliases and add:

```
[toplevel]
cfn = cloudformation

[command cloudformation]
stacks = list-stacks
```

which I *think*, but have not actually tried to implement this, should allow you to run things like:

```
# This is equivalent to:
# aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text

aws cfn stacks created

# This is equivalent to:
# aws cloudformation list-stacks --stack-status-filter DELETE_COMPLETE --query StackSummaries[].[StackName,StackStatus] --output text

aws cfn stacks deleted
```

On second thought, that actually is kinda awesome and I'm 99% sure this would work. Should we support this?

### Other Information

I volunteer to implement this feature.

### Acknowledgements

- [X] I may be able to implement this feature request
- [ ] This feature might incur a breaking change

### CLI version used

v2

### Environment details (OS name and version, etc.)

All of them

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.