Skip to content

Commit

Permalink
Initial cloud deploy setup
Browse files Browse the repository at this point in the history
  • Loading branch information
danivovich committed Jul 29, 2024
1 parent c233e89 commit bb01c0a
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 9 deletions.
39 changes: 37 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
version: 2.1

orbs:
cloudfoundry: circleci/[email protected]
ruby: circleci/[email protected]
docker: circleci/[email protected]

Expand Down Expand Up @@ -137,9 +138,36 @@ jobs:
./cc-test-reporter upload-coverage --input coverage/codeclimate_full_report.json
dev-deploy:
parallelism: 1
docker:
- image: cimg/ruby:3.2.2
steps:
- checkout
- run: bundle cache --all
- run: echo -e $DEV_PRIVATE_KEY > dev_key.pem
- run: echo -e $DEV_PUBLIC_CERT > dev_cert.pem
- run: echo 'export CF_PASSWORD=$CF_PASSWORD_DEV' >> $BASH_ENV
- run: echo 'export CF_USERNAME=$CF_USERNAME_DEV' >> $BASH_ENV
- run:
name: Install Cloud Foundry CLI
command: |
sudo apt-get update
sudo apt-get install -y ca-certificates jq
sudo touch /etc/apt/sources.list.d/cloudfoundry-cli.list
echo "deb [trusted=yes] https://packages.cloudfoundry.org/debian stable main" | sudo tee -a /etc/apt/sources.list.d/cloudfoundry-cli.list
sudo apt-get update
sudo apt-get install dpkg
sudo apt-get install cf7-cli
- cloudfoundry/auth:
endpoint: "https://api.fr.cloud.gov"
org: gsa-tts-innovation-challenge
space: eval-dev
- run: cf push challenge-dev --strategy rolling

workflows:
version: 2
build_and_test:
test-and-deploy:
jobs:
- checkout_code:
name: "checkout code: Ruby << matrix.ruby_version >>"
Expand Down Expand Up @@ -170,4 +198,11 @@ workflows:
ruby_version:
- 3.2.2
postgres_version:
- "16.3"
- "16.3"

- dev-deploy:
requires:
- rspec
filters:
branches:
only: dev
8 changes: 8 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@
require_relative "config/application"

Rails.application.load_tasks

namespace :cf do
desc "Only run on the first application instance"
task :on_first_instance do
instance_index = JSON.parse(ENV["VCAP_APPLICATION"])["instance_index"] rescue nil
exit(0) unless instance_index == 0
end
end
3 changes: 3 additions & 0 deletions apt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
packages:
- imagemagick
10 changes: 10 additions & 0 deletions cloud_start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
echo "------ Starting APP ------ Instance $CF_INSTANCE_INDEX -----"
echo "------ Booting Instance ------ Instance $CF_INSTANCE_INDEX -----"
if [ "$CF_INSTANCE_INDEX" == "0" ]; then
echo "----- Migrating Database ----- Instance $CF_INSTANCE_INDEX -----"
bundle exec rake cf:on_first_instance db:migrate
echo "----- Migrated Database ----- Instance $CF_INSTANCE_INDEX -----"
fi
echo "------ Booting Web Process ------ Instance $CF_INSTANCE_INDEX -----"
bundle exec rails s -b 0.0.0.0 -p $PORT -e $RAILS_ENV
20 changes: 13 additions & 7 deletions config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@ test:
<<: *default
database: challenge_gov_test

dev:
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("POOL_SIZE", 15) %>
url: <%= ENV["DATABASE_URL"] %>

staging:
<<: *default
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("POOL_SIZE", 15) %>
url: <%= ENV["DATABASE_URL"] %>

production:
<<: *default
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
url: <%= ENV["DATABASE_URL"] %>
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("POOL_SIZE", 15) %>
url: <%= ENV["DATABASE_URL"] %>
97 changes: 97 additions & 0 deletions config/environments/dev.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require "active_support/core_ext/integer/time"

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Code is not reloaded between requests.
config.enable_reloading = false

# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true

# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true

# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true

# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
# config.public_file_server.enabled = false

# Compress CSS using a preprocessor.
# config.assets.css_compressor = :sass

# Do not fall back to assets pipeline if a precompiled asset is missed.
config.assets.compile = false

# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.asset_host = "http://assets.example.com"

# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX

# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local

# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
# config.action_cable.url = "wss://example.com/cable"
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]

# Assume all access to the app is happening through a SSL-terminating reverse proxy.
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
# config.assume_ssl = true

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true

# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new(STDOUT)
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }

# Prepend all log lines with the following tags.
config.log_tags = [ :request_id ]

# "info" includes generic and useful information about system operation, but avoids logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
# want to log everything, set the level to "debug".
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")

# Use a different cache store in production.
# config.cache_store = :mem_cache_store

# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "rails_new_production"

config.action_mailer.perform_caching = false

# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true

# Don't log any deprecations.
config.active_support.report_deprecations = false

# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false

# Enable DNS rebinding protection and other `Host` header attacks.
# config.hosts = [
# "example.com", # Allow requests from example.com
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
# ]
# Skip DNS rebinding protection for the default health check endpoint.
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
end
97 changes: 97 additions & 0 deletions config/environments/staging.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require "active_support/core_ext/integer/time"

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Code is not reloaded between requests.
config.enable_reloading = false

# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true

# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true

# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true

# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
# config.public_file_server.enabled = false

# Compress CSS using a preprocessor.
# config.assets.css_compressor = :sass

# Do not fall back to assets pipeline if a precompiled asset is missed.
config.assets.compile = false

# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.asset_host = "http://assets.example.com"

# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX

# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local

# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
# config.action_cable.url = "wss://example.com/cable"
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]

# Assume all access to the app is happening through a SSL-terminating reverse proxy.
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
# config.assume_ssl = true

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true

# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new(STDOUT)
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }

# Prepend all log lines with the following tags.
config.log_tags = [ :request_id ]

# "info" includes generic and useful information about system operation, but avoids logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
# want to log everything, set the level to "debug".
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")

# Use a different cache store in production.
# config.cache_store = :mem_cache_store

# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "rails_new_production"

config.action_mailer.perform_caching = false

# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true

# Don't log any deprecations.
config.active_support.report_deprecations = false

# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false

# Enable DNS rebinding protection and other `Host` header attacks.
# config.hosts = [
# "example.com", # Allow requests from example.com
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
# ]
# Skip DNS rebinding protection for the default health check endpoint.
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
end
28 changes: 28 additions & 0 deletions manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
defaults: &defaults
buildpacks:
- https://github.com/cloudfoundry/apt-buildpack
- nodejs_buildpack
- ruby_buildpack
memory: 1G
disk_quota: 2G
stack: cflinuxfs4
health-check-type: process
command: ./cloud_start.sh

applications:
- name: challenge-dev
<<: *defaults
instances: 1
disk_quota: 6GB
env:
RAILS_ENV: dev
RAILS_LOG_TO_STDOUT: true
RAILS_SERVE_STATIC_FILES: true
HOST: challenge-dev.app.cloud.gov
LOGIN_PRIVATE_KEY_PATH: dev_key.pem
LOGIN_PUBLIC_KEY_PATH: dev_cert.pem
LOGIN_REDIRECT_URL: https://challenge-portal-dev.app.cloud.gov/auth/result
LOGIN_IDP_AUTHORIZE_URL: https://idp.int.identitysandbox.gov/openid_connect/authorize
LOGIN_TOKEN_ENDPOINT: https://idp.int.identitysandbox.gov/api/openid_connect/token
LOGIN_CLIENT_ID: urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:challenge_gov_portal_dev

0 comments on commit bb01c0a

Please sign in to comment.