Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.

Commit b96a7d3

Browse files
committed
Docs For Ring Management
Added high level documentation and guidance for the though process surrounding rings and the implementation for them in Bedrock/SPK
1 parent 2bb964c commit b96a7d3

File tree

3 files changed

+190
-18
lines changed

3 files changed

+190
-18
lines changed

guides/auth-private-helm-repos.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Helm chart repository, we can piggy back off the ability for
99

1010
## Utilizing The Default PAT (ACCESS_TOKEN_SECRET)
1111

12-
By default, all services created via `spk service create` with the the
12+
By default, all services created via `spk service create` with the
1313
`--helm-config-*` family of options will be setup to consume the environment
1414
variable `ACCESS_TOKEN_SECRET` -- The PAT used to clone the application
1515
repository in the HLD-to-Materialized pipeline. So if the PAT used to setup your
@@ -45,7 +45,7 @@ spk service create my-service \
4545

4646
**Note**: it is important that the git URI you pass is an `https` URI and does
4747
NOT contain a username in it. By default, the clone URIs that the Azure DevOps
48-
creates presents in the UI contain your username in them (eg.
48+
creates presents in the UI contain your username in them (e.g.
4949
`https://<my-username>@dev.azure.com/my-org/my-project/_git/my-repo`). Fabrikate
5050
will not inject the PAT if the username is there as the value contained in place
5151
of the username can be a PAT itself.
@@ -76,7 +76,7 @@ variableGroups:
7676
7777
### Updating/Changing The Environment Variable
7878
79-
If you want to change the the environment variable used after creating your
80-
service, simply change the value of `accessTokenVariable` in your `bedrock.yaml`
81-
to the target environment variable (and ensure that the environment variable
82-
exists in your HLD-to-Materialized pipeline).
79+
If you want to change the environment variable used after creating your service,
80+
simply change the value of `accessTokenVariable` in your `bedrock.yaml` to the
81+
target environment variable (and ensure that the environment variable exists in
82+
your HLD-to-Materialized pipeline).

guides/rings-101.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# Rings
2+
3+
## What are Deployment Rings?
4+
5+
The concept of _Deployment Rings_ is an encapsulation of a production-first
6+
DevOps strategy to group your users into cohorts based on the features of your
7+
application your wish to expose to them -- think A/B or canary testing but in a
8+
more formalized matter in which you rollout changes from a smaller ring into a
9+
larger encompassing ring.
10+
11+
Rings formalize around a the idea of having a single of production users and
12+
smaller rings targeting cohorts of the larger ring and potentially even smaller
13+
rings targeting cohorts of those cohorts. This enables the ability to measure
14+
the impact or _Blast Radius_ of the deployed version of the application.
15+
16+
## When Should I Use a Ring?
17+
18+
Rings are useful when you want:
19+
20+
- To be able to test in production.
21+
- Have flexibility in the number of environments/rings available to your system
22+
at any given time.
23+
- Have a standardized means to promote environments/rings to larger cohorts.
24+
25+
## Bedrock -- Applying Rings To Microservices
26+
27+
Generally speaking, rings are more traditionally applied to monolithic
28+
applications -- Delivering specific versions of a single application to specific
29+
cohorts as needed. When in the context of Kubernetes and microservices, this
30+
becomes a much larger problem to tackle as you need to be able to extend the
31+
concept and deployment of rings to not only a single application, but _sets_ of
32+
applications within your cluster.
33+
34+
### Conceptual mapping to Git branches
35+
36+
Bedrock maps rings to branches in your application git repository. As branches
37+
represent a divergence from your main production code (i.e; `master`), they map
38+
to the idea or rings cleanly.
39+
40+
### How its implemented in Bedrock
41+
42+
Due to the limitations of the `Service` type in Kubernetes, Bedrock adopts the
43+
usage of edge routers (Traefik2) with header-based routing capabilities to
44+
identify your Ring via a provided header at ingress time. Instead of only
45+
routing to vanilla Kubernetes `Service`s, for every Bedrock `Ring` and `Service`
46+
defined in your cluster, a Kubernetes `Service` is created to expose it (the
47+
Kubernetes service will be called `<service-name>-<ring-name>`). This _Ringed
48+
Service_ is then exposed via a Traefik2 IngressRoute which routes to it when a
49+
request is made to the router for `/<major-version>/<service-name>/` with a
50+
Header of `Ring: <ring-name>`
51+
52+
To recap, lets imagine you have a Traefik2 ingress service in our cluster with
53+
the name `traefik` and we had an _Ringed Service_ to expose called
54+
`foobar-prod`. Instead of making requests to
55+
`foobar-prod.my-namespace.svc.cluster.local` in your cluster, you would instead
56+
make requests to `traefik.my-namespace.svc.cluster.local/<major-version>/foobar`
57+
with an HTTP header containing `Ring: prod`. The request would be routed via
58+
Traefik2 to the correct _Ringed Service_ based on the service requested and the
59+
`Ring` header -- routing the request to
60+
`foobar-prod.my-namespace.svc.cluster.local` for you.
61+
62+
## Rings & SPK
63+
64+
### Perquisites
65+
66+
[SPK](https://github.com/CatalystCode/spk) is command line tool meant to ease
67+
the adoption of [Bedrock](https://github.com/microsoft/bedrock/) methodologies
68+
and patterns. With SPK, rings are first class citizens and are managed/tracked
69+
alongside your services, enabling quick scaffolding and deployment of your
70+
services to your rings.
71+
72+
### Creating/Adding a Ring
73+
74+
Creating/adding a Ring is based around a single command:
75+
`spk ring create <ring-name>`.
76+
77+
This command adds a new ring to your spk project and tracks it in projects
78+
`bedrock.yaml` file. Subsequently, the command walks through every service in
79+
your project and updates their pipeline YAML to monitor the git branch the ring
80+
corresponds to. Making every merge into the ring branch trigger a new
81+
build/deployment of your ring.
82+
83+
### Deleting/Removing a Ring
84+
85+
Deleting/removing a ring does the inverse of [creating](#creatingadding-a-ring):
86+
`spk ring delete <ring-name>`.
87+
88+
This command removes the ring from your `bedrock.yaml` file and walks through
89+
all the services in your project and removing the ring branch from the service
90+
pipeline YAML.
91+
92+
### What Services Have What Rings?
93+
94+
For each ring defined in your `bedrock.yaml` file, every services
95+
build-update-hld pipeline will be configured to trigger off the said
96+
rings/branches and build a _ringed_ version of it.
97+
98+
Take for example the following `bedrock.yaml`:
99+
100+
```yaml
101+
rings:
102+
master:
103+
isDefault: true
104+
develop:
105+
isDefault: false
106+
services:
107+
./foo:
108+
displayName: ""
109+
helm:
110+
chart:
111+
accessTokenVariable: MY_ENV_VAR
112+
branch: master
113+
git: https://dev.azure.com/my-org/my-project/_git/my-repo
114+
path: foo-helm-chart
115+
k8sBackend: foo
116+
k8sBackendPort: 80
117+
middlewares: []
118+
pathPrefix: ""
119+
pathPrefixMajorVersion: ""
120+
./bar:
121+
displayName: ""
122+
helm:
123+
chart:
124+
accessTokenVariable: MY_ENV_VAR
125+
branch: master
126+
git: https://dev.azure.com/my-org/my-project/_git/my-repo
127+
path: bar-helm-chart
128+
k8sBackend: bar
129+
k8sBackendPort: 80
130+
middlewares: []
131+
pathPrefix: ""
132+
pathPrefixMajorVersion: ""
133+
variableGroups:
134+
- core
135+
```
136+
137+
In this example we have defined 2 rings (`master` and `develop`) and 2 services
138+
(`foo` and `bar`) within our `bedrock.yaml`.
139+
140+
The corresponding `build-update-hld.yaml` files for services `foo` and `bar`
141+
will contain:
142+
143+
```yaml
144+
trigger:
145+
branches:
146+
include:
147+
- master
148+
- develop
149+
```
150+
151+
Making the Azure DevOp pipeline trigger off those corresponding branches/rings.
152+
153+
### Validating the Deployment of My Ringed Service
154+
155+
After your services have been deployed, the next step is to validate that they
156+
are being correctly routed. Remember that route to rings based off a the header
157+
`Ring`.
158+
159+
Imagine our Traefik2 Ingress has been given the IP address `88.88.88.88` we can
160+
ping our services now via a curl command containing the header
161+
`Ring: <target-ring>` where `<target-ring>` corresponds to the ring we wish to
162+
ping:
163+
164+
```sh
165+
curl -H "Ring: master" 88.88.88.88/foo/
166+
curl -H "Ring: master" 88.88.88.88/bar/
167+
curl -H "Ring: develop" 88.88.88.88/foo/
168+
curl -H "Ring: develop" 88.88.88.88/bar/
169+
```

src/commands/service/create.md

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,27 @@ Add a new service into this initialized spk project repository.
44

55
## Example
66

7-
```bash
8-
spk service create . \
9-
--display-name $app_name \
10-
--helm-config-path $path_to_chart_in_repo \
11-
--helm-config-git $helm_repo_url \ # Needs to start with https and not contain user name
12-
--helm-config-branch master \
13-
--helm-chart-access-token-variable $ENV_VAR_NAME
14-
```
15-
7+
```bash
8+
spk service create . \
9+
--display-name $app_name \
10+
--helm-config-path $path_to_chart_in_repo \
11+
--helm-config-git $helm_repo_url \ # Needs to start with https and not contain user name
12+
--helm-config-branch master \
13+
--helm-chart-access-token-variable $ENV_VAR_NAME
14+
```
15+
1616
## Note
1717

18-
- `--helm-chart-*` and `--helm-config-*` settings are exclusive. **You may only
19-
use one.**
18+
- `--helm-chart-*` and `--helm-config-*` settings are mutually-exclusive. **You
19+
may only use one.**
2020
- If the git repository referenced in `--helm-config-git` is a private
2121
repository, you can specify an environment variable in your
2222
HLD-to-Materialized pipeline containing your a PAT to authenticate with via
2323
the `--helm-chart-access-token-variable` option.
2424
- `--middlewares`, `--k8s-backend-port`, `--path-prefix`,
2525
`--path-prefix-major-version`, and `--k8s-backend` are all used to configure
26-
the generated Traefik2 IngressRoutes. ie.
26+
the generated Traefik2 IngressRoutes. i.e.
27+
2728
```sh
2829
spk service create my-example-documents-service \
2930
--middlewares middleware \
@@ -32,7 +33,9 @@ Add a new service into this initialized spk project repository.
3233
--path-prefix documents \
3334
--path-prefix-major-version v2
3435
```
36+
3537
will result in an IngressRoute that looks like:
38+
3639
```yaml
3740
apiVersion: traefik.containo.us/v1alpha1
3841
kind: IngressRoute

0 commit comments

Comments
 (0)