Skip to content

Conversation

@witoff
Copy link
Contributor

@witoff witoff commented Jun 8, 2017

Summary

Per #666 (yikes!), we'd like to better document deployment configurations for trillian. This builds on pull #631 to provide simple, few-line local and cloud deployments using docker-compose and terraform.

Notes

  • This removes the MySQL strict clause in storage.sql's which is incompatible with aurora.
  • This merges Dockerfiles into /examples/deployments/ directory. Shipping these opinionated Dockerfiles next to source code felt like a stretch.
  • This pulls wait-for-it in at docker build time. Is this an appropriate way to use a dependency with our license?

@witoff witoff changed the title Document Local and AWS Deployments Automate Local and AWS Deployments Jun 12, 2017
terraform apply aws/

# Set Variables
HOST=...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about DB_HOST?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merged this with automated launch userdata within terraform (more automation!) and changed to DB_HOST.


resource "aws_security_group" "trillian" {
name = "trillian"
description = "Allow MySQL from Single IP"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to allow from a single CIDR block :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated ;)

}

download
echo "ffe253ce564df22adbcf9c799e251ca0 wait-for-it.sh" > file.md5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could do shas256sum --check <( echo "... wait-for-it.sh" ) and avoid creating the file.md5

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doh, thanks. fixed!

@AlCutter
Copy link
Member

BTW - we generally rebase topic branches onto latest master rather than merge master into the topic branch

@witoff
Copy link
Contributor Author

witoff commented Jun 16, 2017

rebased :)

Copy link
Contributor

@RJPercival RJPercival left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the wait, since I wasn't marked as a reviewer and @AlCutter had already approved it, I'd managed to overlook this.

Both build and example deployment files are stored within this repo. For any of the below deployment methods, start here:

```shell
git clone git@github.com:google/trillian.git
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

export DB_PASSWORD="$(openssl rand -hex 16)"

# Bring up services defined in this compose file. This includes:
# - local MySQL databse
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/databse/database/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


# Bring up services defined in this compose file. This includes:
# - local MySQL databse
# - container to seed the database
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/seed/initialize/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


**Run With Docker Compose**

For simple deployments running in a container is an easy way to get up and running with a local database. To use Docker to run and interact with Trillian, start here:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/For simple deployments/For simple deployments,/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


For simple deployments running in a container is an easy way to get up and running with a local database. To use Docker to run and interact with Trillian, start here:

Set a random password and bring up the services defined in the provided compose file. This includes a local mysql database database, a one-shot container to create the schema and the trillian server:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/mysql database database/MySQL database/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

ADD . /go/src/github.com/google/trillian
WORKDIR /go/src/github.com/google/trillian

RUN go get -v ./server/trillian_log_server
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is trillian_log_server needed in this container?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed this line but going to keep the source code included so /scripts/*.sh can be run

[ -z ${DB_NAME+x} ] && DB_NAME="test"
# format reused supplied environment variables
FLAGS=""
[ -z ${DB_PASSWORD+x} ] || FLAGS="${FLAGS} -p$DB_PASSWORD"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assumes that $DB_PASSWORD does not contain spaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed with: -p'${DB_PASSWORD}'

case "$1" in
--force) FORCE=true ;;
--verbose) VERBOSE=true ;;
*) FLAGS="${FLAGS} $1"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will remove quotation marks around arguments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making $FLAGS an array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a verbose logging statement that will print args to clarify what's being run. even as an array i'd still have to reconstruct with proper flags to pass to mysql. if you think this is a blocker we can revert back to passing all flags via $@ to mysql and only accepting other params via envars.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested fix: https://github.com/RJPercival/trillian/commits/witoff/aws

This will properly handle quoted arguments. I made another couple of small improvements while I was poking around in that file, which you can find just after that commit.

if [ -z ${REPLY+x} ] || [[ $REPLY =~ ^[Yy]$ ]]
then
echo "Resetting DB..."
mysql -u $DB_USER $FLAGS -e "DROP DATABASE IF EXISTS ${DB_NAME};"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some flags, e.g. --defaults-extra-file, will only work if they are the first flag passed to mysql. This flag ordering makes passing that flag impossible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reordered to: mysql -u $FLAGS $DB_USER and preserved user supplied order in collect_vars fn.

echo "Resetting DB..."
mysql -u $DB_USER $FLAGS -e "DROP DATABASE IF EXISTS ${DB_NAME};"
mysql -u $DB_USER $FLAGS -e "CREATE DATABASE ${DB_NAME};"
mysql -u $DB_USER $FLAGS -e "GRANT ALL ON ${DB_NAME}.* TO '${DB_NAME}'@'localhost' IDENTIFIED BY 'zaphod';"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not sure how this is supposed to work. Granting access for the user to connect only from localhost shouldn't work if the Trillian server/signer is running on a different machine, as will likely be the case on cloud infrastructure. It may work if $DB_NAME == "test", because some MySQL installations come with default privileges that grant unrestricted access to that database for all users.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm also not entirely clear on this. this change mirrors what's currently in the master branch and just makes DB_NAME a variable. after this is merged i'd like work on better integration testing here which may prove this unnecessary.

Copy link
Contributor

@RJPercival RJPercival Jul 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the database name hardcoded as "test", it's going to get the special treatment that MySQL gives that table by default. By replacing this with a variable, that's no longer true unless $DB_NAME == "test". Therefore, I think replacing 'localhost' with '%' on this line is warranted. Access to the database server should be restricted to certain IP ranges, so it won't allow brute force attacks on this user by just anyone.

@witoff witoff force-pushed the witoff/aws branch 2 times, most recently from 9b39cce to 47bf243 Compare June 30, 2017 23:01
@RJPercival
Copy link
Contributor

RJPercival commented Jul 3, 2017

I think you need to rebase - looks like master was broken due to a change in a dependency when you last rebased.

@daviddrysdale
Copy link
Contributor

Yeah, Prometheus changed underneath us upstream -- pull #724 should have fixed it though.

witoff and others added 4 commits July 5, 2017 10:12
DB operations should be flexibile to run against many environments

Dockerize core components

remove deprecated comment
@witoff
Copy link
Contributor Author

witoff commented Jul 6, 2017

k, rebased and tests passing now.

mysql -u $FLAGS $DB_USER -e "DROP DATABASE IF EXISTS ${DB_NAME};"
mysql -u $FLAGS $DB_USER -e "CREATE DATABASE ${DB_NAME};"
mysql -u $FLAGS $DB_USER -e "GRANT ALL ON ${DB_NAME}.* TO '${DB_NAME}'@'localhost' IDENTIFIED BY 'zaphod';"
mysql -u $FLAGS $DB_USER -D ${DB_NAME} < ${TRILLIAN_PATH}/storage/mysql/storage.sql
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you meant to separate "-u" and "$DB_USER". FYI, I've fixed this in the branch I referenced above, as a side-effect of adding "-u $DB_USER" to $FLAGS in collect_vars().

@RJPercival
Copy link
Contributor

These should be my final comments; it's looking good to merge bar those.

@witoff witoff force-pushed the witoff/aws branch 2 times, most recently from 67f235b to 115c4da Compare July 24, 2017 06:01
@witoff
Copy link
Contributor Author

witoff commented Jul 24, 2017

edits are merged (thank you!) and waiting on #756 to fix broken golang/mocks updates before we can merge.

@gdbelvin
Copy link
Contributor

gdbelvin commented Jul 24, 2017

Hi @witoff, thanks for this PR. Rather than moving the opinionated Dockerfiles to the example directory, would you mind keeping them in-place and making them less opinionated? Having some kind of starting Dockerfile would help other projects adopt Trillian faster.

If you feel that the opinionated Dockerfiles have value, please use the from Docker command to start with the less opinionated Dockerfiles, and add the opinionated bits in the example directory like you've suggested.

Thanks!
-Gary

@witoff
Copy link
Contributor Author

witoff commented Jul 24, 2017

@gdbelvin updated PR with a proposal on how these could work. my thought process is that main.go exposes a set of flags, default Dockerfiles define what's needed to build/run the binary and it's up to the user to configure from there, likely via docker-compose, docker run etc.

Specifying flags/healthcheck/envars in the Dockerfile makes assumptions about one's infrastructure that could reasonably be incorrect which would force me to write a separate Dockerfile anyways.

I've also kept the /examples/... Dockerfiles separate, since inheriting from the /server/... Dockerfiles would force a 2-phase build (or more scripts) which feels like it would work against the goal here of making it easy to reason about and run one example deployment.

wdyt? if you're okay with this approach does this break any other uses of these dockerfiles that i can help update?

@gdbelvin
Copy link
Contributor

This is great. I now remember why I had the flags in the original docker files, and that is because go flags doesn't pick up environment variables, so I basically duplicated the flags with an additional (confusing) set of defaults. These non-opinionated Docker files would be great if we had a way for go flags to pick up passed-in environment variables.

@RJPercival @Martin2112 Do we have a plan for passing flags via environment variables?

@RJPercival
Copy link
Contributor

No, we had no plans to implement that. It's easy to do, probably something like this in cmd/flags.go:

func ParseFlagsFromEnv() {
  flag.VisitAll(func (f *Flag) {
    // Might want to modify the flag name before using it as the envar name, e.g. uppercase and/or prefix with "TRILLIAN_".
    if env, ok := os.LookupEnv(f.Name); ok {
      f.Value.Set(env)
    }
  })
}

The only question is how much value there is in supporting this. Presumably this is to support people following the 12 Factor App guidelines, which lays out the advantages. The main cost is that it adds a non-obvious, third way of controlling the behaviour of Trillian's binaries.

@Martin2112
Copy link
Contributor

Martin2112 commented Jul 26, 2017 via email

Copy link
Contributor

@gdbelvin gdbelvin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use the command option in docker-compose to add commandline flags now that we're using ENTRYPOINT

LGTM.

@gdbelvin gdbelvin merged commit 9179d40 into google:master Aug 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants