Skip to content

Commit d8c5405

Browse files
author
Constantin Muraru
committed
Update examples
Signed-off-by: Constantin Muraru <[email protected]>
1 parent 9b57eae commit d8c5405

File tree

13 files changed

+189
-16
lines changed

13 files changed

+189
-16
lines changed

README.md

Lines changed: 174 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
11
# himl
2-
A hierarchical config using yaml in Python
2+
A hierarchical config using yaml in Python.
33

44
Latest version is: 0.1.17
55

6+
## Description
7+
8+
A python module which allows you to merge hierarchical config files using YAML syntax. It offers deep merge, variable interpolation and secrets retrieval from secrets managers.
9+
10+
It is ideal if you want to structure your hierarchy in such a way that you avoid duplication. You can define a structure for your configuration using a hierarchy such environment/project/cluster/app. It is up to you what layers you want to use in this hierarchy. The tool will read all yaml files starting from the root (where default values would be) all the way to the leaf (where most specific values would be, which will take precedence).
11+
12+
Idea came from puppet's hiera.
13+
14+
## Table of Contents
15+
16+
1. [Installation](#installation)
17+
2. [Examples](#examples)
18+
3. [Features](#features)
19+
* [Interpolation](#feature-interpolation)
20+
* [Deep merge](#feature-deep-merge)
21+
* [Secrets retrieval](#feature-secrets-retrieval)
22+
* [Merge with Terraform remote state](#feature-terraform-remote-state)
23+
24+
<a name="installation"/>
625

726
## Installation
827

@@ -20,10 +39,80 @@ cd himl
2039
sudo python setup.py install
2140
```
2241

23-
## Example
42+
<a name="examples"/>
43+
44+
## Examples
45+
46+
### Using the python module
47+
48+
This will merge simple/default.yaml with simple/production/env.yaml
49+
```py
50+
from himl import ConfigProcessor
51+
52+
config_processor = ConfigProcessor()
53+
path = "examples/simple/production"
54+
filters = () # can choose to output only specific keys
55+
exclude_keys = () # can choose to remove specific keys
56+
output_format = "yaml" # yaml/json
57+
58+
59+
config_processor.process(path=path, filters=filters, exclude_keys=exclude_keys,
60+
output_format=output_format, print_data=True)
61+
62+
```
63+
64+
The above example will merge `simple/default.yaml` with `simple/production/env.yaml`:
65+
```
66+
$ tree examples/simple
67+
examples/simple
68+
├── default.yaml
69+
└── production
70+
└── env.yaml
71+
```
72+
73+
<a name="deep-merge-example"/>
74+
75+
The example also showcases deep merging of lists and maps.
76+
77+
`examples/simple/default.yaml`
78+
```yaml
79+
---
80+
env: default
81+
deep:
82+
key1: v1
83+
key2: v2
84+
deep_list:
85+
- item1
86+
- item2
87+
```
88+
89+
`examples/simple/production/env.yaml`
90+
```yaml
91+
---
92+
env: prod
93+
deep:
94+
key3: v3
95+
deep_list:
96+
- item3
97+
```
98+
99+
Result:
100+
```yaml
101+
env: prod
102+
deep:
103+
key1: v1
104+
key2: v2
105+
key3: v3
106+
deep_list:
107+
- item1
108+
- item2
109+
- item3
110+
```
24111

25112
### Using the cli
26113

114+
A cli tool called `himl` is automatically installed via `pip`. You can use it to parse a tree of yamls and it will either output the combined configuration at standard output or write it to a file.
115+
27116
```sh
28117
usage: himl [-h] [--output-file OUTPUT_FILE] [--format OUTPUT_FORMAT]
29118
[--filter FILTER] [--exclude EXCLUDE]
@@ -34,10 +123,10 @@ usage: himl [-h] [--output-file OUTPUT_FILE] [--format OUTPUT_FORMAT]
34123
```
35124

36125
```sh
37-
himl examples/config_example/env=dev/region=us-east-1/cluster=cluster2
126+
himl examples/complex/env=dev/region=us-east-1/cluster=cluster2
38127
```
39128

40-
The configuration output will be something like this:
129+
Based on the configuration tree from the [examples/complex](examples/complex) folder, the output of the above command will be the following:
41130
```
42131
cluster:
43132
description: 'This is cluster: cluster2. It is using c3.2xlarge instance type.'
@@ -50,8 +139,8 @@ env: dev
50139

51140
Where the examples folder looks something like this:
52141
```
53-
$ tree examples/config_example
54-
examples/config_example
142+
$ tree examples/complex
143+
examples/complex
55144
├── default.yaml
56145
├── env=dev
57146
│   ├── env.yaml
@@ -73,18 +162,87 @@ examples/config_example
73162
└── region.yaml
74163
```
75164

76-
### Using the python module
165+
<a name="features"/>
77166

78-
```py
79-
from himl import ConfigProcessor
167+
## Features
80168

81-
config_processor = ConfigProcessor()
82-
path = "examples/config_example/env=dev/region=us-east-1/cluster=cluster2"
83-
filters = () # can choose to output only specific keys
84-
exclude_keys = () # can choose to remove specific keys
85-
output_format = "yaml" # yaml/json
169+
<a name="feature-interpolation"/>
86170

171+
### Interpolation
87172

88-
config_processor.process(path=path, filters=filters, exclude_keys=exclude_keys,
89-
output_format=output_format, print_data=True)
173+
In order to avoid repetition, we wanted to make it possible to define a value once and reuse it in other parts of the yaml config.
174+
Unlike yaml anchors, these interpolations work across multiple files.
175+
176+
#### Interpolating simple values
177+
178+
`data/default.yaml`:
179+
```yaml
180+
allowed_roles:
181+
- "arn:aws:iam::{{account.id}}:role/myrole"
182+
```
183+
184+
`data/dev/env.yaml`:
185+
```
186+
account:
187+
id: "123456"
188+
```
189+
190+
#### Interpolating whole `dict`
191+
192+
```yaml
193+
projects:
194+
webapp1:
195+
tagging:
196+
Owner: "Web Service Team"
197+
Environment: "dev"
198+
CostCenter: "123"
199+
data-store:
200+
Owner: "Backend Team"
201+
Environment: "dev"
202+
CostCenter: "455"
203+
204+
# this will copy the whole projects.webapp1.tagging dict to this key
205+
tagging: "{{projects.webapp1.tagging}}"
206+
207+
# or even a double interpolation
208+
tagging: "{{projects.{{project.name}}.tagging}}"
209+
```
210+
211+
<a name="feature-deep-merge"/>
212+
213+
### Deep merge
214+
215+
It's possible to have the same key (eg. a dict/list) in multiple files and combine them using a deep merge.
216+
See an example [here](https://github.com/adobe/himl#deep-merge-example).
217+
218+
<a name="feature-secrets-retrieval"/>
219+
220+
### Secrets retrieval
221+
222+
#### [AWS SSM](https://docs.aws.amazon.com/systems-manager/latest/userguide/integration-ps-secretsmanager.html)
223+
224+
```yaml
225+
passphrase: "{{ssm.path(/key/coming/from/aws/secrets/store/manager).aws_profile(myprofile)}}"
90226
```
227+
228+
#### [Vault](https://www.vaultproject.io/)
229+
230+
Not yet implemented.
231+
232+
233+
<a name="feature-terraform-remote-state"/>
234+
235+
### Merge with [Terraform remote state](https://www.terraform.io/docs/state/remote.html)
236+
237+
```yaml
238+
### Terraform remote states ###
239+
remote_states:
240+
- name: cluster_composition
241+
type: terraform
242+
aws_profile: "my_aws_profile"
243+
s3_bucket: "my_terraform_bucket"
244+
s3_key: "mycluster.tfstate"
245+
246+
247+
endpoint: "{{outputs.cluster_composition.output.value.redis_endpoint}}"
248+
```
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)