I Built A Serverless Ephemeral AWS Account Vending Machine


Last November 2024, I attended an AWS user group meetup in Barcelona. I found Joan García's sessions particularly interesting. He explained how they addressed some recurring challenges at Ocado, such as safely conducting proofs of concept or running hackathons without disrupting production environments while keeping costs under control.
Unfortunately, this session was not recorded. I won’t get into the details but, in short, they implemented a way for their teams to request ephemeral, self-destructed AWS accounts. Users request an account to run a PoC, a hackathon, a workshop, etc. After a set time, or when a specific budget is reached, all the resources in the account are automatically deleted, and the account is closed. In other words: an AWS account vending machine.
I thought it was a great idea! We all love to play with new AWS services, run quick PoCs, etc. but I often forget or am too lazy to clean up after myself, which clutters my AWS accounts with unnecessary resources. In some cases, it can even incur unnecessary costs.
Although Infrastructure as code helps with the tear-down process, I don’t always dot it. Sometimes, I don’t even use IaC, especially if I just want to test or try something quickly. The idea of getting an ephemeral AWS account that I can mess with, and knowing that everything in it will automatically get destroyed later sounded very attractive. The bad news was: Ocado’s solution is not open source... So I re-built it myself.
Requirements
Here are the requirements I had in mind before starting this project:
Security
All sandbox accounts should stay secure within the same AWS Organization.
Users can only access accounts they are supposed to. e.g. they can’t access other user’s accounts.
Users should access the vending machine and sandbox accounts using their SSO credentials.
Low Cost: The solution should be cheap to run (What’s the point of building this to save on costs if the solution itself ends up costing more than the savings?). For that reason, I wanted the solution to be 100% serverless.
Simple:
Users should be able to easily request new accounts through a simple Web App.
Users should access sandbox accounts from the AWS access portal, or the AWS CLI, using SSO, just like they do for any other long-lived account (e.g. dev, prod).
Solution Overview
This solution uses IAM Identity Center. Users sign in using SSO to access AWS accounts under the same organization. They access a web application where they can request a new sandbox account. When a user introduces a request, an account is randomly picked from a pool of AWS accounts specially created for this purpose. It is assigned to the user with a pre-determined Permission Set in IAM Identity Center. The user can then sign into the account using the AWS console, or the AWS CLI with SSO. When the sandbox expires, or when the user requests it, the account assignment is removed. The user loses access to the account and all the resources are deleted using aws-nuke (aws-nuke
is an open-source utility that deletes all the resources in an AWS account). Finally, the account is recycled and put back into the account pool for future assignments. Administrators can control who can access the web application.
How it works
Here is an overview of the architecture.
Sandbox Accounts
Sandbox accounts are organized in an Organization Unit (OU). These are the accounts that are assigned to a user when they request one. They don’t hold any resources except for SSO roles and a special role: AWSNuke
to which we’ll come back later.
Management Account
This is the management account for the AWS organization structure. Users live in this account (in IAM Identity Center). This account also holds a special cross-account role: VendingMachine
. This role is assumed by the Vending Machine service to assign or revoke access to an account for a specific user.
Vending Machine Account
This is the Vending Machine service. The service is composed of the following components:
A static website
This is a React SPA which the users use to request a new sandbox. It is stored on S3 and served by AWS CloudFront distribution.
AppSync API
An AppSync GraphQL API is the gateway between the users and the service. It triggers the Assign Account
and Release Account
Step Function workflows (see below).
Amazon Cognito
A Cognito user pool controls user authentication to AWS AppSync. IAM Identity Center is used as an Identity provider using SAML.
Accounts DynamoDB Table
This DynamoDB table contains information about the sandbox accounts such as their id and status (e.g. USED
or FREE
). When in use, it also stores who is using the account (user id), when it expires, etc.
EventBridge Scheduler
When a user requests an account, a schedule is created at the expiration date to destroy it and return it to the account pool.
Assign Account Step Functions Workflow
When a user requests a new account, the AppSync API starts this Step Function Workflow, which orchestrates the assignation of an account to the user.
First, it tries to find an available account (i.e. an account that is not already used by another user (status = FREE
) and immediately locks it in DynamoDB (status = USED
) so that no other users can have the same account assigned to them.
After that, the workflow invokes the CreateAccountAssignment command to assign the account to the requester user. It does so assuming the VendingMachine
role in the management account.
Finally, we schedule the execution of the Release Account
workflow at the expiration date of the account. By default, it’s 14 days after the request time, but the user can request a shorter or longer period. We also put an accountAssigned
event into an Event Bridge bus to let other services know about it. This event is used by the EventBridge AppSync integration to notify the user that the account is ready, in real-time.
Release Account Step Functions Workflow
This other Step Function workflow orchestrates the destruction of an account; either when it expires (triggered by the EventBridge scheduler), or because the user requested it through the web app when it’s no longer needed.
First, we check if the user initiated the destruction. When this is the case, we delete the schedule that we created when setting up the account. When triggered by the EventBridge scheduler, the schedule is automatically deleted (We set ActionAfterCompletion: 'DELETE'
).
Then, we remove access to the account from the user using the DeleteAccountAssignment command. We also remove the user association in the accounts
DynamoDB table.
Then, we invoke aws-nuke
. Since it’s a long-running process, it is executed within an ECS task running on Fargate. aws-nuke
assumes the AWSNuke
role within the targeted account and uses that role to delete all resources.
Finally, we release the account in DynamoDB so that it can be re-assigned to another user later.
Cost Estimations
Assuming a moderate usage of this service, the operational cost should be close to zero.
With an average of 10 account requests per month, here are the cost estimations of the main components:
AppSync API
API requests: < 1000 requests(1) at $4/million requests = ~$0.004
~10 real-time updates at $2/million = ~$0.00002
< 10 connection minutes at $0.08/million minute = <$0.0000008
(1) Assuming that users consult the web app more often to check expiration times, etc.
DynamoDB
Usage should stay under the free tier. Outside free tier:
~50 write requests = $0.00003125
~1000 read requests = $0.000125
<1MB storage = $0.00025
Cognito
50 MAU (Monthly Active Users) are free (with SAML identity provider).
$.015 per MAU after that.
Step Functions
~150 state transitions. Within the always-free tier of 4,000 state transitions per month.
Outside the free tier, at $0.025 / 1,000 transitions: $0.025 × 150 / 1000 ~= $0.00375
EventBridge (Event bus and scheduler)
~10 events per month: ~$0.00001 ($1 / million events)
~10 schedules per month: Well under the 14M schedules free tier; or ~$0.00001 ($1 / million schedule triggers)
Static Website
S3: ~1.4 Mb - $0.023 x 0.0014GB = $0.0000322
Cloudfront: CloudFront has an always-free tier of 1TB data transfer and 10M HTTPS requests, which is probably more than enough for this use case.
ECS Fargate
Probably the highest cost. This solution uses the lowest configuration possible (0.25 vCPUs and 512 MB of memory). Assuming an average of ~15 minutes execution each time.
CPU: 0.25 vCPU x 0.25 hours x 10 x $0.03238 = $0.0202375 (ARM architecture)
Memory: 0.5GB × 0.25 hours x 10 x $0.00356 = $0.001869
Total cost
Even excluding the free tier, the total cost of operation should not go over a few cents per month. Of course, your mileage may vary, depending on the size of your organization, the number of users, and how many times the service is used.
It’s Open Source!
This project is open-source, you can find it on GitHub. Feel free to fork it and deploy it into your account, share it, and send me your feedback!
What’s Next?
This solution is basic. I built it both as a PoC and for the challenge. It’s also good enough for my personal usage and as an MVP. However, I can see a few improvements that could be added:
User notifications: Before an account is destroyed, users might want to get warned a few days before it happens.
Budgets: I didn't include budget limits in this MVP, but automatically removing costly resources before they increase your AWS bill would be a useful feature.
Time/Budget Extension: Need more time/budget to work on your project? Request an extension.
Multiple Permission Sets: The current implementation grants the
AdministratorAccess
permission set by default. One might want to support more than one permission set, depending on the use case the account is created for, or who requests it.Team accounts: When working with teams, you might want to assign an account to a team, instead of single users, so that several people can work on it at the same time.
Manager approval: Companies might want to require approval by a manager before an account is granted to a user or team. Managers could also be able to control expiration times, budgets, permission sets, etc.
Conclusion
Trying new AWS services, making proofs of concepts, or attending workshops can easily clutter your AWS accounts and incur costs if you forget to clean up after yourself. Ephemeral, self-destructed AWS accounts can help eliminate or mitigate those problems. With a self-service vending machine, users can request sandbox accounts to play with and focus on their projects while the cleanup process is automated.
Subscribe to my newsletter
Read articles from Benoît Bouré directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Benoît Bouré
Benoît Bouré
👨💻 Sofware Engineer · 💬 Consultant · 🚀 Indie Maker · ⚡️ Serverless 🔧 serverless-appsync-plugin · serverless-appsync-simulator · middy-appsync 🐈 and 🍵