Connect Azure Function to SQL server on Amazon EC2 via Cisco VPN

Rick Jen
Microsoft Azure
Published in
6 min readJun 8, 2020
Fullerton Station, Fullerton, CA (2020-02-13 7:30AM)

As a cloud solution architect, I travel often to meet customers (well, prior to COVID-19 😰). Flights, Uber, Lyft, Taxi … you name it. My favorite? Amtrak. Snapped a picture of this bridge right before boarding the train to San Diego.

“How do I access my SQL server in AWS VPC from Azure Functions?”

My customer asked.

In this story, I’m going to walk you through the steps of updating an SQL database in AWS (or, literally, anywhere else) from Azure Functions.

We will continue to use the Azure Function Premium Plan discussed in my previous story and leverage VNet Integration for the function app to make an outbound connection to the SQL server EC2 instance in AWS VPC.

Like all resources governed by enterprise security, this SQL server is running on an EC2 instance with a private IP 10.2.10.4 and accessible only from VPC or on-premises via VPN:

AWS Console

The network topology

Network Topology

Here are the networks we have:

  • On-Premises: 10.100.0.0/16
  • AWS VPC: 10.2.0.0/16
  • Azure HUB: 10.0.0.0/16
  • Azure SPOKE: 10.3.0.0/16

My customer is a Cisco shop: each site has a Cisco router and prefixes are advertised via BGP. In this story, we will deploy a Cisco CSR 1000v Cloud Services Router virtual appliance at each site. You will need deployment guides for: Azure and AWS.

We will build 2 IPsec tunnels over public IPs between:

  • On-Premises and AWS
  • On-Premises and Azure

Once the 2 IPsec tunnels are established, we will run BGP over the tunnels and peer the following 3 private networks:

  • Azure: AS 65001
  • AWS: AS 65002
  • On-Premises: AS 65003

Traffic between AWS and Azure will transit through On-Premises.

In AWS VPC, the SQL Server EC2 instance is deployed in the DB Subnet (10.2.10.0/24) with IP address 10.2.10.4

In Azure, our Premium Function App (the yellow box near the top) is integrated with the Spoke VNet through a delegated subnet (10.3.0.0/24). The Spoke connected to the Hub via VNet Peering. We will look at the Function App code and settings in another section below.

Basically, our traffic flow looks like:

Function ▶ Spoke VNet ▶ Hub VNet ▶ On-Prem ▶ VPC ▶ SQL Server EC2

Deploy the environment

If you have a similar setup already, skip this section and look into the VPN tunnel configurations on CSRs.

If you would like to build from scratch, here we go:

  1. Git clone and retrieve the scripts and IOS configs from my GitHub repo.
  2. Download and install Azure CLI to your local environment, opt to use Azure Cloud Shell, or, the Azure Cloud Shell in Windows Terminal.
  3. Modify and run those 3 .azcli scripts to provision the virtual networks, NSGs, UDRs, CSRs and test VMs. If you have an AWS VPC and subnets already, skip the AWS script.
  4. SSH to the public IP addresses of the CSRs and open those 3.ios scripts in text editor. We are ready to configure those 3 CSR 1000v routers.

Build IPsec VPN tunnels

👷 Go to your Azure Portal and AWS Console to retrieve the 3 Public IP addresses for those CSRs as in the diagram below.

⚠️ This section and next require basic understanding of IPsec VPN and BGP routing protocol. If you’re not comfortable with Cisco IOS, find someone who can help. You will likely need privileged access to the CSRs in order to execute the configure terminal command.

IPsec VPN Tunnels

Let’s build the On-Premises to Azure IPsec tunnel first:

Then build Azure to On-Premises tunnel. Likewise, build the CSR3 to CSR2 (AWS VPC) IPsec tunnel if you don’t have one already.

BGP fun!

In case you’re not aware, our Internet 🌎 is built on the BGP protocol for routing traffic from your browser to anywhere. We will run BGP on top of the tunnels to route traffic between Azure, AWS and on-premises.

Let’s look at the BGP settings in CSR3:

AS 65003 represents the on-premises network and there are 2 tunnels to Azure (tunnel 1) and AWS (tunnel 2). Be aware that ebgp-multihop is enabled as in the example above, since this is eBGP. You can change it according to your routing purpose — i.e. the number of hops needed to reach destination.

10.100.0.0/16 is the address space for on-premises. 10.100.10.0/24 is an internal subnet.

Note the last static route:

ip route 10.100.10.0 255.255.255.0 10.100.1.1

If you’re simulating the on-premises network in an Azure Virtual Network, 10.100.1.1 is the first available IP address in the Inside subnet of CSR3. This is the magic of SDN (Software Defined Networking)! You simply make it the next hop IP for any subnets in your VNet and let the Azure fabric route your traffic.

Build the same for AS 65001 on Azure CSR1 router and AS 65002 for CSR2 in AWS VPC if you don’t have one already.

⚠️ If you used the .azcli script to deploy the environment, you will notice there’s a UDR (route table) associated to the App subnet — so any VMs in that subnet can reach CSR1/CSR2/CSR3 and beyond through the IPsec tunnels once the BGP neighbors are established:

At this point, you should be able to route traffic between Azure and AWS via on-premises.

Azure Function VNet Integration

Let’s go to the Azure Portal and configure VNet integration for your Function App. In my environment, I have a delegated subnet 10.3.0.0/24 in the Spoke VNet, and this is where your Function’s outbound traffic will be NAT’ed to.

Function App VNet Integration

Remember to add a route (to AWS VPC 10.2.0.0/16 via CSR’s inside interface 10.0.1.4 as the next hop) in the UDR associated to the delegated subnet for Azure Function App:

Now, from the Function App’s console, verify we can reach the SQL server on EC2 via port 1433:

Able to reach SQL Server on EC2!

Finally, place the SQL server IP address in the connection string in your Function app:

Function App Settings

That’s It!

Your Function App can now access the SQL server running on AWS EC2 in a private VPC! 👏

In a production environment, there’s usually a firewall in the path, we are skipping that in this story. That’s something you will need to work with your security and networking team.

Now, back on Amtrak, we should have arrived at Solana Beach Station. More about that train station next time…

Have fun with Azure ☁️ and Go Serverless!! 💪

Bonus: The breakfast at the Santa Fe Cafe in Fullerton Station is such a treat! Try it out next time when you’re out here in sunny Southern California!

Bacon & Egg breakfast at Santa Fe Cafe

--

--