Browse Source

Move to Gov PaaS (#24)

Move infra to Gov PaaS
pull/26/head
Daniel Baark 3 years ago committed by GitHub
parent
commit
207e465470
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .cfignore
  2. 78
      .github/workflows/pipeline.yml
  3. 4
      Gemfile.lock
  4. 19
      README.md
  5. 0
      bin/rails
  6. 114
      config/environments/sandbox.rb
  7. 5
      config/webpack/sandbox.js
  8. 20
      doc/adr/adr-004.md
  9. 14
      manifest.yml
  10. 19042
      package-lock.json

1
.cfignore

@ -0,0 +1 @@
.gitignore

78
.github/workflows/pipeline.yml

@ -6,16 +6,12 @@ on:
- main - main
pull_request: pull_request:
concurrency: 'Beta - Production' concurrency: 'sandbox'
defaults: defaults:
run: run:
shell: bash shell: bash
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
jobs: jobs:
test: test:
@ -73,65 +69,35 @@ jobs:
run: | run: |
bundle exec rake bundle exec rake
deploy: deploy:
name: Deploy name: Deploy
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: 'Beta - Production' environment: 'sandbox'
if: github.ref == 'refs/heads/main' if: github.ref == 'refs/heads/main'
needs: needs: test
- test
timeout-minutes: 30
env:
AWS_REGION: eu-west-2
ECR_REPOSITORY: container-repository
ECS_SERVICE: app
ECS_CLUSTER: ecs-cluster
CONTAINER_NAME: app # set this to the name of the container in the containerDefinitions section of your task definition
steps: steps:
- name: Checkout - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Configure AWS credentials - name: Install cf client
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push the image to Amazon ECR
id: build-image
env: env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} CF_CLI_VERSION: 7.0.0-beta.30
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY }}
IMAGE_TAG: ${{ github.sha }}
run: | run: |
# Build a docker container and push it to ECR curl -L "https://packages.cloudfoundry.org/stable?release=linux64-binary&version=${CF_CLI_VERSION}" | tar -zx -C /tmp
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . sudo cp /tmp/cf7 /usr/local/bin/cf7
echo "Pushing image to ECR..." - name: Deploy
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG env:
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" CF_USERNAME: ${{ secrets.CF_USERNAME }}
CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
- name: Download task definition CF_API_ENDPOINT: ${{ secrets.CF_API_ENDPOINT }}
CF_SPACE: ${{ secrets.CF_SPACE }}
CF_ORG: ${{ secrets.CF_ORG }}
run: | run: |
aws ecs describe-task-definition --task-definition app --query taskDefinition > task-definition.json cf7 api $CF_API_ENDPOINT
cf7 auth
- name: Fill in the new image ID in the Amazon ECS task definition cf7 target -o $CF_ORG -s $CF_SPACE
id: task-def cf7 push --strategy rolling
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: ${{ env.CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: true

4
Gemfile.lock

@ -1,6 +1,6 @@
GIT GIT
remote: https://github.com/rspec/rspec-core.git remote: https://github.com/rspec/rspec-core.git
revision: 94dfb29265fbadb1216a0aaf97cd343396c942c3 revision: 053fcfeb6b0b6627edf7261737553a6f7df8cc14
branch: main branch: main
specs: specs:
rspec-core (3.11.0.pre) rspec-core (3.11.0.pre)
@ -297,7 +297,7 @@ GEM
stimulus-rails (0.6.0) stimulus-rails (0.6.0)
rails (>= 6.0.0) rails (>= 6.0.0)
thor (1.1.0) thor (1.1.0)
turbo-rails (0.8.0) turbo-rails (0.8.1)
rails (>= 6.0.0) rails (>= 6.0.0)
tzinfo (2.0.4) tzinfo (2.0.4)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)

19
README.md

@ -44,7 +44,24 @@ Note docker-compose runs the production docker image (RAILS_ENV=production) as t
### Infrastructure ### Infrastructure
The cloud infrastructure running this application is set up using the [infrastructure repository](https://github.com/communitiesuk/mhclg-data-collection-beta-infrastructure) This application is running on [Gov PaaS](https://www.cloud.service.gov.uk/). To deploy you need to:
- Contact your organisation manager to get an account in `dluhc-core` organization and in the relevant spaces (sandbox/production).
- Install the cloudfoundry cli https://docs.cloudfoundry.org/cf-cli/install-go-cli.html
- Login <br/>
`cf login -a api.london.cloud.service.gov.uk -u <your_username>`
- Set your deployment target (sandbox/production) <br/>
`cf target -o dluhc-core -s <deploy_environment>`
- Deploy <br/>
`cf push dluhc-core --strategy rolling`. This will use the [manifest file](manifest.yml)
Once the app is deployed:
- Get a rails console <br/>
`cf ssh dluhc-core -t -c "/tmp/lifecycle/launcher /home/vcap/app 'rails console' ''"`
### Single log submission ### Single log submission

114
config/environments/sandbox.rb

@ -0,0 +1,114 @@
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.cache_classes = true
# 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 either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
# 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.*/ ]
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Include generic and useful information about system operation, but avoid logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII).
config.log_level = :info
# Prepend all log lines with the following tags.
config.log_tags = [:request_id]
# 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 = "data_collector_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
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Log disallowed deprecations.
config.active_support.disallowed_deprecation = :log
# Tell Active Support which deprecation messages to disallow.
config.active_support.disallowed_deprecation_warnings = []
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Use a different logger for distributed setups.
# require "syslog/logger"
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Inserts middleware to perform automatic connection switching.
# The `database_selector` hash is used to pass options to the DatabaseSelector
# middleware. The `delay` is used to determine how long to wait after a write
# to send a subsequent read to the primary.
#
# The `database_resolver` class is used by the middleware to determine which
# database is appropriate to use based on the time delay.
#
# The `database_resolver_context` class is used by the middleware to set
# timestamps for the last write to the primary. The resolver uses the context
# class timestamps to determine how long to wait before reading from the
# replica.
#
# By default Rails will store a last write timestamp in the session. The
# DatabaseSelector middleware is designed as such you can define your own
# strategy for connection switching and pass that into the middleware through
# these configuration options.
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end

5
config/webpack/sandbox.js

@ -0,0 +1,5 @@
process.env.NODE_ENV = process.env.NODE_ENV || 'sandbox'
const environment = require('./environment')
module.exports = environment.toWebpackConfig()

20
doc/adr/adr-004.md

@ -0,0 +1,20 @@
### ADR - 004: Infrastructure Switch
#### Gov PaaS
The application infrastructure will be moved from the initial AWS set up to Gov PaaS. The initial expectation is to have a Gov PaaS account `dluhc-core` with 2 spaces `sandbox`, `production`.
Sandbox will consist of 2 small instances (512M) and 1 tiny-unencrypted-13 Postgres instance.
Production infrastructure sizing will be decided at a later time and once our account has been upgraded to a paid account.
The reasoning for this is:
- Department policy is to use Gov PaaS whenever possible
- DLUHC does not have a lot of internal dev ops skills/capacity so by leveraging Gov PaaS we can leverage having most of the monitoring, running, scaling and security already provided.
- We get a simpler infrastructure setup than the AWS setup we currently have
- All of the infrastructure we currently require is well supported on Gov PaaS
One potential downside is that data replication to CDS may be slightly more complicated as adding our database to a VPC requires the Gov PaaS support team to do that on our behalf.
This also means the Github repository previously used for [Infrastructure](https://github.com/communitiesuk/mhclg-data-collection-beta-infrastructure) will be archived after this change goes in as it won't be needed anymore.

14
manifest.yml

@ -0,0 +1,14 @@
---
applications:
- name: dluhc-core-app
buildpacks:
- https://github.com/cloudfoundry/ruby-buildpack.git
env:
RAILS_ENV: sandbox
processes:
- type: web
command: rake db:migrate && bin/rails server
instances: 2
memory: 512M
services:
- dluhc-core-sandbox-postgres

19042
package-lock.json generated

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save