summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2013-02-11 00:09:13 -0800
committerelijah <elijah@riseup.net>2013-02-11 00:09:13 -0800
commit90055bf202b0ae4d28a52cd2d1b5f1cf14210383 (patch)
tree1e05c47b4a2c59ae3f232b83b7b10fd54dbe55c7 /docs
parentf8900bc466968fd650967abc658e701c172045c0 (diff)
many edits to platform docs
Diffstat (limited to 'docs')
-rw-r--r--docs/platform/config.md110
-rw-r--r--docs/platform/en.md61
-rw-r--r--docs/platform/quick-start.md25
3 files changed, 160 insertions, 36 deletions
diff --git a/docs/platform/config.md b/docs/platform/config.md
index 2d56467..89bf934 100644
--- a/docs/platform/config.md
+++ b/docs/platform/config.md
@@ -1,5 +1,8 @@
-Configuration Files
-=================================
+Configuration files
+===================================
+
+File format
+-------------------------------------------
All configuration files are in JSON format. For example
@@ -8,7 +11,7 @@ All configuration files are in JSON format. For example
"key2": "value2"
}
-Keys should match /[a-z0-9_]/
+Keys should match `/[a-z0-9_]/`
Unlike traditional JSON, comments are allowed. If the first non-whitespace character is '#' the line is treated as a comment.
@@ -18,15 +21,20 @@ Unlike traditional JSON, comments are allowed. If the first non-whitespace chara
"key": "value" # this is an error
}
-Options in the configuration files might be nested. For example:
+Options in the configuration files might be nested hashes or arrays. For example:
{
"openvpn": {
- "ip_address": "1.1.1.1"
+ "ip_address": "1.1.1.1",
+ "protocols": ["tcp", "udp"],
+ "options": {
+ "public_ip": false,
+ "adblock": true
+ }
}
}
-If the value string is prefixed with an '=' character, the value is evaluated as ruby. For example
+If the value string is prefixed with an '=' character, the value is evaluated as ruby. For example:
{
"domain": {
@@ -37,14 +45,88 @@ If the value string is prefixed with an '=' character, the value is evaluated as
In this case, "api_domain" will be set to "api.domain.org".
+Inheritance
+----------------------------------------
+
+Suppose you have a node configuration for `bitmask/nodes/dns_europe.json` like so:
+
+ {
+ "services": "dns",
+ "tags": ["production", "europe"],
+ "ip_address": "1.1.1.1"
+ }
+
+This node will have hostname "dns-europe" and it will inherit from the following files (in this order):
+
+ 1. provider_base/common.json
+ 2. bitmask/common.json
+ 3. provider_base/services/dns.json
+ 4. bitmask/services/dns.json
+ 5. provider_base/tags/production.json
+ 6. bitmask/tags/production.json
+ 7. provider_base/tags/europe.json
+ 8. bitmask/tags/europe.json
+ 9. bitmask/nodes/dns_europe.json
+
+The `provider_base` directory is under the `leap_platform` specified in the file `Leapfile`.
+
+To see all the variables a node has inherited, you could run `leap inspect dns_europe`.
+
+Macros
+----------------------------------------
+
+When using evaluated ruby in a JSON configuration file, there are several special macros that are available. These are evaluated in the context of a node (available as the variable `self`).
+
The following methods are available to the evaluated ruby:
-* nodes -- A list of all nodes. This list can be filtered.
-* global.services -- A list of all services.
-* global.tags -- A list of all tags.
-* file(filename) -- Inserts the full contents of the file. If the file is an erb
- template, it is rendered.
-* file_path(filename) -- Ensures that the file will get rsynced to the node as an individual file. The value returned by `file_path` is where this file will utlimately live when on the node.
-* secret(symbol) -- Returns the value of a secret in secrets.json (or creates it if necessary).
-* variable -- Any variable inherited by a particular node is available by just referencing it using either hash notation or object notation (i.e. self['domain']['public'] or domain.public). Circular references are not allowed, but otherwise it is ok to nest evaluated values in other evaluated values.
+`nodes`
+
+ > A hash of all nodes. This list can be filtered.
+
+`nodes_like_me`
+
+ > A hash of nodes that have the same deployment tags as the current node (e.g. 'production' or 'local').
+
+`global.services`
+
+ > A hash of all services, e.g. `global.services['openvpn']`.
+
+`global.tags`
+
+ > A hash of all tags, e.g. `global.tags['production']`.
+
+ `global.provider`
+
+ > Can be used to access variables defined in `provider.json`, e.g. `global.provider.contacts.default`.
+
+`file(filename)`
+
+ > Inserts the full contents of the file. If the file is an erb template, it is rendered. The filename can either be one of the pre-defined file symbols, are it can be a path relative to the "files" directory in your provider instance. E.g, `file :ca_cert` or `files 'ca/ca.crt'`.
+
+`file_path(filename)`
+
+ > Ensures that the file will get rsynced to the node as an individual file. The value returned by `file_path` is the full path where this file will ultimately live when deploy to the node. e.g. `file_path :ca_cert` or `file_path 'branding/images/logo.png'`.
+
+`secret(:symbol)`
+
+ > Returns the value of a secret in secrets.json (or creates it if necessary). E.g. `secret :couch_admin_password`
+
+`variable.variable`
+
+ > Any variable defined or inherited by a particular node configuration is available by just referencing it using either hash notation or object field notation (e.g. `['domain']['public']` or `domain.public`). Circular references are not allowed, but otherwise it is OK to nest evaluated values in other evaluated values. If a value has not been defined, the hash notation will return nil but the field notation will raise an exception.
+
+Using hashes
+-----------------------------------------
+
+The macros `nodes`, `nodes_like_me`, `global.services`, and `global.tags` all return a hash of other objects. You can reference these hashes either directly or using a filter:
+
+Direct access:
+
+ nodes['vpn1'] # returns node named 'vpn1'
+ global.services['openvpn'] # returns service named 'openvpn'
+
+Filters:
+ nodes[:public_dns => true] # all nodes where public_dns == true
+ nodes[:services => 'openvpn', :services => 'tor'] # openvpn OR tor
+ nodes[:services => 'openvpn'][:tags => 'production'] # openvpn AND production
diff --git a/docs/platform/en.md b/docs/platform/en.md
index 4f4d56d..194a070 100644
--- a/docs/platform/en.md
+++ b/docs/platform/en.md
@@ -1,7 +1,20 @@
LEAP Platform Tools
+=================================
+
+If you have ever been a sysadmin for an organization or company that provides communication services to end users, you have probably screamed this many times:
+
+> $%#*&!! It shouldn't have to be this hard.
+
+We agree! The LEAP Platform is consists of a set of complementary packages and recipes to automate the maintenance of LEAP services in a hardened Debian environment. Our goal is to make it as painless as possible for sysadmins to deploy and maintain an service provider's infrastructure.
+
+There are three main parts to the platform:
+
+1. The platform recipes.
+2. The provider instance.
+3. The command line tool you use to manage your instance.
Platform recipes (leap_platform)
-=================================
+----------------------------------------
The LEAP platform recipes define an abstract service provider. It consists of puppet modules designed to work together to provide a system administrator everything they need to manage a service provider infrastructure that provides secure communication services.
@@ -9,43 +22,57 @@ Typically, a system administrator will not need to modify the LEAP platform reci
The recipes are abstract. In order to configure settings for a particular service provider, a system administrator creates a provider instance. The platform recipes also include a base provider that provider instances inherit from.
+The repository for the platform recipes is `git://leap.se/leap_platform`.
+
Provider instance
-================================
+-----------------------------------------
A "provider instance" is a directory tree (typically tracked in git) containing all the configurations for a service provider's infrastructure. A provider instance primarily consists of:
-* A configuration file for each server (node) in the provider's infrastructure (e.g. nodes/vpn1.json)
-* A global configuration file for the provider (e.g. provider.json).
-* Additional files, such as certificates and keys (e.g. files/nodes/vpn1/vpn1_ssh.pub).
-* A pointer to the platform recipes (as defined in "Leapfile")
+* A configuration file for each server (node) in the provider's infrastructure
+* A global configuration file for the provider
+* Additional files, such as certificates and keys
+* A pointer to the platform recipes
A minimal provider instance directory looks like this:
- └── rewire # provider instance directory
- ├── common.json # settings common to all nodes
- ├── Leapfile # specifies which platform recipe directory to use
- ├── provider.json # global settings of the provider
- ├── files/ # keys, certificates, and other files.
- ├── nodes/ # a directory for node configurations, one node per file
- └── users/ # public key information for privileged sysadmins
+ └── myprovider # provider instance directory
+ ├── common.json # settings common to all nodes
+ ├── Leapfile # specifies which platform recipe directory to use
+ ├── provider.json # global settings of the provider
+ ├── files/ # keys, certificates, and other files.
+ ├── nodes/ # a directory for node configurations, one node per file
+ └── users/ # public key information for privileged sysadmins
A provider instance directory contains everything needed to manage all the servers that compose a provider's infrastructure. Because of this, you can use normal git development work-flow to manage your provider instance.
Command line program (leap_cli)
-=======================================
+------------------------------------------
-The command line program `leap` is used by sysadmins to manage everything about a service provider's infrastructure. Except when creating an new provider instance, `leap` is run from within the directory tree of a provider instance.
+The [command line program](command) `leap` is used by sysadmins to manage everything about a service provider's infrastructure. Except when creating an new provider instance, `leap` is run from within the directory tree of a provider instance.
The `leap` command line has many capabilities, including:
-* Create, initialize, and deploy nodes (e.g. servers)
+* Create, initialize, and deploy nodes
* Manage keys and certificates
* Query information about the node configurations
Traditional system configuration automation systems, like puppet or chef, deploy changes to servers using a pull method. Each server pulls a manifest from a central master server and uses this to alter the state of the server.
-Instead, LEAP uses a masterless push method: The user runs 'leap deploy' from the provider instance directory on their desktop machine to push the changes out to every server (or a subset of servers). LEAP still uses puppet, but there is no central master server that each node must pull from.
+Instead, LEAP uses a masterless push method: The user runs `leap deploy` from the provider instance directory on their desktop machine to push the changes out to every server (or a subset of servers). LEAP still uses puppet, but there is no central master server that each node must pull from.
One other significant difference between LEAP and typical system automation is how interactions among servers are handled. Rather than store a central database of information about each server that can be queried when a recipe is applied, the `leap` command compiles static representation of all the information a particular server will need in order to apply the recipes. In compiling this static representation, `leap` can use arbitrary programming logic to query and manipulate information about other servers.
These two approaches, masterless push and pre-compiled static configuration, allow the sysadmin to manage a set of LEAP servers using traditional software development techniques of branching and merging, to more easily create local testing environments using virtual servers, and to deploy without the added complexity and failure potential of a master server.
+
+The repository for the `leap` command is `git://leap.se/leap_cli`.
+
+Getting started
+----------------------------------
+
+We recommend you read the platform documentation in this order:
+
+1. [quick start tutorial](platform/quick-start).
+* platform [examples](platform/examples).
+* the `leap` [command reference](platform/command).
+* [configuration format](platform/config).
diff --git a/docs/platform/quick-start.md b/docs/platform/quick-start.md
index 3df4333..ff2488f 100644
--- a/docs/platform/quick-start.md
+++ b/docs/platform/quick-start.md
@@ -1,3 +1,16 @@
+LEAP Platform Quick Start
+=====================================================
+
+This is a very minimal tutorial that will walk you through the process of creating and deploying a service provider running the LEAP platform.
+
+All the commands in this tutorial are run on your home desktop or laptop computer, or whatever machine you want to do your system administration from.
+
+What you will need:
+
+* A machine running Debian (or derivatives)
+* At least 4gb of RAM
+* A fast internet connection
+
Installation
--------------------------------
@@ -5,9 +18,9 @@ Install prerequisites:
sudo apt-get install git ruby ruby-dev rsync openssh-client openssl rake
-Install prerequisites to test Leap Platform locally with vagrant:
+Install Vagrant in order to be able to test with local virtual machines (typically optional, but required for this tutorial):
- sudo apt-get install virtualbox
+ sudo apt-get install vagrant virtualbox
This tutorial should work with ruby1.8, but has only been tested using ruby1.9.
@@ -22,11 +35,11 @@ Alternately, you can install `leap` from source:
cd leap_cli
rake build
-* Install as root user (recommended):
+Then, install as root user (recommended):
sudo rake install
-* Install as unprivileged user:
+Or, install as unprivileged user:
rake install
# watch out for the directory leap is installed to, then i.e.
@@ -105,7 +118,7 @@ Create a local node, with the service "webapp":
leap node add --local web1 services:webapp
-This created a node configuration file, but it did not create the virtual machine. In order to test our node "web1", we need to first spin up a virtual machine. The next command will probably take a very long time, because it will need to download an image to create the virtual machine (about 700mb).
+This created a node configuration file, but it did not create the virtual machine. In order to test our node "web1", we need to first spin up a virtual machine. The next command will probably take a very long time, because it will need to download a VM image (about 700mb).
leap local start
@@ -121,6 +134,8 @@ That is it, you should now have your first running node. However, the LEAP web a
leap node init db1
leap deploy db1
+NOTE: You probably want a machine with at least 8gb of RAM when running more than a few local virtual machines.
+
What is going on here?
--------------------------------------------