AWS IAM operates at an immense scale, more than 400 million operations per second, and the stakes are frankly terrifying; a substantial portion of the internet runs on AWS, and access to those resources is regulated by IAM.

I’m therefore glad that the people who design and run IAM are so smart that it’s also frankly terrifying. The depth of expertise and wisdom backing up IAM is such that I am confident that I’m being provided the tools to secure my AWS resources, and that those tools will work as designed.

But to secure my AWS resources, I need to…

Note: this article uses the boto3, the AWS Python SDK, as an example, but other SDKs have analogous features.

I’ve found that newcomers to AWS can sometimes get confused by what it means to have AWS credentials, and that people have notions of “logging into AWS” that don’t really correspond to the way AWS access works. This article aims to explain the basics of AWS authentication — that is, the way you gain an identity that you can use to access AWS services. …

You’re writing some Python, and you need to write out a string containing newlines. You’ve got two options: a regular string with \n in it, or a multi-line string literal using three double quotes (are those sextuple quotes?), which looks like this:

my_string = """This
is a
multi-line string"""
assert my_string == "This\nis a\nmulti-line string"

But you’ve got a problem. The point in your code where you’re putting the string is indented, and those indents are showing up in your string, like this:

def get_string():
return """This
is a
multi-line string"""
assert get_string() == "This\n is a\n multi-line string"


My name is Ben Kehoe. I’m an AWS Serverless Hero. I’ve spoken at re:Invent. I meet regularly with teams across AWS. I’m followed by @awscloud on Twitter. But AWS doesn’t know who I am.

On GitHub, I’m benkehoe. I’m benkehoe when I’m building personal projects like aws-whoami, and I’m benkehoe when I’m building projects for iRobot like cfn-custom-resource (granted, it’s been a long time since we’ve released anything new), and I’m benkehoe when I’m contributing to open-source projects.

On AWS, I am:

  • Any one of several hundred IAM roles within accounts in iRobot’s AWS Organization, none of which bear my…

In 2018, AWS Lambda increased the maximum time a function can run from 5 minutes to 15 minutes. This was a great thing! Ever since then, people have been asking for another increase. And while I am fully on board with the need for serverless compute for longer workloads, I don’t think Lambda — or other FaaS platforms, like Google Cloud Functions — should increase its timeout much beyond its current limit. I’d rather get a new service to accomplish the goal.

The fundamental reason is this: systems make tradeoffs to achieve features. I believe that short-running and long-running compute…

AWS SSO permission sets are a collection of policies that get attached to a managed IAM role in every account the permission set is provisioned to (that is, a principal — a user or group — is given that permission set in that account). While the IAM role has a complex name, with the prefix AWSReservedSSO, followed by the permission set name, followed by a random tag, each separated with an underscore, when the user is signing in, the “role name” they see is just the permission set name.

This means you want to create permission sets that apply to…

I’ve seen some confusion around the AWS CLI v2 command aws sso login. In particular, suppose you have an ~/.aws/config that looks like the following:

[profile AcctA-Role1]
sso_start_url =
sso_region = us-east-2
sso_account_id = 111122223333
sso_role_name = Role1
[profile AcctB-Role2]
sso_start_url =
sso_region = us-east-2
sso_account_id = 777788889999
sso_role_name = Role2
[profile AcctB-Role1]
sso_start_url =
sso_region = us-east-2
sso_account_id = 777788889999
sso_role_name = Role1

(if you’ve been putting this in ~/.aws/credentials, read my explainer about AWS config files)

I have seen people get the impression that if they want to use Role1 in account A (111122223333), they…

I decided to write down the helpful features and settings I’ve discovered in Zoom.

How to leave a meeting quickly

Everyone knows that awkward pause. “Bye!” followed by several seconds of figuring out where your mouse pointer is and landing it on the “Leave Meeting” button.

You can make this less painful by using the keyboard to leave meetings.

First, disable the “Ask me to confirm when I leave a meeting” option in the “General” tab of the desktop app settings. This will reduce your time to leave even when you’re using the mouse.

Recently, I ran a poll on twitter asking how people interacted with boto3, the AWS Python SDK (why is called boto3? See the end of the article for an appendix on this). What I wanted to know is how many people used boto3 sessions, and how many people use the module-level functions. I asked which style people use:

s3 = boto3.client('s3')
ddb = boto3.resource('dynamodb')


session = boto3.Session()
s3 = session.client('s3')
ddb = session.resource('dynamodb')

The split ended up being about 70% in favor of the first option. In this article I’ll share why most application and library code I write…

There are myriad APIs in AWS services that allow services to accept large and/or binary content from you. Zip files for your Lambda functions, images for Rekognition, CloudFormation templates, etc. All of them have one thing in common: that content has to be provided as an S3 object. I think this leaves a lot to be desired.

First, accounts do not come with an S3 bucket to use for this purpose. There’s no “default” bucket you can use. If you use the CloudFormation console, your uploaded template file gets whisked away to an AWS-owned bucket. …

Ben Kehoe

Cloud Robotics Research Scientist at @iRobot

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store