platform docs: updated commands, removed config items that are no longer supported...
[leap_doc.git] / docs / platform / config.md
1 @title = "Configuration Files"
2
3 Files
4 -------------------------------------------
5
6 Here are a list of some of the common files that make up a provider. Except for Leapfile and provider.json, the files are optional. Unless otherwise specified, all file names are relative to the 'provider directory' root (where the Leapfile is).
7
8 `Leapfile` -- If present, this file tells `leap` that the directory is a provider directory. This file is usually empty, but can contain global options.
9
10 `~/.leaprc` -- Evaluated the same as Leapfile, but not committed to source control.
11
12 `provider.json` -- Global options related to this provider.
13
14 `provider.ENVIRONMENT.json` -- Global options for the provider that are applied to only a single environment.
15
16 `common.json` -- All nodes inherit from this file.
17
18 `secrets.json` -- An automatically generated file that contains any randomly generated strings needed in order to deploy. These strings are often secret and should be protected, although any need for a random string or number that is remembered will produce another entry in this file. This file is automatically generated and refreshed each time you run `leap compile` or `leap deploy`. If an entry is no longer needed, it will get removed. If you want to change a secret, you can remove this file and have it regenerated, or remove the particular line item and just those items will be created anew.
19
20 `facts.json` -- If some of your servers are running on AWS or OpenStack, you will need to discover certain properties about how networking is configured on these machines in order for a full deploy to work. In these cases, make sure to run `leap facts update` to periodically regenerate the facts.json file.
21
22 `nodes/NAME.json` -- The configuration file for node called NAME.
23
24 `services/SERVICE.json` -- The properties in this configuration file are applied to any node that includes SERVICE in its `services` property.
25
26 `services/SERVICE.ENVIRONMENT.json` -- The properties in this configuration file are applied to any node that includes SERVICE in its services and has environment equal to ENVIRONMENT.
27
28 `services/TAG.json` -- The properties in this configuration file are applied to any node that has includes TAG in its `tags` property.
29
30 `services/TAG.ENVIRONMENT.json` -- The properties in this configuration file are applied to any node that has includes TAG in its `tags` property and has `environment` property equal to ENVIRONMENT.
31
32 `files/*` -- Various static files used by the platform (e.g. keys, certificates, webapp customization, etc).
33
34 `users/USER/` -- A directory that stores the public keys of the sysadmin with name USER. This person will have root access to all the servers.
35
36
37 Leapfile
38 -------------------------------------------
39
40 A `Leapfile` defines options for the `leap` command and lives at the root of your provider directory. `Leapfile` is evaluated as ruby, so you can include whatever weird logic you want in this file. In particular, there are several variables you can set that modify the behavior of leap. For example:
41
42     @platform_directory_path = '../leap_platform'
43     @log = '/var/log/leap.log'
44
45 Additionally, you can create a `~/.leaprc` file that is loaded after `Leapfile` and is evaluated the same way.
46
47 Platform options:
48
49 * `@platform_directory_path` (required). This must be set to the path where `leap_platform` lives. The path may be relative.
50
51 Vagrant options:
52
53 * `@vagrant_network`. Allows you to override the default network used for local nodes. It should include a netmask like `@vagrant_network = '10.0.0.0/24'`.
54 * `@custom_vagrant_vm_line`. Insert arbitrary text into the auto-generated Vagrantfile. For example, `@custom_vagrant_vm_line = "config.vm.boot_mode = :gui"`.
55
56 Logging options:
57
58 * `@log`. If set, all command invocation and results are logged to the specified file. This is the same as the switch `--log FILE`, except that the command line switch will override the value in the Leapfile.
59
60
61 JSON format
62 -------------------------------------------
63
64 All configuration files, other than `Leapfile`, are in the JSON format. For example:
65
66     {
67       "key1": "value1",
68       "key2": "value2"
69     }
70
71 Keys should match `/[a-z0-9_]/`
72
73 Unlike traditional JSON, comments are allowed. If the first non-whitespace characters are `//` then the line is treated as a comment.
74
75     // this is a comment
76     {
77       // this is a comment
78       "key": "value"  // this is an error
79     }
80
81 Options in the configuration files might be nested hashes, arrays, numbers, strings, or boolean. Numbers and boolean values should **not** be quoted. For example:
82
83     {
84       "openvpn": {
85         "ip_address": "1.1.1.1",
86         "protocols": ["tcp", "udp"],
87         "ports": [80, 53],
88         "options": {
89           "public_ip": false,
90           "adblock": true
91         }
92       }
93     }
94
95 If the value string is prefixed with an '=' character, the result is evaluated as ruby. For example:
96
97     {
98       "domain": {
99         "public": "domain.org"
100       }
101       "api_domain": "= 'api.' + domain.public"
102     }
103
104 In this case, the property "api_domain" will be set to "api.domain.org". So long as you do not create unresolvable circular dependencies, you can reference other properties in evaluated ruby that are themselves evaluated ruby.
105
106 See "Macros" below for information on the special macros available to the evaluated ruby.
107
108 TIP: In rare cases, you might want to force the evaluation of a value to happen in a later pass after most of the other properties have been evaluated. To do this, prefix the value string with "=>" instead of "=".
109
110 Node inheritance
111 ----------------------------------------
112
113 Every node inherits from common.json and also any of the services or tags attached to the node. Additionally, the `leap_platform` contains a directory `provider_base` that defines the default values for tags, services and common.json.
114
115 Suppose you have a node configuration for `bitmask/nodes/willamette.json` like so:
116
117     {
118        "services": "webapp",
119        "tags": ["production", "northwest-us"],
120        "ip_address": "1.1.1.1"
121     }
122
123 This node will have hostname "willamette" and it will inherit from the following files (in this order):
124
125 1. common.json
126     - load defaults: `provider_base/common.json`
127     - load provider: `bitmask/common.json`
128 2. service "webapp"
129     - load defaults: `provider_base/services/webapp.json`
130     - load provider: `bitmask/services/webapp.json`
131 3. tag "production"
132     - load defaults: `provider_base/tags/production.json`
133     - load provider: `bitmask/tags/production.json`
134 4. tag "northwest-us"
135     - load: `bitmask/tags/northwest-us.json`
136 5. finally, load node "willamette"
137     - load: `bitmask/nodes/willamette.json`
138
139 The `provider_base` directory is under the `leap_platform` specified in the file `Leapfile`.
140
141 To see all the variables a node has inherited, you could run `leap inspect willamette`.
142
143 Common configuration options
144 ----------------------------------------
145
146 You can use the command `leap inspect` to see what options are available for a provider, node, service, or tag configuration. For example:
147
148 * `leap inspect common` -- show the options inherited by all nodes.
149 * `leap inspect --base common` -- show the common.json from `provider_base` without the local `common.json` inheritance applied.
150 * `leap inspect webapp` -- show all the options available for the service `webapp`.
151
152 Here are some of the more important options you should be aware of:
153
154 * `ip_address` -- Required for all nodes, no default.
155 * `ssh.port` -- The SSH port you want the node's OpenSSH server to bind to. This is also the default when trying to connect to a node, but if the node currently has OpenSSH running on a different port then run deploy with `--port` to override the `ssh.port` configuration value.
156 * `mosh.enabled` -- If set to `true`, then mosh will be installed on the server. The default is `false`.
157
158 Macros
159 ----------------------------------------
160
161 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`).
162
163 The following methods are available to the evaluated ruby:
164
165 `variable.variable`
166
167   > 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. Properties of services, tags, and the global provider can all be referenced the same way. For example, `global.services['openvpn'].x509.dh`.
168
169 `nodes`
170
171   > A hash of all nodes. This list can be filtered.
172
173 `nodes_like_me`
174
175   > A hash of nodes that have the same deployment tags as the current node (e.g. 'production' or 'local').
176
177 `global.services`
178
179   > A hash of all services, e.g. `global.services['openvpn']` would return the "openvpn" service.
180
181 `global.tags`
182
183   > A hash of all tags, e.g. `global.tags['production']` would return the "production" tag.
184
185  `global.provider`
186
187   > Can be used to access variables defined in `provider.json`, e.g. `global.provider.contacts.default`.
188
189 `file(filename)`
190
191   > 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, or it can be a path relative to the "files" directory in your provider instance. E.g, `file :ca_cert` or `files 'ca/ca.crt'`.
192
193 `file_path(filename)`
194
195   >  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'`.
196
197 `secret(:symbol)`
198
199   > Returns the value of a secret in secrets.json (or creates it if necessary). E.g. `secret :couch_admin_password`
200
201 `hosts_file`
202
203   > Returns a data structure that puppet will use to generate /etc/hosts. Care is taken to use the local IP of other hosts when needed.
204
205 `known_hosts_file`
206
207   > Returns the lines needed in a SSH `known_hosts` file.
208
209 `stunnel_client(node_list, port, options={})`
210
211   > Returns a stunnel configuration data structure for the client side. Argument `node_list` is an `ObjectList` of nodes running stunnel servers. Argument `port` is the real port of the ultimate service running on the servers that the client wants to connect to.
212
213 `stunnel_server(port)`
214
215   > Generates a stunnel server entry. The `port` is the real port targeted service.
216
217 Hash tables
218 -----------------------------------------
219
220 The macros `nodes`, `nodes_like_me`, `global.services`, and `global.tags` all return a hash table of configuration objects (either nodes, services, or tags). There are several ways to filter and process these hash tables:
221
222 Access an element by name:
223
224     nodes['vpn1']                # returns node named 'vpn1'
225     global.services['openvpn']   # returns service named 'openvpn'
226
227 Create a new hash table by applying filters:
228
229     nodes[:public_dns => true] # all nodes where public_dns == true
230     nodes[:services => 'openvpn', 'location.country_code' => 'US'] # openvpn service OR in the US.
231     nodes[[:services, 'openvpn'], [:services, 'tor']]  # services equal to openvpn OR tor
232     nodes[:services => 'openvpn'][:tags => 'production']  # openvpn AND production
233     nodes[:name => "!bob"] # all nodes that are NOT named "bob"
234
235 Create an array of values by selecting a single field:
236
237     nodes.field('location.name')
238     ==> ['seattle', 'istanbul']
239
240 Create an array of hashes by selecting multiple fields:
241
242     nodes.fields('domain.full', 'ip_address')
243     ==> [
244       {'domain_full' => 'red.bitmask.net', 'ip_address' => '1.1.1.1'},
245       {'domain_full' => 'blue.bitmask.net', 'ip_address' => '1.1.1.2'},
246     ]
247
248 Create a new hash table of hashes, with only certain fields:
249
250     nodes.pick_fields('domain.full', 'ip_address')
251     ==> {
252       "red" => {'domain_full' => 'red.bitmask.net', 'ip_address' => '1.1.1.1'},
253       "blue => {'domain_full' => 'blue.bitmask.net', 'ip_address' => '1.1.1.2'},
254     }
255
256 With `pick_fields`, if there is only one field, it will generate a simple hash table:
257
258     nodes.pick_fields('ip_address')
259     ==> {
260       "red" => '1.1.1.1',
261       "blue => '1.1.1.2',
262     }