Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
YOU54F committed Apr 25, 2019
0 parents commit ee5523e
Show file tree
Hide file tree
Showing 35 changed files with 3,535 additions and 0 deletions.
39 changes: 39 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
version: 2.1

jobs:
test:
docker:
# the Docker image with Cypress dependencies
- image: circleci/node:8.15
environment:
## this enables colors in the output
TERM: xterm
working_directory: ~/app
steps:
- checkout
- run:
name: downloadpb
command: make downloadpb
- run:
name: Install deps
command: yarn install
- run:
name: packagewithpg
command: make packagewithpg
- run:
name: package
command: make package
- run:
name: buildpglayer
command: make buildpglayer
- run:
name: create_domain
command: yarn run create-domain
- run:
name: deploy
command: yarn run deploy

workflows:
build-test:
jobs:
- test
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.ruby-gemset
.ruby-version
node_modules
.git
.serverless
vendor/bundle
.DS_Store
.bundle/config
.env
15 changes: 15 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
SERVERLESS_DOMAIN_NAME=
SERVERLESS_CERTIFICATE_NAME=
PACT_BROKER_DATABASE_USERNAME=
PACT_BROKER_DATABASE_PASSWORD=
PACT_BROKER_DATABASE_HOST=
PACT_BROKER_DATABASE_NAME=
PACT_BROKER_LOG_LEVEL=DEBUG
PACT_BROKER_BASE_URL=https://$SERVERLESS_DOMAIN_NAME
PG_RUBY_LAYER_ARN=arn:aws:lambda:eu-west-2:************:layer:pgRuby25:1
AWS_PROFILE_NAME=
AWS_REGION='eu-west-2'\
PACT_BROKER_BASIC_AUTH_USERNAME=
PACT_BROKER_BASIC_AUTH_PASSWORD=
PACT_BROKER_BASIC_AUTH_READ_ONLY_USERNAME=
PACT_BROKER_BASIC_AUTH_READ_ONLY_PASSWORD=
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.ruby-gemset
.ruby-version
node_modules
.git
.serverless
vendor/bundle
.DS_Store
.bundle/config
.env
lib/
9 changes: 9 additions & 0 deletions .serverlessrack
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SERVERLESS_DOMAIN_NAME=
SERVERLESS_CERTIFICATE_NAME=
PACT_BROKER_DATABASE_USERNAME=
PACT_BROKER_DATABASE_PASSWORD=
PACT_BROKER_DATABASE_HOST=
PACT_BROKER_DATABASE_NAME=
PACT_BROKER_LOG_LEVEL=DEBUG
PACT_BROKER_BASE_URL=https://$SERVERLESS_DOMAIN_NAME
PG_RUBY_LAYER_ARN=arn:aws:lambda:eu-west-2:************:layer:pgRuby25:1
21 changes: 21 additions & 0 deletions .slsignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
rubypg_layer/**
node_modules/**
.serverless/**
.circleci/**
.bundle/**
.gitignore
.slsignore
build-withpg.sh
build-withpglayer.sh
docker-compose.yml
Dockerfile
Gemfile
Gemfile.lock
Makefile
package.json
README.md
renovate.json
serverless.yml
serverless.domain.yml
yarn.lock
.env
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM lambci/lambda:build-ruby2.5

RUN yum install -y postgresql postgresql-devel
# If we need mysql
# RUN yum install -y postgresql postgresql-devel mysql-devel

ADD pact_broker/Gemfile /var/task/Gemfile
ADD pact_broker/Gemfile.lock /var/task/Gemfile.lock

RUN bundle install && bundle install --deployment
20 changes: 20 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 changes: 20 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
downloadpb:
rm -rf pact_broker && curl -L https://api.github.com/repos/dius/pact_broker-docker/tarball | tar xz --strip=1 */pact_broker

packagewithpg:
./build-withpg.sh

package:
./build-withpglayer.sh

buildpglayer:
cd rubypg_layer && ./build.sh

deploypglayer:
cd rubypg_layer && sls deploy -v

logs:
awslogs get /aws/lambda/pact-broker-serverless-dev-api --profile=${AWS_PROFILE_NAME}

deploy:
sls deploy -v
164 changes: 164 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
Serverless Pact Broker
==================

This repository deploys [Pact Broker](https://github.com/pact-foundation/pact_broker) using as an AWS Lambda function along with API Gateway using Serverless.

## Prerequisites

* A running postgresql database and the ability to connect to it (see [POSTGRESQL.md][postgres]).
* An AWS account
* A custom domain in route 53 with a certificate

## Getting Started

1. [Install Docker](https://docs.docker.com/engine/installation/)
2. Prepare your environment if you are not running postgresql in a docker container. Setup the pact broker connection to the database through the use of the following environment variables.
<!-- If you want to use a disposable postgres docker container just do `export DISPOSABLE_PSQL=true` before running the [script/test.sh][test-script]. -->

For a postgres database

* PACT_BROKER_DATABASE_USERNAME
* PACT_BROKER_DATABASE_PASSWORD
* PACT_BROKER_DATABASE_HOST
* PACT_BROKER_DATABASE_PORT (optional, defaults to the 5432)
* PACT_BROKER_DATABASE_NAME

<!-- 1. Test the pact broker environment by executing [script/test.sh][test-script] -->

## Serverless setup

* `README.md`- this file
* `Makefile` - useful commands to run everything
* `build-withpg.sh` - a build file to compile the gem dependencies and postgres in your function
* `build-withpglayer.sh` - a build file to compile the gem dependencies and utilise postgres via an aws layer, creatable in the rubypg_layer folder.
* `serverless.yml` - A file to deploy the application using Serverless
* `rubypg_layer` - an aws layer template to provide an aws base with postgres dependencies satisfied
* `.slsignore` - .gitignore style file to exclude files from packaged deployment artefacts
* `.env.example` - for your secrets, rename to `.env` and fill out with your variables

## Serverless Plugins

plugins:
- serverless-rack - A ruby handler to provide a translation between lambda functions and our rack middleware
- serverless-ignore - A .gitignore like file to exclude files from your serverless deployment package.
- serverless-domain-manager - A way to map your function to a cloud 53 hosted domain name

## Running with Serverless

1. Run `make downloadpb` which will download the latest version of the `pact_broker` folder in `dius/pact_broker-docker` _note_ this command will remove the old folder without futher warning.
2. Open `pact_broker/Gemfile` and comment out Passenger, mysql2 and sqlite, as we don't need them
1. Passenger - We are using Rack here
2. MySql2 - This may work, but doubles the size of the deployment package, so if its needed, we can create a mysql layer.
3. Sqlite - Same reason as above, I am only using PostGres in my examples so I want as small a function as possible.
3. Run `make packagewithpg` to build the pact broker bundle dependencies and postgres dependencies in a docker container, and copy them to your `vendor` and `lib` folders.
Alternatively you can run `make package` to build the pact broker bundle dependencies. You will need a custom aws layer with the postgres dependencies satisfied to run your function successfully. See the next section
4. Run `yarn install` or delete the `.lock` file and run `npm install` if you prefer. This will install serverless, along with serverless-rack, serverless-ignore & serverless-domain-manager.
5. edit `pact_broker/config.ru` and add `config.log_dir = "/tmp/log"` to the following method, in order to output our logs to disk space, that the lambda function has write permissions to.

```ruby
app = PactBroker::App.new do | config |
config.log_dir = "/tmp/log"
...
end
```

5. Run `make deploy` to deploy your function, and you will receive a URL at the end if everything went OK.

_note_ out of the box, serverless rack does not let us configure the base folder path to `config.ru`, I currently have a fork and will propose a PR to allow this setting, via a custom var. For now, the fork will take the env argument `RACK_CONFIG_BASE` which is set to `pact_broker/config.ru` in our `serverless.yml`. If it is not set, it will revert to serverless-racks default of `config.ru`.

6. Run `make logs` to access the aws lambda logs from cloudwatch, you will need to curl your endpoint or load it in the browser to initiate a request after deployment (and see anything useful in the logs)

## Mapping a custom domain to your function

If you have a route 53 domain setup, you can use serverless-domain-manager to map your to your domain.

1. In the root `serverless-yml`, we have a custom domain section


```yml
customDomain:
domainName: ${env:SERVERLESS_DOMAIN_NAME}
certificateName: ${env:SERVERLESS_CERTIFICATE_NAME}
stage: dev
createRoute53Record: true
```
These are read in via env vars
```
SERVERLESS_DOMAIN_NAME=you54f.co.uk
SERVERLESS_CERTIFICATE_NAME=you54f.co.uk
PACT_BROKER_BASE_URL=https://$SERVERLESS_DOMAIN_NAME
```

We need to pass the domain name into the pact broker app via `PACT_BROKER_BASE_URL`.

2. You will need a user with permissions to update route53 records, a template is provided in `serverless.domain.yml`, you can run this in via cloudformation.


## Creating a custom AWS layer with Postgres dependencies satisfied

1. Run `make pglayer` to build the postgres dependencies in a docker container and save them back to your host in the `lib` folder.
2. Run `deploy pglayer` to deploy it to AWS. Note the ARN address outputted to the console.
3. In the root folder, update `.env.example` to `.env` and set the following env var `PG_RUBY_LAYER_ARN=arn:aws:lambda:eu-west-2:************:layer:pgRuby25:1` to the value in step 2
4. In the root `serverless-yml`, we read the env var `PG_RUBY_LAYER_ARN` which contains the ARN recorded in the previous step. Uncomment this section out.

```yml
layers:
- ${env:PG_RUBY_LAYER_ARN}
```
## Notes
* The application makes use of Rack via Serverless-Rack
## Using basic auth
To enable basic auth, run your container with:
* `PACT_BROKER_BASIC_AUTH_USERNAME`
* `PACT_BROKER_BASIC_AUTH_PASSWORD`
* `PACT_BROKER_BASIC_AUTH_READ_ONLY_USERNAME`
* `PACT_BROKER_BASIC_AUTH_READ_ONLY_PASSWORD`

Developers should use the read only credentials on their local machines, and the CI should use the read/write credentials. This will ensure that pacts and verification results are only published from your CI.

Note that the [verification status badges][badges] are not protected by basic auth, so that you may embed them in README markdown.

## Heartbeat URL

If you need to make a heartbeat URL publicly available, set `PACT_BROKER_PUBLIC_HEARTBEAT=true`. No database connection will be made during the execution of this endpoint.

## Using SSL

SSL is provided as default with the API Gateway

## Setting the log level

Set the environment variable `PACT_BROKER_LOG_LEVEL` to one of `DEBUG`, `INFO`, `WARN`, `ERROR`, or `FATAL`.

## Webhook whitelists

* PACT_BROKER_WEBHOOK_HOST_WHITELIST - a space delimited list of hosts (eg. `github.com`), network ranges (eg. `10.2.3.41/24`, or regular expressions (eg. `/.*\\.foo\\.com$/`). Regular expressions should start and end with a `/` to differentiate them from Strings. Note that backslashes need to be escaped with a second backslash. Please read the [Webhook whitelists](https://github.com/pact-foundation/pact_broker/wiki/Configuration#webhook-whitelists) section of the Pact Broker configuration documentation to understand how the whitelist is used. Remember to use quotes around this value as it may have spaces in it.
* PACT_BROKER_WEBHOOK_SCHEME_WHITELIST - a space delimited list (eg. `http https`). Defaults to `https`.

## Other environment variables

* PACT_BROKER_BASE_EQUALITY_ONLY_ON_CONTENT_THAT_AFFECTS_VERIFICATION_RESULTS - `true` by default, may be set to `false`.
* PACT_BROKER_ORDER_VERSIONS_BY_DATE - `true` by default, may be set to `false`.
* PACT_BROKER_DISABLE_SSL_VERIFICATION - `false` by default, may be set to `true`.

## General Pact Broker configuration and usage

Documentation for the Pact Broker application itself can be found in the Pact Broker [wiki][pact-broker-wiki].

# Troubleshooting

See the [Troubleshooting][troubleshooting] page on the wiki.

[badges]: https://github.com/pact-foundation/pact_broker/wiki/Provider-verification-badges
[troubleshooting]: https://github.com/DiUS/pact_broker-docker/wiki/Troubleshooting
[postgres]: https://github.com/DiUS/pact_broker-docker/blob/master/POSTGRESQL.md
[test-script]: https://github.com/DiUS/pact_broker-docker/blob/master/script/test.sh
[docker-compose]: https://github.com/DiUS/pact_broker-docker/blob/master/docker-compose.yml
[pact-broker-wiki]: https://github.com/pact-foundation/pact_broker/wiki
[reverse-proxy]: https://github.com/pact-foundation/pact_broker/wiki/Configuration#running-the-broker-behind-a-reverse-proxy
21 changes: 21 additions & 0 deletions build-withpg.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash -x

set -e

rm -rf lib && mkdir -p lib
rm -rf vendor

docker build -t ruby25-pg-builder -f Dockerfile .

CONTAINER=$(docker run -d ruby25-pg-builder false)

docker cp \
$CONTAINER:/usr/lib64/libpq.so.5.5 \
lib/libpq.so.5

docker cp \
$CONTAINER:/var/task/vendor \
vendor

docker stop $CONTAINER
docker rm $CONTAINER
15 changes: 15 additions & 0 deletions build-withpglayer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash -x

set -e

rm -rf vendor

docker build -t ruby25-pg-builder -f Dockerfile .

CONTAINER=$(docker run -d ruby25-pg-builder false)

docker cp \
$CONTAINER:/var/task/vendor \
vendor

docker rm $CONTAINER
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "3"

services:
postgres:
image: postgres
healthcheck:
test: psql postgres --command "select 1" -U postgres
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: postgres
Loading

0 comments on commit ee5523e

Please sign in to comment.