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.
Once you have received a temporary username / password to login from the instructor, log into the Google Cloud Console: https://console.cloud.google.com/. Here's what you should see once logged in :
From there, click on the project name to get to the dashboard view :
While Google Cloud can be operated remotely from your laptop, in this codelab we will be using 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 (the gcloud
sdk and more), it offers a persistent 5GB home directory, and runs on the Google Cloud, greatly enhancing network performance and authentication. This means that all you will need for this codelab is a browser (yes, it works on a Chromebook).
To activate Google Cloud Shell, from the developer console simply click the button on the top right-hand side (it should only take a few moments to provision and connect to the environment):
Once connected to the cloud shell, you should see that you are already authenticated and that the project is already set to your PROJECT_ID
:
$ gcloud auth list Credentialed accounts: - <myaccount>@<mydomain>.com (active)
$ gcloud config list project [core] project = <PROJECT_ID>
If for some reason the project is not set, simply issue the following command :
$ gcloud config set project <PROJECT_ID>
Looking for you PROJECT_ID
? Check out what ID you used in the setup steps or look it up in the console dashboard :
IMPORTANT. Finally, set the default zone and project configuration:
$ gcloud config set compute/zone us-central1-f $ 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.
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.
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>
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
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
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
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!
$ 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
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.
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!
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.
In GCP console of existing/new project select Networking
Click in Create Network
Click in Firewall rules and three new rules
Note, when entering more than one protocol and port numbers, separate them with a semicolon.
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
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.
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.
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.
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):
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
Check if both now have connection
Access your Instance GCP Instance MySQL and create the following new firewall rule:
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!
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/
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
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
.
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
Next with the LAMP stack installed, we now need to configure and deploy the memegen 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
$ 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.
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:
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!
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/
Access the url the server in your browser. http://<ip machine>. You should see::
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!
/