- Clone this repo then
cd
into the cloned directory - Run
http-server
to serve the index file - Visit the Cloud Browser in your browser
At this point, you should see the Settings
page where you can enter your AWS Key
and Secret
. Save those values locally to your browser's Local Storage.
- Make sure you have a tool like
http-server
installed to serve static pages locally - AWS account with Key and Secret. The default region is set to
us-east-1
. Feel free to edit the value in index.html if you want to use some other area.
It is a programmable, read-only browser based interface to your AWS resources.
- AWS SDK aws-sdk-2.941.0 served from https://sdk.amazonaws.com/js/aws-sdk-2.941.0.min.js. I used V2 of AWS CLI to keep the setup simple. You can reduce the amount of code being sent over the wire by switching to V3 and only include AWK SDK objects that you care about.
- Bulma CSS 0.9.3 served from https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css. it's the only CSS I know but I'm sure a half competent UI developer can make the interface look very nice
- VueJS 3 from https://cdn.jsdelivr.net/npm/vue/dist/vue.js. I use it in the browser mode to keep the setup simple.
- FontAwesome
- GoatCounter for metrics
Cloud Browser runs purely inside your browser and makes no server/backend network calls to anything other than AWS and OpenAI. You can verify this by monitoring your network traffic in browser DevTools. So, the app is as secure as your browser.
-
The AWS console is a general purpose tool. That being the case, it is very common to have to click through a myriad menu options to surface information relevant to your specific use case.
-
There is a lot of (understandable) handwringing that happens around giving AWS access to contractors and consultants. Adding and updating IAM policies to make sure every consultant/contractor is only seeing what they are supposed to see is an exercise no one enjoys doing. Plus, this busywork takes time away from actually building stuff.
-
Product and engineering leadership want access to AWS without the cruft and want an easy way to get things done in there without (a) having to learn the ins and outs of AWS (b) having to wait for days for a principal engineer to actually build what they want. An example of this could be a SVP of technology wanting to show some interesting access patterns to the SVP of marketing using CloudFront logs.
To answer this, we need to define two roles: a Cloud Browser Guru and a User.
A Guru is the person responsible for maintaining and enhancing the Cloud Browser interface for your AWS account. The Guru is functionally equivalent to a Jira admin. They can edit and enhance the interface that a User sees.
A User accesses Cloud Browser on their browser and uses it to read/query data from AWS. A User has no role to play to make Cloud Browser usable.
To help a Guru build a use case specific AWS interface, Cloud Browser has defined a DSL.
The key insight behind the DSL is that a typical AWS case involves listing resources, following by drilling into one instance of that resource, then seeing more details about that resource. For example, you may list all your Lambdas, then drill into one Lambda, then check its concurrency setting or handler code.
Luckily for us, AWS provides a Javascript SDK to be used in the browser to help us list, drill, and show specific resources.
Here is an example of this in action. Read the Glossary further down in this document while referencing this example.
{
"list": {
"func": "listFunctions",
"key": "Functions",
"section_header": "Your Lambda Functions",
"title": "FunctionName",
"subtitle": "Version, Description, Runtime",
"next": "drill",
"loading_message": "Downloading Lambdas..."
},
"drill": {
"func": "getFunction",
"params": "FunctionName=$FunctionName",
"section_header": "Your Function",
"title": "Configuration.FunctionName",
"subtitle": "Configuration.Runtime, Configuration.CodeSize, Configuration.LastModified, Code.Location",
"loading_message": "Getting Lambda details...",
"empty_message": "No function found",
"formats": {
"subtitle": {
"Configuration.LastModified": stringAsDate,
"Code.Location": stringAsLink,
"withLabels": true
}
},
"next": "show",
"action_hooks": {
"openai": {
"prompt": "explain this code in plain english to a senior software engineer:\n ",
"parameter": "Code.Location",
"injection_method": "download",
"button_label": "Explain Function",
"textarea_default_value": "\nPaste this Lambda function"s code here then have OpenAI explain what it does..."
}
}
},
"show": {
"func": "modal",
"title": "Configuration.FunctionName",
"section_header": "Your function details",
"subtitle": "*",
"empty_message": "No details found",
"formats": {
"subtitle": {
"Configuration."Layers"": jsonAsString,
"withLabels": true
}
},
"next": "show",
"action_hooks": {
"openai": {
"prompt": "explain this code in plain english to a senior software engineer:\n ",
"parameter": "Code.Location",
"injection_method": "download",
"button_label": "Explain Function"
}
}
},
"apiVersion": "2015-03-31"
}
breadcrumbs
are name/value pairs you want to carry forward into down the stack. E.g., you may want to pass the Athena CatalogName down the stack while reading Athena tables since CatalogName is a required parameter for list-table-metadata
.
Lambda
corresponds to the Lambda client object defined by the SDK.
list
, drill
, and show
are three keys inside Lambda. list
is the only required key. Your next step could be called anything you want so long as you specify the correct next
value defined below.
func
: is the name of the function that the you would like to call on the SDK's Lambda object. E.g., listFunctions
corresponds to this Lambda API. func
can have a special magic value of modal
which displays data in a browser modal
params
: a comma separated Name1=$Value1, Name2=$Value2
string. Here, Name1 | Name2 | ...
correspond to the param name expected by the AWS SDK. $Value1 | $Value2 | ...
correspond to the value of the variable whose name is Value1 | Value2 | ...
. E.g. if the params string is foo=$bar
, then the API call would expect a variable called foo
and the value of foo
would be value of bar
.
section_header
: is the title of the page as shown in the browser to the user.
key
: sometimes, AWS returns a list of data attached to a specific key. E.g., the response to listFunctions
results in a dictionary with root Functions
. Specifying the key
as Functions
makes it easy to identify the array whose elements we need to show as a list.
title
: the name of the resource. E.g., setting title to FunctionName
lets you display the name of the Lambda function.
subtitle
: some extra information about the resource to help users correctly identify the resource. The subtitle
can be one of three values: '*', '', or a comma delimited string. In this case, Version, Description, Runtime
are a comma delimited set of keys. Their values, concatenated as a comma delimited string, form the displayed subtitle.
next
: is the name of the next function to call when the user clicks on a specific lambda. Since list
is followed by drill
-ing into a specific function, next
is set to drill
.
loading_message
is the message to be shown while the underlying data is being requested from AWS by SDK.
empty_message
: is the message to be shown when there is no data available to be shown.
formats.title
| formats.subtitle
: how specific fields within the title or subtitle should be formatted. E.g., if your subtitle includes a date, you could request it to be formatted into a human friendly form. Links can be formatted as anchor tags with the anchor text of Link.
withLabels
: specifies that the formatting should include the label from where the data is being read. E.g., if withLabels
is set to true, subtitle will say Version=$Latest, Runtime=nodejs14.x,...
and so on. If withLabel
is not defined or is set to false, the subtitle will say $Latest, nodejs14.x, ...
without the labels.
action_hooks
: this is a bit of a value added feature. You could ask the interface to display various bells and whistles at any level of the interface. E.g., you could ask the interface to display an OpenAI textbox and set up a prompt to tell OpenAI what to do. In this example, we have asked OpenAI to explain what a given Lambda function does.
A special note about the prompt
field inside action_hooks
. Since the prompt
might only make sense if some contextual information from the AWS resource is included, the prompt
can include two special string $title
and $subtitle
. While create the Open AI request, $title
and $subtitle
will be replaced by the actual value of title
and subtitle
.
- I liked the technical challenge.
- I've always wanted a better interface to view my AWS resources.
- Maybe this will be it for some definition of it