To better understand the Infrastructure as Code
(IaC
) concept, we will first define the problem we are facing and deal with it with manually to get our hands dirty and see how things work overall.
Imagine you have developed a new cool application called raddit.
You want to run your application on a dedicated server and make it available to the Internet users.
You heard about the public cloud
thing, which allows you to provision compute resources and pay only for what you use. You believe it's a great way to test your idea of an application and see if people like it.
You've signed up for a free tier of Google Cloud Platform (GCP) and are about to start deploying your application.
First thing we will do is to provision a virtual machine (VM) inside GCP for running the application.
Use the following gcloud command in your terminal to launch a VM with Ubuntu 16.04 distro:
$ gcloud compute instances create raddit-instance-2 \
--image-family ubuntu-1604-lts \
--image-project ubuntu-os-cloud \
--boot-disk-size 10GB \
--machine-type n1-standard-1
Generate an SSH key pair for future connections to the VM instances (run the command exactly as it is):
$ ssh-keygen -t rsa -f ~/.ssh/raddit-user -C raddit-user -P ""
Create an SSH public key for your project:
$ gcloud compute project-info add-metadata \
--metadata ssh-keys="raddit-user:$(cat ~/.ssh/raddit-user.pub)"
Add the SSH private key to the ssh-agent:
$ ssh-add ~/.ssh/raddit-user
Verify that the key was added to the ssh-agent:
$ ssh-add -l
To start the application, you need to first configure the environment for running it.
Connect to the started VM via SSH:
$ INSTANCE_IP=$(gcloud --format="value(networkInterfaces[0].accessConfigs[0].natIP)" compute instances describe raddit-instance-2)
$ ssh raddit-user@${INSTANCE_IP}
Install Ruby:
$ sudo apt-get update
$ sudo apt-get install -y ruby-full build-essential
Check the installed version of Ruby:
$ ruby -v
Install Bundler:
$ sudo gem install --no-rdoc --no-ri bundler
$ bundle version
Clone the application repo, but first make sure git
is installed:
$ git version
At the time of writing the latest image of Ubuntu 16.04 which GCP provides has git
preinstalled, so we can skip this step.
Clone the application repo into the home directory of raddit-user
user:
$ git clone https://github.com/Artemmkin/raddit.git
Install application dependencies using Bundler:
$ cd ./raddit
$ sudo bundle install
Install MongoDB which your application uses:
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
$ echo "deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
$ sudo apt-get update
$ sudo apt-get install -y mongodb-org
Start MongoDB and enable autostart:
$ sudo systemctl start mongod
$ sudo systemctl enable mongod
Verify that MongoDB is running:
$ sudo systemctl status mongod
Download a systemd unit file for starting the application from a gist:
$ wget https://gist.githubusercontent.com/Artemmkin/ce82397cfc69d912df9cd648a8d69bec/raw/7193a36c9661c6b90e7e482d256865f085a853f2/raddit.service
Move it to the systemd directory
$ sudo mv raddit.service /etc/systemd/system/raddit.service
Now start the application and enable autostart:
$ sudo systemctl start raddit
$ sudo systemctl enable raddit
Verify that it's running:
$ sudo systemctl status raddit
Open a firewall port the application is listening on (note that the following command should be run on your local machine):
$ gcloud compute firewall-rules create allow-raddit-tcp-9292 \
--network default \
--action allow \
--direction ingress \
--rules tcp:9292 \
--source-ranges 0.0.0.0/0
Get the public IP of the VM:
$ gcloud --format="value(networkInterfaces[0].accessConfigs[0].natIP)" compute instances describe raddit-instance-2
Now open your browser and try to reach the application at the public IP and port 9292.
For example, I put in my browser the following URL http://104.155.1.152:9292, but note that you'll have your own IP address.
Congrats! You've just deployed your application. It is running on a dedicated set of compute resources in the cloud and is accessible by a public IP. Now Internet users can enjoy using your application.
Now that you've got the idea of what sort of steps you have to take to deploy your code from your local machine to a virtual server running in the cloud, let's see how we can do it more efficiently.
Destroy the current VM and move to the next step:
$ gcloud compute instances delete raddit-instance-2
Next: Scripts