Accessing and using AWS resources effectively and efficiently can be a daunting task as your team size grows. In this example, we're creating a tool that allows trusted users ( ones which are in our WayScript workspace ), to create S3 buckets themselves without the need of a system administrator or creating specific AWS IAM users for them. Our goals we'll tackle in this project include:

  • Identify a user and their permissions - should they be able to create a S3 bucket?
  • Receive metadata about the user's project in order to create an appropriately named and tagged bucket
  • Notify the user the bucket has been created

Watch the Tutorial

Building the Service

This section of the tutorial will have a few requirements and likely need to be done by an AWS admin. Those requirements include:

  • The ability to create an AWS IAM User with the appropriate S3 permissions for your use case
  • Be able to invite users to your WayScript workspace

AWS

We'll need to create a IAM user that has access to creating buckets in S3. Once we create this user we'll need to store the secrets of this user into a WayScript secrets file.

  1. Access IAM from the AWS console
  2. Select Users from the Access Management dropdown
  3. Click Add User

4. Follow the user setup, giving the user programmatic access

5. Create a group with the appropriate policies. In the following example there is a group named 's3_admin' with full permissions of S3 resources

6. Tag your user if desired and continue through creation. After creating your user you will be given the credentials needed. Be sure to copy these credentials before leaving this screen.

WayScript

  1. Create a lair within your workspace to host our service
  2. Create an app.py and requirements.txt
#app.py
from flask import Flask, request
import boto3

from wayscript import context

import os 

app = Flask(__name__)

# AWS SETTINGS
# The secret key and access key come from an IAM user
# These secrets should be placed inside the .secrets file and then accessed using os
# For help creating an IAM user with permissions view the AWS docs
# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html

region = 'us-east'
ACCESS_KEY = os.environ.get('ACCESS_KEY')
SECRET_KEY = os.environ.get('SECRET_KEY')

# WayScript specific functions
# WayScript provides detailed information about the user when they access wayscript hosted endpoints
# This is done using the WayScript SDK
# For more information view:
# https://docs.wayscript.com/building-tools/sdk

def get_user_details():
  application_key = request.headers.get('Authorization')[7:]
  user = context.get_user_by_application_key(application_key)
  return user

# AWS Resource Calls
# Boto3 is used in this example to access AWS resources
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html

def create_s3_client():
    client = boto3.client(
    's3',
    aws_access_key_id=ACCESS_KEY,
    aws_secret_access_key=SECRET_KEY
    )
    return client


@app.route('/create-bucket', methods=['GET', 'POST'])
def create_aws_resource_s3_bucket():
  if request.method != 'POST':
    return {'error': 'endpoint expected POST request with payload "project"'}
  if not request.json:
    return {'error': 'Missing Lair Context'}
  try:
    user = get_user_details()
  except:
    return {'data': 'logged out user.'}
  
  # Name Bucket
  # Name-Project-Env
  env_type = request.json.get('environment')
  project_name = request.json.get('name')
  
  bucket_name = str(user.get('first_name')) + "-" + project_name + "-" + env_type
  client = create_s3_client()
  response = client.create_bucket(Bucket=bucket_name.lower())
  return response 
  

if __name__ == '__main__':
  app.run()

To explain the above code, what we're creating is a flask application with an endpoint of /create-bucket

At this endpoint, we're accepting a POST request from the user ( Which is shown later in this tutorial ) that has context of the lair that they're sending the request from. What this allows is for our service to identify the user, lair, and environment, to create the appropriate S3 bucket for them.

Finally, the response we send back to the user is the response from AWS. This allows the user to be aware of an error codes and also receive a 200 whenever the bucket is successfully created.

3. Insert your AWS secrets into the WayScript secrets file. These secrets will need to be named the same name as you use in your os.environ.get('<secret-name>') above

4. Deploy your flask application via WayScript

The deploy trigger will give you the endpoint where your application is hosted. This endpoint + '/create-bucket' will be the endpoint in which a user will send a request to create their bucket.

How the End User Uses our Service

Once the service is hosted, a user can access it if they belong to the workspace. WayScript has built in user SSO which makes using tools like this one very straight forward.

  1. End user creates a lair and decides they need an S3 bucket
  2. They use the service endpoint and their lair context from a script and execute it via the terminal. That code looks like this:
import requests
from wayscript import context

lair = context.get_lair()

headers = {
    'Authorization': 'Bearer  d15a5b0e-c0a1-42fe-a73c-e8e2dbacdc3d'
}
lair_endpoint_url = 'https://surprisingly-spry-kudzu-clubhouse-dev.wayscript.cloud/create-bucket'

response = requests.post(lair_endpoint_url, json=lair, headers=headers)
print(response.content)

To explain the above code, we're sending a POST to our newly created service from within a lair. We pass that lair context to our service and the bucket is automatically created with name-project-env_type

Closing

WayScript services give us a solid, best practice forming foundation to build services like this one on top of. S3 is a simple showcase of this, as we take advantage of user SSO, selective permissions, environment creation and metadata, and package it all together to create a flask application that alleviates the pain point of creating user groups through AWS.