Getting Started with Rails On Services
Getting Started with Infrastructure
After reading this guide, you will know:
How to create Terraform code to stand up an instance and Kubernetes cluster for a Rails on Services project deployment
The required elements of the infrastructure
How to quickly generate the configuration and templates for your provider
In following guide we’ll learn to extend ROS CLI with Google Cloud Platform infrastructure provider based on existing AWS provider
- Getting Started with Infrastructure
1 Creating a New Rails on Services Project
The best way to read this guide is to follow it step by step. All steps are essential to standup the infrastructure
1.1 Installing Rails on Services
Rails on Services is currently under heavy development. We have a separate repo for setting up the project. Please see Setup and complete:
- Virtual Mashine Setup section to launch development environment
- Verify VM Configuration
Once Vagrant is up and running, the directory from which you ran vagrant ssh
is mounted in the VM.
You can use a text editor of your choice on Host OS and run ROS CLI commands on the VM to test your changes.
All subsequent commands are executed in the VM
Assuming that you ran vagrant ssh
from your host OS dir of ~/my-project
and you have just exected vagrant ssh
so in the VM:
cd my-project
ros new my-platform
cd my-platform
ros be init
Your folder structure in the VM should look like below and further will be referenced as root folder.
tree ~ -L 3
.
|-- my-project
| |-- my-platform
| | |-- ansible.cfg
| | |-- avp
| | |-- config
| | |-- Rakefile
| | |-- README.md
| | |-- ros
| | `-- VERSION
| '-- ros
| | |-- cli
| | |-- guides
| | |-- images
| | `-- setup
| |-- Vagrantfile
2 ROS configuration files explanation
The ~/my-project/my-platform/ros/config
directory has the following contents:
.
|-- deployments
| |-- development-specs.yml
| |-- development.yml
| |-- gcp.yml
| |-- production.yml
| `-- test.yml
|-- deployment.yml
`-- environment.yml
deployment.yml
is a master configuration file which values applies to any deployment managed by ROS CLI.
Deployment configuration files in deployments
folder will override any values defined in deployment.yml
.
Deployment configuration file usage determined by ROS_ENV
environmental variable passed to ROS CLI upon runtime.
Default deployment configuration file is development.yml
if no ROS_ENV
been set.
Setting ROS_ENV=test
tell ROS CLI to use test.yml
config.
3 Creating a new Provider
We use terraform for infrastructure providers.
In following example we will create an GKE instance with a VPC.
3.1 Start with creating a config file
- Create a profile configuration file
cd ~/my-project/my-platform/ros/config/deployments
cp gcp.yml your-provider.yml
- Set the values in the config file
components:
be:
components:
infra:
config:
cluster:
type: instance
components:
provider_settings:
config:
provider: gcp
region: us-central1
zone: us-central1-a
project: 'my-project-name'
credentials_file: 'path/to/credentials.json'
vpc:
config:
provider: gcp #other supported types: azure, oracle
vpc_name: my-test-vpc
subnet_name: my-test-subnet
cidr: '10.100.0.0/16'
instance:
config:
provider: gcp
name: my-test-instance
machine_type: 'f1-micro'
disk_image: 'debian-cloud/debian-9'
dns:
config:
provider: gcp
Note on empty dns
module declaration. This is to override default dns settings declared in deployment.yml
Config values from your-provider.yml
are exposed as variables in the template your-provider-main.tf
Edit this file and add the variables and values that are required to configure your provider’s infrastructure.
3.2 Create your TF template
We are done with editing ROS project for now. Lets go back to our project root folder and update CLI project.
Terraform temlpates stored at ~/my-project/ros/cli/lib/ros/be/infra/templates/terraform
cd ~/my-project/ros/cli/lib/ros/be/infra/templates/terraform
mkdir your-provider # NOTE: folder name *must* match your provider name set in your-provider.yml
touch your-provider/instance.tf.erb
Following template is sufficient to generate a correct main.tf
file.
Note on ERB variables declaration as tf.component.config.value
provider "google" {
credentials = "${file("<%= tf.provider_settings.config.credentials_file %>")}"
project = "<%= tf.provider_settings.config.project %>"
region = "<%= tf.provider_settings.config.region %>"
}
module "vpc" {
source = "./gcp/vpc"
vpc_name = "<%= tf.vpc.config.vpc_name %>"
create_subnetworks = false
subnet_name = "<%= tf.vpc.config.subnet_name %>"
cidr = "<%= tf.vpc.config.cidr %>"
}
module "gci" {
source = "./gcp/gci"
name = "<%= tf.instance.config.name %>"
machine_type = "<%= tf.instance.config.machine_type %>"
disk_image = "<%= tf.instance.config.disk_image %>"
zone = "<%= tf.provider_settings.config.zone %>"
subnetwork = module.vpc.subnetwork.self_link
}
3.3 Create Terraform configuration files
Terraform configuration files stored at `cli/lib/ros/be/infra/files/terraform
cd ~/my-project/ros/cli/lib/ros/be/infra/files/terraform/
mkdir your-provider # NOTE: folder name *must* match your provider name set in your-provider.yml
cd your-provider
mkdir instance-type vpc dns
Now put your terraform resource declaration files, variables and outputs into corresponding folders.
Examples are shown below and can be found in ~/my-project/ros/cli/lib/ros/be/infra/files/terraform/{gcp, aws}
3.4 Working examples of Terraform provider files
For reference, here is what the aws and gcp providers content looks like.
In the files
directory there is a set of files for each infrastructure component
In the templates
directory there is a single ERB template file for each infra deployment type: instance
or kubernetes
~/my-project/ros/cli/lib/ros/be/infra$ tree files templates
files
`-- terraform
|-- aws
| |-- acm
| | |-- main.tf
| | |-- outputs.tf
| | `-- variables.tf
| |-- ec2
| | |-- locals.tf
| | |-- main.tf
| | |-- outputs.tf
| | |-- templates
| | | |-- userdata-debian.tpl
| | | `-- userdata-ubuntu.tpl
| | `-- variables.tf
| |-- eks
| | `-- main.tf
| |-- route53
| | |-- main.tf
| | |-- outputs.tf
| | `-- variables.tf
| `-- vpc
| |-- main.tf
| |-- outputs.tf
| `-- variables.tf
`-- gcp
|-- gci
| |-- main.tf
| |-- outputs.tf
| `-- variables.tf
`-- vpc
|-- main.tf
|-- outputs.tf
`-- variables.tf
templates
`-- terraform
|-- aws
| |-- instance.tf.erb
| `-- kubernetes.tf.erb
`-- gcp
`-- instance.tf.erb
4 Set components mapping
As final touch, we set components (declared in gcp.yml) mapping to terraform modules mapping in our template generator.
vim ~/my-project/ros/cli/lib/ros/be/infra/generator.rb
Update gcp type with following values:
def gcp(type)
{
vpc: 'vpc',
instance: 'gci'
}[type]
end
5 Stand up the infrastructure
You should now be able to launch simple infrastructure consisting of a single VPC and GCI:
cd ~/my-project/my-platform/ros
Generate Terraform scripts out of your templates
ros generate:be:infra
Generate the Terraform plan
ros be infra plan
Apply your Terraform infrastructure plan
ros be infra apply
Use -v
and/or -n
for verbosity and/or dry-run respectively.
Use ros be infra help
to find out commands description.