In this lab you will learn how to setup a secure hybrid configuration between a GCE project and an on-premise server (for the purposes of the code lab the on-premise server will be emulated by setting up a different GCE project. The example app we will be using as the vehicle for the lab is a LAMP stack Memegen app. We will keep the MySQL database containing the meme images and meme text in the on premise server but migrate the web server and web app front end onto GCP. Specific items covered are user of Network Admin IAM role, VPN and subnetwork setup. Secure web server setup with Firewall rules.

Self-paced environment setup

If you don't already have a Google Account (Gmail or Google Apps), you must create one. Sign-in to Google Cloud Platform console (console.cloud.google.com) and create a new project:

Remember the project ID, a unique name across all Google Cloud projects (the name above has already been taken and will not work for you, sorry!). It will be referred to later in this codelab as PROJECT_ID.

Very Important - Visit each of these pages to kick-off some initial setup behind the scenes, such as enabling the Compute Engine API.

Compute → Compute Engine → VM Instances

You might see a new task appears on the bottom right corner, you don't need to wait for them to finish to keep going.

Once the operations completes, for this codelab you will do most of the work from the menus.

Note you can also do all of these actions from Google Cloud Shell, a command line environment running in the Cloud. This Debian-based virtual machine is loaded with all the development tools you'll need (docker, gcloud, kubectl and others) and offers a persistent 5GB home directory. Open the Google Cloud Shell by clicking on the icon on the top right of the screen:

Finally, using Cloud Shell, set the default zone and project configuration:

$ gcloud config set compute/zone us-central1-a
$ gcloud config set compute/region us-central1

You can pick and choose different zones too. Learn more about zones in Regions & Zones documentation.

In this lab, you will build three instances of the a meme generator app. All instances will be built using Linux, Apache, MySQL and PHP - ie. a LAMP stack. The first version will be organized as if it is an on-premise standalone server. Once that version is in place. We will then partition the app so that the MySQL database holding the key data remains on-premise but we now put the front end into GCP, using IAM roles to set up a required VPN and Firewalls. Finally, we will build a full GCE version and migrate the data from the on-premises version.

First we start with implementing the on-premise environment version of the application using GCE (Google Compute Engine). You will be creating an instance, deploying Apache, MySQL and PHP packages in succession.

Create Debian a 8 machine

In your Google Cloud Platform (GCP) console (https://console.cloud.google.com/ ) select your project or create one.

In GCP console select Compute Engine

In VM Instances click in Create Instance


Select the name for your instance, your zone (us-central1-a), machine type
(1 vCPU), Boot disk (Debian GNU/Linux 8.3 (jessie)), Allow HTTP and HTTPS Traffic and create

Now you have a Debian 8 Instance up and running.

Install Apache 2.4.10

Access you Debian 8 machine:

If it is the first time that you access your machine, please execute the command:

$ sudo apt-get update

After that, execute:

$ sudo apt-get install apache2

Access the url the server in your browser. http://<ip machine>. If you see :

Check if it's working by entering your browser:

http://<ip machine>

Install MySQL 5.5.46

Execute

$ sudo apt-get install mysql-server php5-mysql

Include your password (ex. khn2160200310)

Always set a new root password, you should never leave the default or worse empty.

To keep your new database server safe, there is an additional script you need to run:

$ sudo mysql_secure_installation

Don't remove the remote access to admin :) (We will need this later in Code Lab, but in production environment you should remove this access)

To check if MySQL is running, execute

$ sudo /etc/init.d/mysql status

Done !!! Now you have MySQL installed

Install PHP 5.6.17 and packages

For PHP installation, execute:

$ sudo apt-get install php5-common libapache2-mod-php5 php5-cli php5-ldap

Then, restart Apache on your machine

$ sudo /etc/init.d/apache2 restart

Now we will create a php file in /var/www/html:

$ cd /var/www/html
$ sudo vi info.php
$ paste <?php phpinfo(); ?>
$ more info.php
<?php phpinfo(); ?>

Access the Server URL in your browser. http://<machine ip>/info.php

If you see :

PHP is working

Congratulations !! Now you have LAMP Environment up and running.

Once the environment is setup, now we will deploy a PHP-MySQL application on the on-premise machine.

With the environment setup, now we we get, configure and deploy the application

Get the application

install git

$ cd ~
$ sudo apt-get install git

Clone the application from GIT

$ git clone https://github.com/googlecodelabs/cloud-lamp-migration
$ cd cloud-lamp-migration

Create and Populate the Database

Access MySQL

$ mysql -u "root" -h "localhost" -p

Execute (source) the SQL file "source_script.sql"

-> source source_script.sql
-> exit

** Important! Please note that Root Access are targeted to these config steps. After you've completed them, please remove root access, so that you won't have a possible security vulnerability in a production environment!

Configure the application on Apache

$ cd ..

Move your app to apache www.

$ sudo mv <directory that git was cloned> /var/www/GCPNext

Copy the conf to site-available in apache.

$ sudo cp /var/www/GCPNext/lamp-server.conf /etc/apache2/sites-available/lamp-server.conf

The lamp-server.conf has the virtual host configuration.

<VirtualHost *:80>
 ServerAdmin webmaster@dummy-host.example.com
 DocumentRoot /var/www/GCPNext/web
 ServerName google.cit.com.br
 ServerAlias google.cit.com.br

 ErrorLog /var/log/apache2/google.error_log
 CustomLog /var/log/apache2/google.access_log common

 <Directory /var/www/GCPNext/web>
 Options Indexes FollowSymLinks
 AllowOverride All
 Require all granted
 </Directory>
</VirtualHost>


Alias /image-src/ "/var/www/GCPNext/image-src/"
<Directory "/var/www/GCPNext/image-src/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

Alias /image-final/ "/var/www/GCPNext/image-final/"
<Directory "/var/www/GCPNext/image-final/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

Alias /gallery/ "/var/www/GCPNext/gallery/"
<Directory "/var/www/GCPNext/gallery/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

remove the default site enabled

$ sudo rm /etc/apache2/sites-enabled/000-default.conf

Go to the site-enabled directory and create link to lamp-server in site enabled

$ cd /etc/apache2/sites-enabled/
$ sudo ln -s ../sites-available/lamp-server.conf 000-default.conf

activate rewrite model

$ sudo ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load

restart apache

$ sudo /etc/init.d/apache2 restart

Run the application

Access the url the server in your browser. http://<machine ip>.

If you get this screen :

Congratulations! It is working! Your web application is now live. Post your first meme celebrating your success!

Next, we'll create the Hybrid Environment.

Yay! You have your "on-premise" machine live and serving memes! Now we'll show you how to migrating this system into the cloud. Many customers are hesitant to move everything to cloud all at once. So, the first step we'll show is how to create a hybrid version of the configuration where your data stays "on-premise" but the front-end of the app is moved to the cloud.

Allow remote root access in MySQL on-premise

In your on-premise machine edit the my.cnf

$ sudo vi /etc/mysql/my.cnf

Comment the line

# bind-address                = 127.0.0.1

Save the file

Access the MySQL and allow remote access to root:

$ mysql -u "root" -h "localhost" -p
-> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '<password>';
-> FLUSH PRIVILEGES;
-> exit

Done !!! Now you have your MySQL server installed.

**Important! Please note that Root Access are targeted to these config steps. After you've completed them, please remove root access, so that you won't have a possible security vulnerability in a production environment!

Creating Your Hybrid Environment Apache PHP Machine

With your mySQL machine in place; you'll now setup your Apache PHP machine..

In your Google Cloud Platform (GCP) console (https://console.cloud.google.com/ ) create a new project.

Create new Networking

In GCP console of existing/new project select Networking

Click in Create Network

Create new Firewall rules

Click in Firewall rules and three new rules

Note, when entering more than one protocol and port numbers, separate them with a semicolon.

Create new GCE PHP machine

In GCP console select Compute Engine

In VM Instances click in Create Instance


Select the name instance-php your zone (us-central1-a), machine type
(1 vCPU), Boot disk (Debian GNU/Linux 8.3 (jessie)), Allow HTTP and HTTPS Traffic and create


IMPORTANT: SELECT YOUR new NETWORK MEME-NETWORK

Install Apache 2.4.10

Access your Instance PHP:

if it is the first time that you access your machine, please execute the command:

sudo apt-get update

After that, execute:

sudo apt-get install apache2

Access the url the server in your browser. http://<ip machine>. If you see :

Apache is now working on your GCE machine.

Install PHP 5.6.17 and packages on you GCE machine

execute:

sudo apt-get install php5-common libapache2-mod-php5 php5-cli php5-ldap php5-mysql

Restart Apache on your machine

sudo /etc/init.d/apache2 restart

Now, We will create a php file in /var/www/html:

$ cd /var/www/html
$ sudo vi info.php
$ paste <?php phpinfo(); ?>

Access the url the server in your browser. http://<ip machine>/info.php. If you see :

It is working.

Install MySQL Client

sudo apt-get install mysql-client

Cool, now your MySQL client is installed.

You now have an "on-premise" MySQL server setup in a GCP Project and a machine in GCE setup for your web frontend in other GCP Project. The next step is to connect the two securely so that you transfer data. In this section, you will be creating a static IP address and setting up a VPN.

Create Static IP's

In order to connect the VPN, you'll need static IP addresses for both your MySQL server instance (on premise) and your GCE Apache machine.

Example screen shot - your instances names and IP addresses will be different.

Access your GCP - MySQL and create a static IP

Network >> External IP addresses >> Reserve Static Address

Access your GCP - Apache and create a static IP

Network >> External IP addresses >> Reserve Static Address:

Check if External IP Address creation is OK.

Once OK, you will have two External IP Address in differents GCP projects (one on each):

Create VPN

The next step is to create a VPN Connection for each of your projects pointing to each other.

The Shared secret is the key that allow connections in VPN. In real project choose a

strong shared secret.

Select create VPN connection In GCP MySQL

Select create VPN connection In GCP PHP

Compare two configurations

Check if both now have connection

Create a new Firewall rule to allow connection between Apache and

Access your Instance GCP Instance MySQL and create the following new firewall rule:

Testing the connection

Now let's get the internal ip of your MySQL machine

On GCE page, click on "instance-on-premise"

And get your internal ip address, as shown below:

Do the same with your PHP Machine in your GCP - PHP Project,

Access your Instance PHP:

In shell from you PHP machine access the MySQL service of your MySQL Machine

$ sudo apt-get install telnet
$ telnet <internal_ip_mysql> 3306

If it works, congratulations !!! Now you have a VPN configured between your Apache machine with your MySQL database.

** Important! Please note that Root Access are targeted to these config steps. After you've completed them, please remove root access, so that you won't have a possible security vulnerability in a production environment!

Configuring and Deploying your application to run Hybrid

Allow connection between servers on-premise and Hybrid

Setup public SSH keys

On your on-premise machine, you will generate public SSH keys with no password:

$ ssh-keygen -f ~/.ssh/id_rsa -q -P ""
$ cat ~/.ssh/id_rsa.pub

This is our public SSH key that can be placed on other hosts to give us access:

Copy this key to your clipboard and login to your hybrid php machine .

Place this SSH key into your ~/.ssh/authorized_keys file:

Note: be careful copying the key as inadvertent line feeds or line breaks will cause the key to be invalid.

Create a different schema to hybrid version

For this Codelab, rather than use the existing schema - we'll clone a new one so that your original on-premise example stays intact.

Export the database . On your on-premise

$ mysqldump -u root -p gcpnext16lamp > export.sql

Create the schema and allow remote access to 'gcpnext16hybrid' user :

import the SQL file

$ mysql -u "root" -h "localhost" -p gcpnext16hybrid < export.sql;

** Important! Please note that Root Access are targeted to these config steps. After you've completed them, please remove root access, so that you won't have a possible security vulnerability in a production environment!

Migrate Project from On-premise to Hybrid

Export the project from your on-premise to hybrid php machine. On your on-premise server

$ cd /var/www

$ rsync -avuz -e ssh --perms --chmod=777 GCPNext/* <your_user>@<ip_your_hybrid_php_machine>:/home/<your_user>/GCPNext/

Configure application on Apache

On your hybrid php server. Move your app to apache www.

$ cd /home/<your_user>
$ sudo mv GCPNext /var/www/GCPNext

Configure your application to use the another MySQL.

$ cd /var/www/GCPNext/web/core
$ sudo vi remote_config.ini

change the db_host from localhost to <ip_your_hybrid_mysql_machine> and db_name to gcpnext16hybrid

db_driver = "mysql"
db_host = "localhost"
db_name = "

gcpnext16hybrid

"
db_user = "gcpnext16"
db_pass = "abacabbbabebibobu123"
db_dsn = "[db_driver]:host=[db_host];dbname=[db_name]"

dir_src_img = "image-src"
dir_final_img = "image-final"
dir_gallery = "gallery"

Copy the conf to site-available in apache.

$ sudo cp /var/www/GCPNext/lamp-server.conf /etc/apache2/site-available/lamp-server.conf

remove the default site enabled

$ sudo rm /etc/apache2/site-enabled/000-default.conf

Go to the site-enabled directory and create link to lamp-server in site enabled

$ cd /etc/apache2/site-enabled/
$ sudo ln -s ../sites-available/lamp-server.conf 000-default.conf

The lamp-server.conf has the virtual host configuration.

<VirtualHost *:80>
 ServerAdmin webmaster@dummy-host.example.com
 DocumentRoot /var/www/GCPNext/web
 ServerName google.cit.com.br
 ServerAlias google.cit.com.br

 ErrorLog /var/log/apache2/google.error_log
 CustomLog /var/log/apache2/google.access_log common

 <Directory /var/www/GCPNext/web>
 Options Indexes FollowSymLinks
 AllowOverride All
 Require all granted
 </Directory>

</VirtualHost>


Alias /image-src/ "/var/www/GCPNext/image-src/"
<Directory "/var/www/GCPNext/image-src/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

Alias /image-final/ "/var/www/GCPNext/image-final/"
<Directory "/var/www/GCPNext/image-final/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

Alias /gallery/ "/var/www/GCPNext/gallery/"
<Directory "/var/www/GCPNext/gallery/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

active rewrite model

$ sudo ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load

restart apache

$ sudo /etc/init.d/apache2 restart

Run the application

Access the url the server in your browser. http://<ip machine>. If you see :

Congratulations! It is working! Your web application is live. Post your first meme in hybrid version and celebrating your success!

Now that you have built and tested your applications in both on-premise and hybrid modes,

We'll now show you the simple way to deploy the full app directly onto GCE and easily migrate the database

.

Create LAMP machine

First create a LAMP machine in GCE.

Select Cloud Launcher

Type LAMP

Select :

Deploy the machine - note the name should be all lowercase and can include dashes

After the machine is created:

Access the machine and execute:

$ sudo apt-get install php5-cli php5-ldap php5-gd

Restart Apache on your machine:

$ sudo /etc/init.d/apache2 restart

Configuring and deploying your application to run Full GCE

Next with the LAMP stack installed, we now need to configure and deploy the memegen application.

Get the application

install git

$ sudo apt-get install git

Clone the application from GIT

$ git clone https://<bitbucket-user>@bitbucket.org/ciandt_it/google-memegen-next16.git

Configure application on Apache

$ cd ..

Move your app to apache www.

$ sudo mv <directory that git was cloned> /var/www/GCPNext

Copy the conf to site-available in apache.

$ sudo cp /var/www/GCPNext/lamp-server.conf /etc/apache2/site-available/lamp-server.conf

The lamp-server.conf has the virtual host configuration.

<VirtualHost *:80>
 ServerAdmin webmaster@dummy-host.example.com
 DocumentRoot /var/www/GCPNext/web
 ServerName google.cit.com.br
 ServerAlias google.cit.com.br

 ErrorLog /var/log/apache2/google.error_log
 CustomLog /var/log/apache2/google.access_log common

 <Directory /var/www/GCPNext/web>
 Options Indexes FollowSymLinks
 AllowOverride All
 Require all granted
 </Directory>

</VirtualHost>


Alias /image-src/ "/var/www/GCPNext/image-src/"
<Directory "/var/www/GCPNext/image-src/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

Alias /image-final/ "/var/www/GCPNext/image-final/"
<Directory "/var/www/GCPNext/image-final/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

Alias /gallery/ "/var/www/GCPNext/gallery/"
<Directory "/var/www/GCPNext/gallery/">
 Order allow,deny
 Allow from all
 # Require all granted
</Directory>

remove the default site enabled

$ sudo rm /etc/apache2/site-enabled/000-default.conf

Go to the site-enabled directory and create link to lamp-server in site enabled

$ cd /etc/apache2/site-enabled/
$ sudo ln -s ../sites-available/lamp-server.conf 000-default.conf

activate rewrite model

$ sudo ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load

restart apache

$ sudo /etc/init.d/apache2 restart

Now you have the full GCE machine configured and the application configured.

Now let's migrate the data environment between the existing on-premise machine and your new full GCE one.

Allow connection between servers

Setup public SSH keys

On your on-premise machine, you will generate public SSH keys with no password:

$ ssh-keygen -f ~/.ssh/id_rsa -q -P ""
$ cat ~/.ssh/id_rsa.pub

This is our public SSH key that can be placed on other hosts to give us access:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLVDBIpdpfePg/a6h8au1HTKPPrg8wuTrjdh0QFVPpTI4KHctf6/FGg1NOgM++hrDlbrDVStKn/b3Mu65//tuvY5SG9sR4vrINCSQF++a+YRTGU6Sn4ltKpyj3usHERvBndtFXoDxsYKRCtPfgm1BGTBpoSl2A7lrwnmVSg+u11FOa1xSZ393aaBFDSeX8GlJf1SojWYIAbE25Xe3z5L232vZ5acC2PJkvKctzvUttJCP91gbNe5FSwDolE44diYbNYqEtvq2Jt8x45YzgFSVKf6ffnPwnUDwhtvc2f317TKx9l2Eq4aWqXTOMiPFA5ZRM/CF0IJCqeXG6s+qVfRjB root@cloudads

Copy these keys to your full gce machine .

Place these SSH key into your ~/.ssh/authorized_keys file:

Migrate the database

Export the database from your on-premise to full GCE MySQL machine. On your on-premise

$ mysqldump -u root -p gcpnext16lamp > export.sql

Send export.sql to full GCE machine:

$ rsync -avuz -e ssh export.sql <your_user>@<ip_your_full_gce_machine>:<directory>

On your full gce machine:

Create the schema and allow remote access to 'gcpnext16' user :

$ mysql -u "root" -h "localhost" -p
mysql> CREATE SCHEMA IF NOT EXISTS `gcpnext16lamp` DEFAULT CHARACTER SET utf8 ;
mysql> USE `gcpnext16lamp` ;

import

$ mysql -u "root" -h "localhost" -p gcpnext16lamp < export.sql

** Important! Please note that Root Access are targeted to these config steps. After you've completed them, please remove root access, so that you won't have a possible security vulnerability in a production environment!

Migrate images

Export the images from your on-premise machine. On your on-premise machine

$ cd /home/<your_user>/
$ sudo rm -rf /var/www/GCPNext/image-src/
$ sudo rm -rf /var/www/GCPNext/image-final/
$ sudo rm -rf /var/www/GCPNext/gallery/

$ mv image-final /var/www/GCPNext/
$ mv image-src /var/www/GCPNext/
$ mv gallery /var/www/GCPNext/

Run the application

Access the url the server in your browser. http://<ip machine>. You should see::

Congratulations!

You've completed the full journey from and on-premise hosted application to a hybrid hosted server to full GCE hosted application. You've setup VPN's and Firewall rules. Now post your first meme from the GCE hosted version of your application to celebrate the achievement!

What we've covered

Next steps

Learn more

Give us your feedback

/