Skip to content

About balcony

Python lets you inspect anything on runtime

In Python, everything is an object. Even the modules are objects.

When a module is imported, it can be queried for its composite objects on runtime.

Listing boto3 scope
print(dir(boto3))
# [..., '__version__, 'client', 'docs','resources', 'session', 'utils']

AWS SDK exposes the AWS API on service basis, accessible through service clients.

iam_client = boto3.client('iam')

balcony parses boto3 clients

For each available AWS service, its boto3.client is created and parsed for it's functions.

Every client has a _PY_TO_OP_NAME mapping that looks like this:

key value
attach_role_policy AttachRolePolicy
detach_role_policy DetachRolePolicy
create_role CreateRole
delete_role DeleteRole
get_role GetRole

_PY_TO_OP_NAME represents a mapping from the pythonic function names to actual AWS HTTP API operation names.

AWS API Operation names follows a nice Verb+Resource(s) convention.

Read-only operations have Get, List, Describe verbs.

balcony only uses the read-only operations

Balcony only uses the Operation names starting with Get, List, Describe verbs.

This means that it won't take any action on your AWS account other than reads.

Quick look at some of the IAM operations

Let's take the a look at IAM client, and how balcony groups them together.

Here's some IAM operations:

get operations list operations
GetGroup ListGroups
GetGroupPolicy ListGroupPolicies
GetPolicy ListPolicies
GetRole ListRoles
GetRolePolicy ListRolePolicies
GetUser ListUsers

Operations can be grouped under their resource names

Naming convention allows parsing CamelCase operation names to Verb+ResourceNodeName(s) format. Plurality is also taken into account.

Some operations have the same ResourceNodeName but a different Verb.

Resource Node Operations
Group GetGroup, ListGroups
GroupPolicy GetGroupPolicy, ListGroupPolicies
Policy GetPolicy, ListPolicies
Role GetRole, ListRoles
RolePolicy GetRolePolicy, ListRolePolicies
User GetUser, ListUsers

These operations are grouped under their respective ResourceNode. Here's the tree view of an example resource node:

Composition of ServiceNode, ResourceNode and Operations
ServiceNode: (iam)
├── ResourceNode: (Role)
│   └── operation_names: list
│       ├── GetRole
│       └── ListRoles
└── ResourceNode: (Policy)
    └── operation_names: list
        ├── GetPolicy
        └── ListPolicies