Skip to content

Commit 5d5ee8e

Browse files
committed
feat(doc): Updated dev deployments documentation
Describing how to run own rabbitmq/postgres for testing purposes
1 parent 37fd2ab commit 5d5ee8e

File tree

5 files changed

+190
-4
lines changed

5 files changed

+190
-4
lines changed

dev-docs/dev-deployment.md

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ You will need to have the following
1313
* A running kubernetes cluster with at least 2000 mCPU and 4GB RAM available.
1414
* Helm 3 installed
1515
* The latest version of kubectl installed, and credentials configured to talk to the cluster
16-
* A RabbitMQ cluster running the latest available version.
16+
* A RabbitMQ cluster running the latest available version. (see also [install RabbitMQ](#own-rabbitmq-in-cluster))
1717
The deployment process requires administrative access (the RabbitMQ management API) and creates multiple users.
1818
The free levels of CloudAMQP's service do not support this.
19-
* A Postgres server running Postgres 11.x (see below for Google Cloud SQL, or use another provider).
19+
* A Postgres server running Postgres 11.x (see below for Google Cloud SQL, or use another provider). (see also [install Postgres](#own-postgres-in-cluster))
2020
The Postgres server must be initialized with the `en_US.utf8` locale; see [the deployment docs](../ui/docs/manual/deploying/database.mdx).
2121
* An AWS account and an IAM user in that account
2222
Set up your `aws` command-line to use the IAM user (`aws configure`).
@@ -222,3 +222,134 @@ If you set up a taskcluster-github app, you probably want to test a variety of i
222222
2. Put together a body of your pulse message. Make sure you use the schemas. It should be in JSON format.
223223
3. Look up the routing key and exchange you need (most likely you are testing a handler - so look up the bindings for that handler in the code).
224224
3. Navigate to the management UI on the RabbitMQ server (the url from `pulseHostname`), login using the above credentials and go to the exchange of interest. You will see *Publish Message* section in the UI. Fill out the *Routing Key* and *Payload* fields (the result of the step 2 goes into the latter). Press *Publish Message* and you're done.
225+
226+
## Own RabbitMQ in cluster
227+
228+
It is possible to run RabbitMQ directly in the same cluster for dev purposes.
229+
230+
Warning: by using this approach, you are responsible for maintenance and backups.
231+
232+
You can use one of the existing helm charts, steps listed below:
233+
234+
1. Add helm repository:
235+
236+
`helm repo add bitnami https://charts.bitnami.com/bitnami`
237+
2. To enable TLS you need to create certificates according to [RabbitMQ Documentation](https://www.rabbitmq.com/ssl.html#automated-certificate-generation)
238+
<details>
239+
<summary>
240+
Generate and upload rabbitmq-certificates
241+
</summary>
242+
243+
```sh
244+
git clone https://github.com/michaelklishin/tls-gen tls-gen
245+
246+
cd tls-gen/basic
247+
make && make verify && make info
248+
249+
cd result
250+
cp ca_certificate.pem ca.crt && cp server_certificate.pem tls.crt && cp server_key.pem tls.key
251+
252+
kubectl -n $NAMESPACE create secret generic rabbitmq-certificates \
253+
--from-file=./ca.crt \
254+
--from-file=./tls.crt \
255+
--from-file=./tls.key
256+
```
257+
</details>
258+
3. Create config with chart values:
259+
<details>
260+
<summary><code>rabbitmq/values.yaml</code></summary>
261+
262+
```yaml
263+
auth:
264+
username: admin
265+
password: adminpassword # set some strong management password
266+
erlangCookie: secretcookie # set some cookie secret
267+
268+
tls:
269+
enabled: true
270+
existingSecret: rabbitmq-certificates # same name of the secret from the previous step
271+
```
272+
273+
More details at <https://github.com/bitnami/charts/tree/master/bitnami/rabbitmq>
274+
</details>
275+
4. Install chart:
276+
277+
`helm install tc-rabbitmq --namespace $NAMESPACE -f ./rabbitmq/values.yaml bitnami/rabbitmq`
278+
279+
This will create several resources. By default it will create Persisted Volume Claim for `8Gb` of disk that will be persisted by kubernetes cluster.
280+
5. Create proxy (port forwarding) to be able to access management panel:
281+
282+
`kubectl port-forward --namespace $NAMESPACE svc/tc-rabbitmq 15672:15672`
283+
284+
You are now able to access it via <http://localhost:15672> using username and password configured in `rabbitmq/values.yaml`.
285+
286+
6. Ensure that vhost and users are created.
287+
288+
In your `dev-config.yml` (that is created with `yarn dev:init`) you should have `meta.rabbitAdminManagementOrigin = http://127.0.0.1:15672` to be able to properly access it
289+
290+
Run `yarn dev:ensure:rabbit` to create missing users and vhost. It will prompt for management password (see `rabbitmq/values.yaml`), and assumes that `dev-config.yml` was already generated.
291+
292+
7. Update `dev-config.yml` to have:
293+
294+
`pulseHostname = tc-rabbitmq-headless` if running in the same namespace, or `pulseHostname: tc-rabbitmq-headless.$NAMESPACE.svc.cluster.local` otherwise
295+
296+
In case of connection issues, set non tls mode with `pulseAmqps = false`
297+
298+
8. Run `yarn dev:apply` if needed, to recreate configs and secrets with new pulse values.
299+
300+
## Own Postgres in cluster
301+
302+
It is possible to run Postgres directly in the same cluster for dev purposes.
303+
304+
Warning: by using this approach, you are responsible for maintenance and backups.
305+
306+
1. Add helm repository:
307+
308+
`helm repo add bitnami https://charts.bitnami.com/bitnami`
309+
310+
2. Create config with chart values:
311+
<details>
312+
<summary><code>postgres/values.yaml</code></summary>
313+
314+
```yaml
315+
auth:
316+
postgresPassword: rootpassword # set something strong
317+
username: taskcluster
318+
password: taskcluster # set something strong
319+
database: taskcluster
320+
321+
tls:
322+
enabled: true
323+
autoGenerated: true
324+
325+
volumePermissions:
326+
enabled: true
327+
328+
image:
329+
tag: 11 # TaskCluster currently supports version 11
330+
```
331+
332+
More details at <https://github.com/bitnami/charts/tree/master/bitnami/postgresql>
333+
</details>
334+
3. Install chart:
335+
336+
`helm install tc-postgresql --namespace $NAMESPACE -f ./postgresql/values.yaml bitnami/postgresql`
337+
338+
This will create several resources. By default it will create Persisted Volume Claim for `8Gb` of disk that will be persisted by kubernetes cluster.
339+
4. Create proxy (port forwarding) to be able to access Postgres locally:
340+
341+
`kubectl port-forward --namespace $NAMESPACE svc/tc-postgresql 5432:5432`
342+
343+
You are now able to connect to it via <http://localhost:5432> using username and password configured in `postgres/values.yaml`.
344+
345+
5. Ensure that users are created.
346+
347+
In your `dev-config.yml` (that is created with `yarn dev:init`) you should have `meta.dbPrivateIp = tc-postgresql.$NAMESPACE.svc.cluster.local` to be able to properly access it
348+
349+
`yarn dev:ensure:db` will create all necessary users for all services
350+
351+
6. Migrate database
352+
353+
Once users are set, you can run `yarn dev:db:upgrade` (with running port-forward) to create db schema and stored functions
354+
355+
Now it should be possible to use postgres for dev purposes inside the cluster. Make sure to make backups.

infrastructure/tooling/src/dev/index.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const _ = require('lodash');
55
const { readRepoYAML, writeRepoYAML } = require('../utils');
66
const inquirer = require('inquirer');
77
const commonPrompts = require('./common');
8-
const { rabbitPrompts, rabbitResources } = require('./rabbit');
8+
const { rabbitPrompts, rabbitResources, rabbitAdminPasswordPrompt, rabbitEnsureResources } = require('./rabbit');
99
const { azureResources } = require('./azure');
1010
const { postgresPrompts, postgresResources, postgresEnsureDb } = require('./postgres');
1111
const { k8sResources } = require('./k8s');
@@ -109,8 +109,18 @@ const ensureDb = async (options) => {
109109
await postgresEnsureDb({ userConfig });
110110
};
111111

112+
const ensureRabbit = async (options) => {
113+
const userConfig = await readUserConfig();
114+
const prompts = [];
115+
116+
await rabbitAdminPasswordPrompt({ userConfig, prompts });
117+
const answer = await inquirer.prompt(prompts);
118+
119+
await rabbitEnsureResources({ userConfig, answer });
120+
};
121+
112122
const delete_ = async (options) => {
113123
await helm('delete');
114124
};
115125

116-
module.exports = { init, apply, verify, ensureDb, delete_, dbUpgrade, dbDowngrade };
126+
module.exports = { init, apply, verify, ensureDb, ensureRabbit, delete_, dbUpgrade, dbDowngrade };

infrastructure/tooling/src/dev/rabbit.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,44 @@ const rabbitResources = async ({ userConfig, answer, configTmpl }) => {
111111
return userConfig;
112112
};
113113

114+
const rabbitAdminPasswordPrompt = ({ userConfig, prompts }) => {
115+
prompts.push({
116+
type: 'password',
117+
name: 'rabbitAdminPassword',
118+
message: 'RabbitMq admin password.',
119+
});
120+
};
121+
122+
const rabbitEnsureResources = async ({ userConfig, answer }) => {
123+
const apiUrl = `${userConfig.meta?.rabbitAdminManagementOrigin}/api`;
124+
const agent = request.agent().auth(userConfig.meta?.rabbitAdminUser, answer.rabbitAdminPassword).type('json');
125+
const vhost = userConfig.pulseVhost;
126+
127+
console.log(`(Re-)creating RabbitMQ vhost ${vhost}`);
128+
await agent.put(`${apiUrl}/vhosts/${encodeURIComponent(vhost)}`);
129+
130+
for (const [name, cfg] of Object.entries(userConfig)) {
131+
if (!cfg.pulse_username || !cfg.pulse_password) {
132+
continue;
133+
}
134+
135+
console.log(`Creating RabbitMQ user ${cfg.pulse_username}`);
136+
await agent.put(`${apiUrl}/users/${encodeURIComponent(cfg.pulse_username)}`).send({
137+
password: cfg.pulse_password,
138+
tags: '',
139+
});
140+
const regexName = `taskcluster\\-${name.replace(/_/g, '\\-')}`;
141+
await agent.put(`${apiUrl}/permissions/${encodeURIComponent(vhost)}/${encodeURIComponent(cfg.pulse_username)}`).send({
142+
configure: `^(queue/${regexName}/.*|exchange/${regexName}/.*)`,
143+
write: `^(queue/${regexName}/.*|exchange/${regexName}/.*)`,
144+
read: `^(queue/${regexName}/.*|exchange/.*)`,
145+
});
146+
}
147+
};
148+
114149
module.exports = {
115150
rabbitPrompts,
116151
rabbitResources,
152+
rabbitAdminPasswordPrompt,
153+
rabbitEnsureResources,
117154
};

infrastructure/tooling/src/main.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,13 @@ program.command('dev:ensure:db')
180180
run(ensureDb, options);
181181
}));
182182

183+
program.command('dev:ensure:rabbit')
184+
.description('Verify that rabbitmq users and vhost are properly set')
185+
.action(actFn(({ options }) => {
186+
const { ensureRabbit } = require('./dev');
187+
run(ensureRabbit, options);
188+
}));
189+
183190
program.command('test:meta')
184191
.action(actFn(({ options }) => {
185192
const { main } = require('./meta');

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@
192192
"dev:delete": "node infrastructure/tooling/src/main.js dev:delete",
193193
"dev:verify": "node infrastructure/tooling/src/main.js dev:verify",
194194
"dev:ensure:db": "node infrastructure/tooling/src/main.js dev:ensure:db",
195+
"dev:ensure:rabbit": "node infrastructure/tooling/src/main.js dev:ensure:rabbit",
195196
"smoketest": "node infrastructure/tooling/src/main.js smoketest",
196197
"test:meta": "node infrastructure/tooling/src/main.js test:meta",
197198
"db:upgrade": "node db/src/main.js upgrade",

0 commit comments

Comments
 (0)