How To Expand Your AWS Infrastructure To Europe

A high-level overview of how to setup a new production environment in Europe.

Many software companies in the US seek growth opportunities by expanding into Europe as a new revenue stream.

This post is intended for software engineers or engineering leaders interested in creating a new AWS region to unlock sales to European customers.

European Expansion can lift IPO valuation by 55% - Jamie Bristow [source]

At Telophase, we have worked with multiple companies to help them establish and maintain their multi-region infrastructure, expanding their business. In this post, we provide a high-level overview of the steps required to provision and set up your production infrastructure in Europe, as well as some of the decisions you will need to make along the way.

AWS Control Plane

This section outlines how you should set up a new AWS account, select a region, and provision your infrastructure as code to expand your infrastructure.

Create a New AWS Account

You have two options: you can either reuse your original AWS account or create a new one. Using a new AWS account for your new region is the best way to enforce isolation between regions. You can manage multiple accounts via AWS Organizations and configure login via AWS IAM Identity Center. Creating a new account has several benefits:

  • Cross-account IAM access needs to be explicitly granted by both accounts. [example]
  • Having distinct accounts can avoid inadvertent developer access to hardcoded items such as S3 buckets from another region.
  • It limits the scope of impact of adverse events such as security breaches or noisy neighbors.
  • Isolating costs per account enables financial attribution.

Creating a new account does make your infrastructure more complex, and some of your tools will need to be aware of the multiple accounts:

  • Your CI/CD system needs to assume new IAM roles.
  • Docker images must be pushed to multiple accounts or sourced from another account.
We recommend CI Systems use their US and EU accounts independently.

Pick a Region

When selecting a region, it is important to prioritize user experience and data compliance by considering the location of your users.

For your first EU region, we recommend using eu-west-1 for the following reasons:

It is the most cost-effective of the eu-west-* regions.

  • For example, the lowest tier PostgreSQL RDS instance is 5% cheaper in eu-west-1 than in eu-west-2.

eu-west-1 is one of the first regions to receive new features.

  • For instance, eu-west-1 was the first European region to receive Graviton 3 (source).

Audit Your Infrastructure as Code (IaC)

One of the challenges when setting up a new region in AWS is determining which resources are being tracked in IaC (Infrastructure as Code). Many companies grow organically without IaC, and only realize the need to adopt it for source control and compliance as they mature. This often results in a mixed bag of tracked and untracked resources.

To address this issue, we recommend taking an inventory of AWS resources that are being tracked in IaC. Additionally, any resources that need to be spun up in the new region should be imported. Managing resources across multiple regions with IaC ensures consistency.

With Terraform you can specify in your AWS provider what region to use and what role to assume for the specified region.

We recommend using Terraform or Pulumi for managing your IaC. Terraform has an extensive provider environment so you can use Terraform for a range of things from your AWS infrastructure to your GitHub Organization.

Once you have imported your AWS resources into IaC then you can plumb a new target region and AWS account through and duplicate your resources.

(plug) If you don’t have any IaC reach out to us at Telophase and we can help make the import process a breeze.

Right-size Resources

When you provision your resources in a new region, you won’t have any customers initially. Having unused production-sized infrastructure handling little traffic can be costly. Here are some cost levers to consider:

  • Decreasing min count of autoscaling services
  • Scale down Server and DB vCPU / Memory
Example terraform code for region specific configuration cpu and memory in a self contained module

One Terraform pattern for keeping company-specific modules contained is to define locals and perform lookups based on a few key variables, such as environment and region. This eliminates the need for plumbing the webserver_cpu from the root module and allows you to pass around a minimal set of Terraform variables.

Networking

When setting up a new account, you will have a new Virtual Private Cloud (VPC), static IPs, and a new entry point for your application. Below, we outline a few recommended networking changes to support an isolated environment.

Routing to Europe

We recommend using a subdomain for all your DNS records in Europe. For example, telophase.dev is our parent domain and then we delegate eu.telophase.dev to our European account. AWS provides these directions for delegating a hosted zone for a subdomain to another account. This grants our European AWS account complete control to provision new records.

The Parent account owns telophase.dev hosted zone and points the NS to the EU accounts hosted zone for delegation.

Delegating the subdomain to the new account makes creating things like SSL certificates for your load balancers or CloudFront all in the European account.

Determine Your VPC CIDR

When creating a new VPC your US and European CIDR blocks mustn’t overlap. If you want to peer your VPCs for cross-region communication, you’ll want to ensure that the CIDR ranges are unique.

VPC Peering example from AWS

Establishing VPC peering can enable cross-region coordination without sending traffic over the public internet. This is useful in situations such as running an ad-serving business with customers in the US region but needing to serve ads globally. In this case, coordination with VPCs in the regions where the ads are being served is necessary.

Originating Webhooks

Customers verify webhook IP addresses as an additional layer of security alongside validating webhook signatures to ensure that web requests being handled come from the expected sender.

It is common practice to publish your company's IP ranges so that customers can allowlist your IPs. AWS publishes an ip-ranges.json syntax to follow [source]. Within the syntax, is a region specification where you can constrain specific IP ranges for clear communication to EU and US customers. For example:

  • Datadog IP Addresses [source]
  • Stripe webhook IP Addresses [source]

Audit 3rd-Party Dependencies

Depending on your vendors, you’ll need to think about how you access 3rd parties. Here are some common cases:

Callback URLs for an auth provider

  • For example, app.telophase.dev/auth0callback will now need to include app.eu.telophase.dev/auth0callback. See Auth0 documentation for an example [source]

Oauth App URL redirects

  • Example: if you have a GitHub Oauth App and want to redirect a user back to your page after setup the redirect URLs will need to be updated [ref]

Metrics Provider

  • When sending metrics to a provider like Datadog, we recommend tagging all metrics with the  region to easily aggregate data
  • We recommend updating paging monitors to include the region for clear action as a result of a page

Analyze Your Data Model

It's important to ensure unique keys for internal data, such as organizations and users. When standing up completely independent databases, you lose the unique constraint at the database layer. Here is one approach for SERIAL (auto-increment) types in PostgreSQL:

Why Should IDs Be Unique?

Implementing unique IDs across distinct databases is critical because data teams will aggregate data across regions for high-level company overviews. Introducing collisions on assumed unique IDs will likely to produce unintentional data corruption via combining data for multiple organizations or overwriting as a few examples.

Auto Incrementing Keys

Auto Incrementing keys can be handled by setting a unique starting value based on a region. This allows you to divide up based on customer segments leaving room for more customers. For example:

ALTER SEQUENCE tablename_columnname_seq RESTART WITH anynumber; [source]

PostgreSQL SERIAL range allows from 1 to 2,147,483,647 which is typically a sufficient range for SaaS customers and Users.

We suggest reserving space for future expansion and considering how large your tables are

New Regions Are Never Finished…

Setting up new AWS regions requires numerous changes across your infrastructure. Depending on your customer type, you may have different business requirements, and the aforementioned is just the beginning.

At Telophase, we specialize in providing a white-glove experience to help your company go multi-region and easily maintain multi-region environments. We are here to help your company unlock business in the Europe.

Contact us at team@telophase.dev for a free consultation, and we will provide you with tailored advice based on your needs.

We plan to blog more about our experiences in helping set up and maintain multi-region environments. We would love to receive feedback on any of the topics discussed above and let us know if you are interested in any of the following:

  • Auditing your application logic for multi-region
  • Setting up cell-based architecture
  • Unifying views for multiple regions and AWS organizations
  • Deploying to multiple regions
  • Monitoring and alerting for multiple regions
  • Unified application login
  • Data model approaches for supporting multiple regions