If you work at a startup, you know how slim the margin for error is. If your startup is building on AWS, then you may also know how easy it is to make mistakes on such a vast platform. After building a startup on AWS and advising dozens of startups doing the same, this is the practical advice I wish I’d been given early in my startup journey.
1. Leverage infrastructure as code
You should define all of your AWS infrastructure with some form of infrastructure as code, or IaC. There are myriad benefits covered in countless articles on the web, and I won’t rehash those here.
Aside from the primary value prop of IaC, there’s a supremely practical benefit: It’s much more productive.
Building out your infrastructure in the AWS console is painful and time consuming. That’s not meant to be an indictment on the teams at AWS that build and maintain the console; it serves a purpose and (mostly) serves it well. The main issue with the console is that you’re navigating to pages that are largely focused on a single service. If you’re building anything worth building, you’re going to be tying multiple services together. That’s much easier to do with IaC.
There are exceptions to this “single service” paradigm in the console, mostly when you’re working with higher level services like Amplify and Elastic Beanstalk. And we’ll continue to see progress to support common use cases and related services. But you’re still going to be better off building with IaC.
Popular IaC options
AWS’ first-party options
- CloudFormation (JSON, YAML)
- CDK (TypeScript, Python, Java, C#, Go)
- SAM (JSON, YAML)
Third-party options
If your team already has experience with an IaC solution, that’s probably your best bet. Otherwise, I prefer and recommend the first-party options. If I’m starting a new project, I always reach for the CDK because I love doing things like this:
Those 17 lines of TypeScript will compile (“synth”) into 395 lines of CloudFormation JSON. And it’ll package up the lambda code and deploy it as well. It’s so good.
2. Segregate your workloads into multiple accounts
Once you have your infrastructure defined in code through IaC, you should be able to quickly stand up new environments for dev, test, stage, prod, etc. Put each of these environments into separate AWS accounts. It’s far too easy to inadvertently modify production resources when you’re slinging everything into a single AWS account.
There is some overhead involved with managing multiple AWS accounts, but it’s worth the trouble. In fact, the “trouble” is a feature, not a bug.
Manual AWS Organization setup
To ease the administrative burden, set up an AWS Organization and add new accounts through the Organizations console. You’ll need a unique email address for each account. I typically follow a pattern like:
- [email protected] for the root account
- [email protected] for the prod account
- [email protected] for the test account
This should work for the majority of startups, though you might want to add the company name into the addresses if you have a more complicated org structure. Make sure your email provider supports “+” aliases, which will route all email to the root account. In Gmail, I can use these “+” aliases liberally.
The root (“management”) account should be kept free of any application resources. You’ll manage billing here by configuring the member accounts with consolidated billing and possibly DNS (Route53), depending on your setup.
You should also set up AWS SSO in the management account instead of IAM users. It’s super helpful for managing your team’s access to the various child accounts and is a better offering than the historical IAM approach. Your team members will thank you.
Automated setup with AWS Control Tower
An even better approach than setting up all of the above manually is to use AWS Control Tower. Control Tower gives you a simple way to launch a multi-account setup (called a “landing zone”) with tons of best practices implemented out of the box. There’s no additional cost associated with Control Tower itself, but it will add some minor costs to your bill by configuring services you might not have set up otherwise.
3. Set up continuous integration and continuous delivery
Every startup wants to continuously deliver value to its customers, but continuous integration and continuous delivery, or CI/CD, can be quite complex and daunting. AWS has a suite of services for managing this complexity, highlighted by CodeBuild and CodePipeline. I’ve also had great experiences with GitHub Actions.
Before you invest in either of these solutions, you’ll need a suite of automated tests that give you the confidence to ship frequent changes. There’s no shortcut here. If you’ve been building a product for months or years with little or no test coverage, adding CI/CD is a lot of effort to essentially break your product faster.
If you’re defining your infrastructure with the AWS CDK, then you should take a look at CDK Pipelines. It allows you to define your CI/CD pipeline in CodePipeline alongside your CDK InfraStack(s). As you push changes to your CI/CD pipeline, the pipeline self-mutates to keep itself up to date while also deploying any changes to your application code and infrastructure. It’s still in developer preview, but I’ve used it a ton and recommend it every chance I get.
4. Use cloud-native services
This is admittedly much easier in the early stage of building, but you’ll gain a lot when building with cloud-native services. Stedi founder Zack Kanter explained the concept of cloud-native services in an excellent Twitter thread:
“How can we use AWS/GCP in ways that we couldn’t possibly do better ourselves? This is called ‘servicefull’ architecture — using your provider’s cloud-native services to replace server code.”
Another gem from that thread:
“If you’re using AWS/GCP to run vanilla servers, you’re building software to work the same way it did when companies ran servers in their office 15 yrs ago. That should be a wake up call about your technology choices…”
This might require learning new skills and practices — it’s an entirely different way of architecting and building your application — but, for those that take the plunge, there are huge advantages.
“What about vendor lock-in,” you ask? AWS exec Matt Asay makes an excellent point:
“It’s always a matter of choosing ‘lock in’ strategically. No ‘lock in’ means you’re stuck with lowest common denominator commodity infra. Sure, you’re ‘free’! You’re also hurting your customers”
And hey, Begin co-founder Brian LeRoux argues that lock-in might even be a myth: “It’s a technical fantasy made popular by marketing.”
5. Get help
AWS expertise is a Thing™. There’s no shame in seeking outside help as you navigate all the complexities. If you need help implementing best practices on AWS, AWS IQ allows customers to hire third-party experts for any number of projects. You can post projects, choose qualified experts, and grant them access to your account directly from the platform. Payments made to experts show up on your AWS bill under the “Marketplace” category.
If you have the budget, AWS Enterprise Support gives you access to architectural reviews and tailored guidance starting at $15,000 a month. The more affordable Business Support tier offers a much more limited version of this, at a far cheaper price (starting at $100 a month).
Lastly, you can build the desired skills in-house by providing your engineering team with the resources and training necessary to get the most out of your cloud infrastructure. There are endless free and paid resources available on the web for cloud training, but a great place to start is the AWS training and certification portal.