Building an Inclusion, Diversity & Equity (ID&E) startup on AWS

AWS has an huge commitment to ID&E. Their flagship annual conference (AWS re:invent) featured a very impressive ID&E track, and they are genuinely invested in creating a more inclusive culture.

So when we set-up Divrsity choosing a cloud vendor for Divrsity, AWS was the obvious choice.

And, even though we'd used both GCP and Azure on previous side-projects, AWS seemed to do the best job of abstracting away the myriad of complex infrastructure components required to run an ecommerce business in 2022.

As we progressed through setup, it became more and more obvious that Divrsity should go all-in on AWS; using native AWS services whereever possible. In-hindsight, selecting a single provider for as many services as possible is blindingly obvious (hindsight is 20-20): as a startup, we don't want to be setting up dozens of different billing accounts in order to bring the idea to market.


Ecosystem of components

What we didn't realise at the start is that most AWS components have a pretty good understanding of their dependencies/neighbours; meaning it's often a single button click (and a 60 second wait) to make the various services work together.

A great example of this integration is Route53. Previously we've had experience with a variety of domain registrars (including Google, GoDaddy, 123-reg) so our initial plan was to use one of those. Fortunately, the fact that we already had billing set-up with AWS and a desire to keep Divrsity management clean made us go with Route53.

Thank goodness for that (accidental) decision; suddenly a cascade of things were trivial to configure: AWS Simple Email Service (SES) for outbound survey comms (including DKIM and all the associated super-gnarly DNS configuration); then setting up AWS Workmail to manage the @divrsity.team mailboxes; which made it easy to redirect bounced survey invitations into a SNS queue and on to SQS; as well as set-up Elastic Beanstalk to serve the primary website; which also made it a couple of clicks to configure the load balancer with an SSL certificate.


Elastic Beanstalk For the Win

Talking of the website, we'd originally intended to go with a separate domain for the static pages and the app. That was before we discovered that ElasticBeanstalk already includes Nginx that is pre-configured to serve static assets. Now we have a single deployment for the public-facing website and the ruby application. At some point that's going to need to change but, while we're a tiny startup, simple is good.

Admittedly Elastic Beanstalk wasn't all plain sailing. Initial setup didn't work at all (load balancer wasn't talking to Nginx which wasn't talking to Rails, which we could only figure out by logging in to the box, which we couldn't do because it didn't have a key), and we literally spent two whole days trying to get the Nginx component working because we assumed that AWS was right and we were doing something wrong. Eventually we gave up completely on the pre-canned Amazon config and wrote our own (which is also more secure). See our elastic beanstalk journey for more tech info

It's probably taken us a month from having a base understanding of AWS to being fairly proficient at driving all the components, and figuring out why things aren't working (N.B. it's almost always security group configuration and/or IAM roles).

Still, the site is now live and now we've moved from infrastructure / code to days of fighting with Google Analytics/Ads/Search Console. After four days we're still waiting for google to index the site; and waiting for our Google Ads account to be validated so we can give them money! The tools are clearly designed for people who have made careers from Search Engine Marketing rather than mere startups who presumably don't pay the Google bills...


The Divrsity Tech stack version 1.0

This is likely to change beyond all recognition in the next few months, but here's the Divrsity tech stack so-far:

  • Elastic Beanstalk for the Rails app / Nginx. This dealt with a whole bunch of stuff we don't need to care about including EC2, Autoscaling groups and Load Balancers.
  • RDS Postgres, which was initially configured by Elastic Beanstalk but we broke it away fairly early on (one button click, wait 2 minutes), so that it wasn't tightly coupled to that environment. It's worth noting that even on a small [Graviton2] box RDS is fast... much faster than I'd expected
  • AWS Lambda (running a Java function) for handing async workflows such as sending invites and summarising survey responses
  • Route53 for DNS
  • Simple Email Service for outbound e-mail
  • SNS and SQS for bounced survey invitation processing (did I mention how things not working are always IAM roles and/or security groups)
  • Secrets Manager because it's crazy how many keys you need to write down/remember when you're setting up a new venture
  • Workmail for corporate e-mail and calendaring
  • And we're currently even using CodeCommit for git since we're bound to end-up automating a bunch of stuff in the future

There are two non-AWS components in the stack; largely because they looked awesome, already had very comprehensive Rails support and were baked-in to the template that we'd chosen (the truly amazing https://jumpstartrails.com/):

The only component that we've really had to spend any time choosing is HubSpot for Customer Relationship Management. We chose it because it's pretty much the de-facto standard for CRM so we can hire a team that don't have to spend time learning the tool. It also has a huge advantage that their API is pretty good, meaning we can automatically upload events (such as customer sign-ups) to ensure nobody falls between the cracks

The next thing to do with infrastructure will be to add CloudFront so that I can kill off the traffic that's trying to see whether we're running php and compromise the server! Traffic that literally started within 5 minutes of the service being up - man some people need to get a life! Since the questions are the same for every survey for a given company, that'll also have the benefit that CloudFront can edge cache the survey questions and remove a bunch of ugly load from the database/rails app.


What matters to startups?

AWS has clearly saved us tonnes of time getting us to the start line but, as a bootstrapped startup, they have come up trumps where it really matters - cost. Once the site was vaguely live, Divrsity was able to join the AWS Activate Founders programme (https://aws.amazon.com/activate/) which provides $1,000 in AWS credits. Consequently, our total bills for December and January are $31 - the cost of the .team domain registration - and not a penny more.

By the time we burn through the credits, we'll hopefully be running a business with actual revenues, and helping companies deliver measurable improvements in Diversity & Inclusion.


More Blog Articles

Learn why we created Divrsity
Understand how Lenses help you create an inclusive company
Learn how we ensure employee anonymity


To whom it may concern... The Elastic Beanstalk journey:

  1. ElasticBeanstalk configured NGinx to connect to http://unix://tmp/sockets/puma.sock:3000 which didn't seem to work at all. This may or may not be a permissions issue, but to get somewhat live, we just configured the load balancer to connect direct to Rails for a subset of URLs.
  2. For some reason, the default NGinx configuration didn't seem to want to serve the index.html file from /public when users connect to https://diversity.team/. Creating our own .platform/nginx/nginx.conf turned out to be the best and easiest solution (no idea why we resisted it for so long). This enabled us to redirect the load balancer for all traffic to Nginx and brought the benefit of enhanced security: the default rules forward anything that doesn't match to the Rails app, whereas the new version only forwards known URLs.
  3. Nginx is clever and offloads large post messages to disk rather than just blowing it's memory. Unfortunately ElasticBeanstalk has a permissions issue. The trick was to create .platform/hooks/postdeploy/enable_large_submit_for_nginx.sh, and add chmod a+rx /var/lib/nginx /var/lib/nginx/tmp