Building A Dynamic vSphere/AWS Hybrid Cloud Lab - Part 1

Building A Dynamic vSphere/AWS Hybrid Cloud Lab - Part 1

In this blog series we'll walk through creating a dynamic lab hybrid cloud environment with a local (on-prem) vSphere environment and an AWS environment.

As more and more companies migrate workloads to public clouds like AWS and Azure, it's critical that those of us that are responsible for managing those workloads know how to manage them in the aforementioned public clouds.

Part #1 - Architecture Overview and vSphere Terraform buildout
Part #2 - AWS Terraform buildout
Part #3 - Building the Chef Cookbook for VPN connectivity
Part #4 - Building the test app

In the first part of this blog series we'll cover the architecture overview and the Terraform buildout for the vSphere side of the connection.

All the code from this series can be found on github.
https://github.com/martezr/terraform-aws-vsphere-lab

Architecture

In this design the goal is connect a web instance (Apache) running in AWS to a database instance (Mariadb) running locally in a vSphere environment.

We'll be using two CentOS 7 instances running OpenVPN to establish a client/server VPN connection to avoid opening any ports on the local vSphere side.

vSphere

The vSphere environment will utilize two existing standard switches to reduce the complexity given that Terraform does not support creating networks out of the box.

Networking

  • VM Network (192.168.150.x/24) - External virtual network with connectivity to the internet.
  • Hybrid (172.16.20.x/24) - Isolated virtual network where the database instance resides and connectivity is provided through the router instance utilizing NAT.

Instances

  • Router - The router will be a CentOS 7 instance that will leverage FirewallD to perform the NAT and OpenVPN for the VPN.
  • Database - Mariadb will be installed on the database instance and data will be loaded to provide data for the apache web instance in AWS.

AWS

The AWS environment will be composed of a single VPC with subnets in a single availability zone.

Networking

  • VPC Hybrid (10.0.0.0/16) - A single VPC will be used.
  • Public Subnet (10.0.0.x/24) - The public subnet will host the router instance for the AWS side of the VPN connection and be accessible from the internet.
  • Private Subnet (10.0.1.x/24) - The private subnet will host the web instance with connectivity provided by the router instance in the public subnet.

Instances

  • Router - The router instance will run OpenVPN to establish VPN connectivity to the router instance on the vSphere side.
  • Web - The web instance will run Apache and will have just enough functionality to test connectivity across the VPN tunnel to the database instance.

Chef

Chef will be utilized later in the series due to it's existing integration with Terraform as a built-in option for a provisioner.


Terraform

Terraform will be used to dynamically create the environments both on the local vSphere side as well as the remote AWS public cloud side.

The following steps are the high level tasks that we need to accomplish to build out our environment in vSphere.

  • It's assumed that there is an existing CentOS 7 template in the environment.

Step #1: Create an awshybrid VM folder to place the VMs
Step #2: Create the awshybridrtr1 virtual machine that will act as our vSphere VPN endpoint and router for the database instance.
Step #3: Configure the awshybridrtr1 virtual machine to act as a router.
Step #4: Create the awshybriddb virtual machine that will host the mariadb database server.
Step #5: Install mariadb and allow remote connectivity on the awshybriddb virtual machine.

Installing Terraform
The first thing we need to do is make sure that Terraform is installed on our machine.

https://www.terraform.io/downloads.html
https://www.terraform.io/intro/getting-started/install.html

Once it's installed on our machine let's grab the example code from github to get us started.

git clone https://github.com/martezr/terraform-aws-vsphere-lab  

Now that we've got the code we need to change to the directory.

cd terraform-aws-vsphere-lab  

In the directory are three files that terraform will need.

  • buildout.tf - Terraform code for building the environment
  • variables.tf - Variable definition file
  • terraform.tfvars - Static variable file

The terraform.tfvars file can be deleted if the desire is to be prompted for the variable information. There are other more secure methods than hard coding them in a static file.

provider "vsphere" {  
  user           = "${var.vsphere_username}"
  password       = "${var.vsphere_password}"
  vsphere_server = "${var.vsphere_server}"

  # if you have a self-signed cert
  allow_unverified_ssl = true
}

# Create a folder
resource "vsphere_folder" "awshybridcloud" {  
  datacenter = "GRT"
  path = "awshybridcloud"
}

# Create a virtual machine within the folder
resource "vsphere_virtual_machine" "awshybridrtr1" {  
  name       = "awshybridrtr1"
  datacenter = "GRT"
  folder     = "${vsphere_folder.awshybridcloud.path}"
  vcpu       = 2
  memory     = 4096

  network_interface {
    label = "VM Network"
    ipv4_address       = "192.168.150.10"
    ipv4_prefix_length = "24"
    ipv4_gateway       = "192.168.150.254"
  }

  network_interface {
    label = "Hybrid"
    ipv4_address       = "172.16.20.1"
    ipv4_prefix_length = "24"
    ipv4_gateway       = "172.16.20.1"
  }

  disk {
    template = "centos7temp"
    type     = "thin"
  }

  provisioner "remote-exec" {
    connection {
      type        = "ssh"
      host        = "192.168.150.10"
      user        = "root"
      password    = "password123"
    }

    inline = [
      "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf",
      "sysctl -p",
      "yum -y install firewalld",
      "systemctl start firewalld; systemctl enable firewalld",
      "firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -o ens160 -j MASQUERADE",
      "firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i ens192 -o ens160 -j ACCEPT",
      "firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i ens160 -o ens192 -m state --state RELATED,ESTABLISHED -j ACCEPT",
      "firewall-cmd --reload",
    ]
  }

}

# Create a virtual machine within the folder
resource "vsphere_virtual_machine" "awshybriddb" {  
  name       = "awshybriddb"
  depends_on = ["vsphere_virtual_machine.awshybridrtr1"]
  datacenter = "GRT"
  folder     = "${vsphere_folder.awshybridcloud.path}"
  vcpu       = 2
  memory     = 4096

  network_interface {
    label = "Hybrid"
    ipv4_address       = "172.16.20.50"
    ipv4_prefix_length = "24"
    ipv4_gateway       = "172.16.20.1"
  }

  disk {
    template = "centos7temp"
    type     = "thin"
  }

  provisioner "remote-exec" {
    connection {
      bastion_host = "192.168.150.10"
      bastion_user = "root"
      bastion_password = "password123"
      user        = "root"
      password    = "password123"
    }

    inline = [
      "yum -y install mariadb-server && systemctl enable mariadb && systemctl start mariadb",
      "mysql -u root -e \"GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password123'; FLUSH PRIVILEGES;\" && systemctl restart mariadb"
    ]
  }
}

The FirewallD and Mariadb installation and configuration will be handled via the Terraform inline provisioner.

  • The ssh connection to the database instance is proxied through the router instance as a bastion host since it's traffic is being NAT'd. This is the reason the database instance is built after and depends on the router instance.

Now that we've got our Terraform code in place let's kick of a build to test everything out.

terraform apply  

The apply command will take some time as it goes through provisioning the two virtual machines and getting them configured. Once it's all done we should see a message similar to that below letting us know that the apply is complete.

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.  

It's a good idea to now validate that both machines are properly configured as we expected before we add anything else.

Validation tasks

  • Log into the router instance and validate internet connectivity
  • Log into the router instance and validate connectivity to the database instance
  • Log into the database instance and validate connectivity to the internet
  • Log into the router instance and validate connectivity to the mariadb database on the database instance
    • Install mariadb client (yum -y install mariadb)
    • Connect to the database (mysql -u root -h 172.16.20.50 -p)

That covers the first part of the series in which we were able to standup everything we needed on the vSphere side of our hybrid cloud test environment.


References

Terraform Documentation https://www.terraform.io/docs/index.html

Centos 7 Firewalld Configuration
http://www.mjhall.org/centos7-firewalld-nat-router/

Subscribe to