Skip to content

Commit

Permalink
Merge pull request pulumi#966 from pulumi/vl/GCPNativeRail
Browse files Browse the repository at this point in the history
Add google-native version of gcp-ts-k8s-ruby-on-rails-postgresql
  • Loading branch information
Vivek Lakshmanan committed Apr 19, 2021
2 parents 0c530b4 + 7734019 commit 04afe35
Show file tree
Hide file tree
Showing 102 changed files with 2,014 additions and 0 deletions.
130 changes: 130 additions & 0 deletions google-native-ts-k8s-ruby-on-rails-postgresql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new?template=https://github.com/pulumi/examples/tree/master/gcp-ts-k8s-ruby-on-rails-postgresql/infra)

# Containerized Ruby on Rails App Delivery using the Google Native Pulumi Provider

This example is a full end to end example of delivering a containerized Ruby on Rails application. It

- Provisions a [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/) cluster
- Provisions a fully managed Google Cloud SQL PostgreSQL database
- Builds a containerized Ruby on Rails container image, and publishes it to the Google Container Registry
- Deploys that container image as a Kubernetes Service inside of the provisioned GKE cluster

All of these happen behind a single `pulumi up` command, and are expressed in just a handful of TypeScript.

## Prerequisites

Before trying to deploy this example, please make sure you have performed all of the following tasks:
- [downloaded and installed the Pulumi CLI](https://www.pulumi.com/docs/get-started/install/).
- [downloaded and installed Docker](https://docs.docker.com/install/)
- [signed up for Google Cloud](https://cloud.google.com/free/)
- [followed the instructions here](https://www.pulumi.com/docs/intro/cloud-providers/gcp/setup/) to connect Pulumi to your Google Cloud account.

This example assumes that you have Google Cloud's `gcloud` CLI on your path. This is installed as part of the
[Google Cloud SDK](https://cloud.google.com/sdk/).

As part of this example, we will setup and deploy a Kubernetes cluster on GKE. You may also want to install [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) if you would like to directly interact with the underlying Kubernetes cluster.

## Running the Example

After cloning this repo, `cd infra/` and run these commands. After 8 minutes, you'll have a fully functioning GKE
cluster and containerized Ruby on Rails application deployed into it, using a hosted PostgreSQL instance!

1. Create a new stack, which is an isolated deployment target for this example:

```bash
$ pulumi stack init dev
```

2. Set the required configuration variables for this program:

```bash
$ pulumi config set google-native:project [your-gcp-project-here]
$ pulumi config set google-native:region us-west1 # any valid region
```

Since we will use Google's Container Registry for hosting the Docker image, we need to configure your machine's Docker to be able to authenticate with GCR:

```bash
$ gcloud auth configure-docker # Configure docker to be able to push to your Google project's container registry
```

The following configuration variables have defaults or are automatically generated when not specified but can be explicitly specified as follows:

```bash
$ pulumi config set clusterPassword --secret [your-new-cluster-password-here] # must be at least 16 characters
$ pulumi config set dbUsername [your-new-db-username-here]
$ pulumi config set dbPassword --secret [your-new-db-password-here]
$ pulumi config set masterVersion # any valid master version, or latest
```

Config variables that use the `--secret` flag are [encrypted and not stored as plaintext](https://www.pulumi.com/docs/intro/concepts/config/#secrets).

By default, your cluster will use the default nodepool. `index.ts` includes a reference incantation to enable an additional nodepool
which can be configured as follows:
```bash
$ pulumi config set clusterNodeCount 5
$ pulumi config set clusterNodeMachineType n1-standard-2
```

You can even change these after provisioning.

3. Deploy everything with the `pulumi up` command. This provisions all the GCP resources necessary, including
your GKE cluster and database, as well as building and publishing your container image, all in a single gesture:

```bash
$ pulumi up
```

This will show you a preview, ask for confirmation, and then chug away at provisioning your cluster:

```
Updating stack 'google-rails-dev'
Performing changes:
Type Name Plan Info
+ pulumi:pulumi:Stack google-rails-dev create
+ ├─ docker:image:Image rails-app create
+ ├─ google-native:container/v1:Cluster cluster create
+ ├─ google-native:sqladmin/v1beta4:Instance web-db create
+ ├─ google-native:container/v1:ClusterNodePool primary-node-pool create
+ ├─ pulumi:providers:kubernetes gke-k8s create
+ ├─ gcp:sql:User web-db-user create
+ ├─ kubernetes:apps/v1:Deployment rails-deployment create
+ └─ kubernetes:core/v1:Service rails-service create
Diagnostics:
docker:image:Image (rails-app):
Building container image: context=../app
logging in to registry...
Sending build context to Docker daemon 22.79MB
Step 1/9 : FROM ruby:2.5
---> 8e2b5b80415f
...
---outputs:---
appAddress: "http:https://32.233.14.89:3000"
appName : "rails-deployment-vt7uyigk"
dbAddress : "36.223.156.57"
kubeConfig: "apiVersion: v1\n..."
info: 8 changes
+ 8 created
Update duration: 7m20.867501974as
```

After this completes, numerous outputs will show up. `appAddress` is the URL that your Rails app will be available
at, `appName` is the resulting Kubernetes Deployment, `dbAddress` is your PostgreSQL hostname in case you want to
connect to it with `psql`, and `kubeConfig` is the full Kubernetes configuration that you can use with `kubectl`.

4. Open a browser to visit the site, `open $(pulumi stack output appAddress)/todo_lists`. Make some todo lists!

5. At this point, you have a running cluster. Feel free to modify your program, and run `pulumi up` to redeploy changes.
The Pulumi CLI automatically detects what has changed and makes the minimal edits necessary to accomplish these
changes. This could be altering the app code, adding new Google Cloud or Kubernetes resources, or anything, really.

6. Once you are done, you can destroy all of the resources, and the stack:

```bash
$ pulumi destroy
$ pulumi stack rm
```
27 changes: 27 additions & 0 deletions google-native-ts-k8s-ruby-on-rails-postgresql/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore uploaded files in development
/storage/*
!/storage/.keep

/node_modules
/yarn-error.log

/public/assets
.byebug_history

# Ignore master key for decrypting credentials and more.
/config/master.key
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruby-2.5.1
10 changes: 10 additions & 0 deletions google-native-ts-k8s-ruby-on-rails-postgresql/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs bundler
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
RUN rake app:update:bin
CMD ["/myapp/start"]
62 changes: 62 additions & 0 deletions google-native-ts-k8s-ruby-on-rails-postgresql/app/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.9'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.5'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby

# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of chromedriver to run system tests with Chrome
gem 'chromedriver-helper'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
Loading

0 comments on commit 04afe35

Please sign in to comment.