devlift-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- devlift_cli/MANUAL.md +1066 -0
- devlift_cli/__init__.py +3 -0
- devlift_cli/__main__.py +4 -0
- devlift_cli/api/__init__.py +0 -0
- devlift_cli/api/approvals.py +53 -0
- devlift_cli/api/catalog.py +96 -0
- devlift_cli/api/client.py +125 -0
- devlift_cli/api/context.py +21 -0
- devlift_cli/api/deployments.py +37 -0
- devlift_cli/api/infra.py +94 -0
- devlift_cli/api/infra_list.py +61 -0
- devlift_cli/api/kong.py +29 -0
- devlift_cli/api/services.py +106 -0
- devlift_cli/api/vpc.py +24 -0
- devlift_cli/app.py +163 -0
- devlift_cli/auth/__init__.py +0 -0
- devlift_cli/auth/oauth.py +270 -0
- devlift_cli/auth/session.py +64 -0
- devlift_cli/auth/storage.py +135 -0
- devlift_cli/commands/__init__.py +0 -0
- devlift_cli/commands/approval.py +51 -0
- devlift_cli/commands/auth.py +180 -0
- devlift_cli/commands/catalog.py +187 -0
- devlift_cli/commands/clusters.py +108 -0
- devlift_cli/commands/deployment.py +77 -0
- devlift_cli/commands/dynamodb.py +121 -0
- devlift_cli/commands/eks.py +326 -0
- devlift_cli/commands/kong.py +145 -0
- devlift_cli/commands/languages.py +40 -0
- devlift_cli/commands/manual.py +82 -0
- devlift_cli/commands/repositories.py +49 -0
- devlift_cli/commands/request.py +89 -0
- devlift_cli/commands/s3.py +198 -0
- devlift_cli/commands/sqs.py +229 -0
- devlift_cli/config.py +94 -0
- devlift_cli/context.py +97 -0
- devlift_cli/data/placement/vance.json +16 -0
- devlift_cli/errors.py +52 -0
- devlift_cli/ops/__init__.py +0 -0
- devlift_cli/ops/approvals.py +343 -0
- devlift_cli/ops/eks.py +877 -0
- devlift_cli/ops/kong.py +343 -0
- devlift_cli/ops/placement.py +128 -0
- devlift_cli/ops/resources.py +418 -0
- devlift_cli/ops/status.py +152 -0
- devlift_cli/ops/wait.py +82 -0
- devlift_cli/render/__init__.py +0 -0
- devlift_cli/render/output.py +75 -0
- devlift_cli/resolve/__init__.py +0 -0
- devlift_cli/resolve/allowlist.py +192 -0
- devlift_cli/resolve/names.py +179 -0
- devlift_cli-0.1.0.dist-info/METADATA +106 -0
- devlift_cli-0.1.0.dist-info/RECORD +56 -0
- devlift_cli-0.1.0.dist-info/WHEEL +5 -0
- devlift_cli-0.1.0.dist-info/entry_points.txt +3 -0
- devlift_cli-0.1.0.dist-info/top_level.txt +1 -0
devlift_cli/MANUAL.md
ADDED
|
@@ -0,0 +1,1066 @@
|
|
|
1
|
+
# DevLift CLI manual
|
|
2
|
+
|
|
3
|
+
`devlift` (alias `dl`) is the command-line tool for the DevLift platform. It
|
|
4
|
+
works like the AWS CLI: `devlift <group> <operation> [flags]`. Every command
|
|
5
|
+
is a fixed sequence of calls to the DevLift backend's REST API, the same
|
|
6
|
+
endpoints the web dashboard uses. Nothing here talks to an AI model.
|
|
7
|
+
|
|
8
|
+
Read this manual any time with `devlift man` (paged, like `man`: scroll,
|
|
9
|
+
`/` to search, `q` to leave), or print one section with
|
|
10
|
+
`devlift manual <topic>` (for example `devlift manual s3`).
|
|
11
|
+
|
|
12
|
+
## 1. Install
|
|
13
|
+
|
|
14
|
+
Requires Python 3.11 or newer. Nothing else: the installer puts DevLift in
|
|
15
|
+
its own environment and touches no system packages.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
curl -fsSL <install-url>/install.sh | sh
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or, from a wheel you were sent:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
sh install.sh ./devlift_cli-<version>-py3-none-any.whl
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
It installs into `~/.local/share/devlift` and links `devlift` and `dl` into
|
|
28
|
+
`~/.local/bin`, telling you if that is not on your PATH. Re-run it to
|
|
29
|
+
upgrade. To remove it entirely:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
rm -rf ~/.local/share/devlift
|
|
33
|
+
rm -f ~/.local/bin/devlift ~/.local/bin/dl
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Developers working on the CLI itself clone the repository and run
|
|
37
|
+
`pip install -e .` inside a virtualenv instead.
|
|
38
|
+
|
|
39
|
+
The login token is kept in the OS keyring when one is available, otherwise
|
|
40
|
+
in `~/.config/devlift/credentials.json` with mode 0600.
|
|
41
|
+
|
|
42
|
+
## 2. First run
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
devlift configure --base-url http://localhost:8000 --default # where the backend runs
|
|
46
|
+
devlift login # opens the browser
|
|
47
|
+
devlift whoami # who you are, what the server enables
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`configure` writes a profile to `~/.config/devlift/cli.json`. A profile is
|
|
51
|
+
just a name, a backend URL and a default output format, and each one keeps
|
|
52
|
+
its own sign-in.
|
|
53
|
+
|
|
54
|
+
### Switching profiles
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
devlift profile list what you have; the default is starred
|
|
58
|
+
devlift profile show which one this shell is using, and why
|
|
59
|
+
devlift profile use prod switch, now and for every later command
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`profile use` changes the saved default, so it lasts until you change it
|
|
63
|
+
again. For one command only, pass `--profile prod` anywhere on the line. For
|
|
64
|
+
one shell session, export `DEVLIFT_PROFILE=prod`.
|
|
65
|
+
|
|
66
|
+
A new profile is created by configuring a name that does not exist yet:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
devlift --profile local configure --base-url http://localhost:8000
|
|
70
|
+
devlift --profile local login
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Two things override a switch, and `profile use` warns you when either is set.
|
|
74
|
+
`DEVLIFT_PROFILE` beats the saved default, and `DEVLIFT_BASE_URL` replaces
|
|
75
|
+
the backend of whichever profile is chosen. An exported `DEVLIFT_BASE_URL` is
|
|
76
|
+
the usual reason a switch appears to do nothing, or why a command reports
|
|
77
|
+
being signed in to one backend while targeting another. `devlift profile
|
|
78
|
+
show` names the cause.
|
|
79
|
+
|
|
80
|
+
## 3. Global options
|
|
81
|
+
|
|
82
|
+
These work anywhere on the command line, before or after the subcommand.
|
|
83
|
+
|
|
84
|
+
| Option | Meaning |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `--profile NAME` | Use this profile (default: the one marked default, or `default`). |
|
|
87
|
+
| `-o, --output table\|json\|yaml` | Output format. Table on a terminal, JSON when piped. |
|
|
88
|
+
| `-y, --yes` | Answer yes to confirmations. |
|
|
89
|
+
| `--no-input` | Never prompt. A missing value is an error (exit 3). Use in scripts and CI. Without `-y`, a write stops at its confirmation (exit 5) after printing its summary on stderr, in `-o json` mode too: a dry run. |
|
|
90
|
+
| `--endpoint-url URL` | Override the backend URL for this one call. |
|
|
91
|
+
| `--debug` | Log every HTTP call to stderr. |
|
|
92
|
+
| `-V, --version` | Print the version. |
|
|
93
|
+
| `-h, --help` | Help for any command. |
|
|
94
|
+
|
|
95
|
+
Environment variables: `DEVLIFT_PROFILE`, `DEVLIFT_BASE_URL` (overrides the
|
|
96
|
+
profile's backend), `DEVLIFT_TOKEN` (use this bearer token instead of the
|
|
97
|
+
stored login), `DEVLIFT_OUTPUT`, `DEVLIFT_NO_CACHE=1` (skip the catalog
|
|
98
|
+
cache), `DEVLIFT_CONFIG_DIR`.
|
|
99
|
+
|
|
100
|
+
Note: a token belongs to the backend it was obtained from. If
|
|
101
|
+
`DEVLIFT_BASE_URL` or `--endpoint-url` points elsewhere the CLI refuses with
|
|
102
|
+
exit 2 and tells you to `devlift login` for that backend.
|
|
103
|
+
|
|
104
|
+
## 4. Exit codes
|
|
105
|
+
|
|
106
|
+
| Code | Meaning |
|
|
107
|
+
|---|---|
|
|
108
|
+
| 0 | Success |
|
|
109
|
+
| 1 | Error (server error, unexpected failure) |
|
|
110
|
+
| 2 | Not signed in, or the token is for another backend. Run `devlift login`. |
|
|
111
|
+
| 3 | Missing or invalid input, or an ambiguous name |
|
|
112
|
+
| 4 | Permission refused by the server |
|
|
113
|
+
| 5 | Confirmation required (no `--yes` while `--no-input`) |
|
|
114
|
+
| 6 | Not found |
|
|
115
|
+
| 7 | Conflict: name already exists, wrong state, lane busy |
|
|
116
|
+
|
|
117
|
+
Errors go to stderr as `error: <message>` plus an optional hint line. With
|
|
118
|
+
`-o json` stdout carries only JSON, so `devlift … -o json | jq` is safe.
|
|
119
|
+
|
|
120
|
+
## 5. Placement allowlist
|
|
121
|
+
|
|
122
|
+
The backend lists every region for every application, which is wider than
|
|
123
|
+
what exists. What each product, environment and region really offers is
|
|
124
|
+
recorded per tenant in `devlift_cli/data/placement/{tenant}.json`, shipped
|
|
125
|
+
inside this CLI:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
{"<workspace>": {"<product>": {"<env>": {"<aws region>": ["s3", "sqs", ...]}}}}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Every create resolves its placement through that file, so a region the
|
|
132
|
+
config does not list for that service is refused before anything is written:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
error: s3 is not offered in 'canada' for core/stage.
|
|
136
|
+
Available there: Mumbai.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`applications list`, `environments list` and `regions list` are filtered by
|
|
140
|
+
it too, so what you are offered is what you can actually create in. They say
|
|
141
|
+
how many rows they hid, and `--all` shows everything the backend reports:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
devlift applications list core (falcon has no placement)
|
|
145
|
+
devlift environments list core/stage: Mumbai
|
|
146
|
+
devlift regions list --for s3 Mumbai
|
|
147
|
+
devlift regions list --all Canada, London, Mumbai
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Service keys are `s3`, `sqs`, `dynamo`, `eks`, `gateway` and `database`.
|
|
151
|
+
Matching is on names, not codes: product `core`, environment `stage`, region
|
|
152
|
+
`ap-south-1` resolved to its city label. A tenant with no file is not
|
|
153
|
+
filtered at all, and filtering fails closed, so a bad match shows nothing
|
|
154
|
+
rather than a placement that does not exist.
|
|
155
|
+
|
|
156
|
+
The chatbot carries the same file at
|
|
157
|
+
`backend/data/placement/{tenant}.json` and the dashboard a coarser copy.
|
|
158
|
+
Change one, change the others.
|
|
159
|
+
|
|
160
|
+
## 6. Names instead of codes
|
|
161
|
+
|
|
162
|
+
Wherever a command takes `--app`, `--env`, `--region` or a service, you can
|
|
163
|
+
type the name you see in the dashboard: `--app core`, `--env stage`,
|
|
164
|
+
`--region mumbai`, `services describe java-service`. Matching is
|
|
165
|
+
case-insensitive, exact first, then unique prefix. An ambiguous name is an
|
|
166
|
+
error that lists the candidates. Codes are accepted too.
|
|
167
|
+
|
|
168
|
+
Catalog answers are cached for ten minutes per profile. Add `--no-cache` to a
|
|
169
|
+
list command, or set `DEVLIFT_NO_CACHE=1`, to refetch.
|
|
170
|
+
|
|
171
|
+
## 7. Commands
|
|
172
|
+
|
|
173
|
+
### auth
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
devlift login [--no-browser] Sign in through the browser (OAuth 2.1, PKCE).
|
|
177
|
+
devlift logout Revoke and forget the stored token.
|
|
178
|
+
devlift whoami User, tenant, backend, enabled features.
|
|
179
|
+
devlift configure [--base-url URL] [--default-output FMT] [--default] [--list]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`--no-browser` prints the sign-in URL instead of opening a browser. The
|
|
183
|
+
login waits up to five minutes for the redirect.
|
|
184
|
+
|
|
185
|
+
### applications, environments, regions, resource-types, resource-groups, repositories, languages
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
devlift applications list [--active] [--all]
|
|
189
|
+
devlift environments list [--app NAME] [--all] Environments and their regions per application.
|
|
190
|
+
devlift regions list [--app NAME] [--env ENV] Regions you can place resources in (the --region values).
|
|
191
|
+
devlift regions list --for s3 Only the regions that really offer that service.
|
|
192
|
+
devlift regions list --all Skip the placement allowlist (section 5).
|
|
193
|
+
devlift regions list --vendor aws The cloud vendor's raw region list.
|
|
194
|
+
devlift resource-types list [--family FAMILY] Infrastructure types (storage, compute, network, …).
|
|
195
|
+
devlift resource-groups list [--app NAME] Resource groups; services are created inside one.
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
A resource group is the permission boundary a service lives in, so it
|
|
199
|
+
decides who may later edit, approve and deploy that service. It is asked for
|
|
200
|
+
by `eks create` when the application has more than one.
|
|
201
|
+
|
|
202
|
+
### services
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
devlift services list [--app NAME] [--search TEXT]
|
|
206
|
+
devlift services describe <name|code>
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### repositories
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
devlift repositories list [--search TEXT] Repositories the DevLift GitHub App can see (--repository values).
|
|
213
|
+
devlift repositories branches <owner/name> Branches of one repository (--branch values).
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### languages
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
devlift languages list Languages and versions a service can use (--language / --version values),
|
|
220
|
+
and whether a starting template exists for each.
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### clusters
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
devlift clusters list [--app NAME] [--env ENV] [--region REGION] [--type eks|ecs] [--search TEXT] [--all]
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The clusters services run on, and the `--cluster` values for `eks create`.
|
|
230
|
+
Narrowed to placements you could really create in: the backend reports only
|
|
231
|
+
the environments this deployment serves, and the placement allowlist
|
|
232
|
+
(section 5) says which of those offer EKS or ECS. Clusters outside both are
|
|
233
|
+
real but unusable from here, so they are hidden and counted; `--all` shows
|
|
234
|
+
everything the backend reports.
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
devlift clusters list --type eks --app core --env stage
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
22 of 25 hidden: not a placement this deployment offers; --all shows everything.
|
|
242
|
+
|
|
243
|
+
Cluster Type Environment Region Application Registered
|
|
244
|
+
acme-core-stage-mumbai-01-application-cluster EKS stage Mumbai core yes
|
|
245
|
+
…two more in the same placement, not registered
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Within that, **Registered** is the flag that matters: only a registered
|
|
249
|
+
cluster may take a new service, and `eks create` will not offer the others.
|
|
250
|
+
A row whose Application reads "tenant-level" belongs to no single product
|
|
251
|
+
and is the fallback for products with no cluster of their own.
|
|
252
|
+
|
|
253
|
+
With exactly one registered cluster in a placement, `eks create` fills it in
|
|
254
|
+
silently. With several it asks, or wants `--cluster` under `--no-input`.
|
|
255
|
+
|
|
256
|
+
### s3
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
devlift s3 list [--app NAME] [--env ENV] [--region REGION]
|
|
260
|
+
devlift s3 describe <bucket|code> [--env ENV]
|
|
261
|
+
devlift s3 create --name NAME --app APP --env ENV --region REGION
|
|
262
|
+
[--versioning | --no-versioning]
|
|
263
|
+
[--replication --cross-account-id 123456789012 | --no-replication]
|
|
264
|
+
[--wait] [-y]
|
|
265
|
+
devlift s3 update <bucket|code> [--env ENV] [--app APP]
|
|
266
|
+
[--versioning | --no-versioning]
|
|
267
|
+
[--replication --cross-account-id 123456789012 | --no-replication]
|
|
268
|
+
[--wait] [-y]
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Every valid combination of the two settings, for `update` and for `create`,
|
|
272
|
+
is listed further down this section.
|
|
273
|
+
|
|
274
|
+
Section 8 walks a bucket through from the first flag to a finished
|
|
275
|
+
deployment.
|
|
276
|
+
|
|
277
|
+
Bucket names: 3-63 characters, lowercase letters, numbers, dots and hyphens,
|
|
278
|
+
starting and ending with a letter or number. The backend prefixes the tenant
|
|
279
|
+
and region on the real AWS name.
|
|
280
|
+
|
|
281
|
+
`--replication` copies objects to another AWS account and needs
|
|
282
|
+
`--cross-account-id` with that account's 12 digits. Either flag without the
|
|
283
|
+
other is refused (exit 3).
|
|
284
|
+
|
|
285
|
+
Every create also stores the AWS account and cloud region the resource sits
|
|
286
|
+
in, which is what the dashboard canvas uses to place it. They are resolved
|
|
287
|
+
automatically and printed in the summary. If they cannot be resolved the
|
|
288
|
+
command says so before asking for confirmation: the resource would deploy
|
|
289
|
+
normally but never appear on the canvas.
|
|
290
|
+
|
|
291
|
+
`update` changes only the flags you pass. It reads the bucket, shows a
|
|
292
|
+
Field | Current | New table, asks for confirmation, then queues and deploys
|
|
293
|
+
the change exactly as `create` does (section 8). The name, application,
|
|
294
|
+
environment and region cannot change — a bucket somewhere else is a new
|
|
295
|
+
bucket. Passing values the bucket already has is reported and changes
|
|
296
|
+
nothing.
|
|
297
|
+
|
|
298
|
+
**Every combination.** Run each without `-y` first: the diff is printed and
|
|
299
|
+
nothing is written (exit 5). Only the flags you pass change; the rest of the
|
|
300
|
+
bucket is left alone.
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
# versioning
|
|
304
|
+
devlift s3 update my-logs --versioning # turn it on
|
|
305
|
+
devlift s3 update my-logs --no-versioning # turn it off
|
|
306
|
+
|
|
307
|
+
# replication
|
|
308
|
+
devlift s3 update my-logs --replication --cross-account-id 123456789012
|
|
309
|
+
devlift s3 update my-logs --cross-account-id 210987654321 # keep it on, change the target
|
|
310
|
+
devlift s3 update my-logs --replication # only if a target is already stored
|
|
311
|
+
devlift s3 update my-logs --no-replication # off, and the target is cleared
|
|
312
|
+
|
|
313
|
+
# both at once: one diff, one confirmation, one deployment
|
|
314
|
+
devlift s3 update my-logs --no-versioning --replication --cross-account-id 123456789012
|
|
315
|
+
devlift s3 update my-logs --versioning --no-replication
|
|
316
|
+
|
|
317
|
+
# doing it for real, and following the deployment
|
|
318
|
+
devlift s3 update my-logs --no-versioning --replication --cross-account-id 123456789012 -y
|
|
319
|
+
devlift s3 update my-logs --versioning -y --wait
|
|
320
|
+
devlift s3 update my-logs --no-replication -y -o json
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
What each combination does:
|
|
324
|
+
|
|
325
|
+
| Flags | Result |
|
|
326
|
+
|---|---|
|
|
327
|
+
| `--versioning` / `--no-versioning` | Versioning on or off. Nothing else touched. |
|
|
328
|
+
| `--replication --cross-account-id ID` | Replication on, replicating to that account. |
|
|
329
|
+
| `--cross-account-id ID` alone | Changes the target account, leaving replication as it is. |
|
|
330
|
+
| `--replication` alone | Only works when the bucket already stores a target account. Without one: "Replication needs a target account" (exit 3). |
|
|
331
|
+
| `--no-replication` | Replication off and the target account emptied, both shown in the diff. |
|
|
332
|
+
| `--no-replication --cross-account-id ID` | Refused (exit 3). An account id means nothing with replication off. |
|
|
333
|
+
| Values the bucket already has | "already has those values. Nothing to change", exit 0, `changed: false`. |
|
|
334
|
+
| No flags at all | Refused (exit 3), listing the flags it accepts. |
|
|
335
|
+
|
|
336
|
+
The same pairs apply to `create`, with one difference: there both
|
|
337
|
+
decisions must be stated. On a terminal the command asks for anything you
|
|
338
|
+
leave out; under `--no-input` a missing one is an error.
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai --versioning --no-replication
|
|
342
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai --no-versioning --no-replication
|
|
343
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai --versioning --replication --cross-account-id 123456789012
|
|
344
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai --no-versioning --replication --cross-account-id 123456789012
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
`--app` and `--env` are normally unnecessary. `--env` only disambiguates a
|
|
348
|
+
name that exists in several environments. `--app` is only needed when the
|
|
349
|
+
backend does not report which application a resource belongs to and more
|
|
350
|
+
than one could own it; otherwise the command infers it from the placement
|
|
351
|
+
allowlist and says which it used.
|
|
352
|
+
|
|
353
|
+
An update also repairs a resource that is missing the dashboard placement:
|
|
354
|
+
if the stored record has no AWS account and cloud region, they are resolved
|
|
355
|
+
and added, and the command says so. That is the fix for a resource created
|
|
356
|
+
by an earlier version of this CLI that never appears on the canvas.
|
|
357
|
+
|
|
358
|
+
### sqs
|
|
359
|
+
|
|
360
|
+
```
|
|
361
|
+
devlift sqs list [--app NAME] [--env ENV] [--region REGION]
|
|
362
|
+
devlift sqs describe <queue|code> [--env ENV]
|
|
363
|
+
devlift sqs create --name NAME --app APP --env ENV --region REGION
|
|
364
|
+
[--fifo | --no-fifo] [--dlq | --no-dlq]
|
|
365
|
+
[--cross-account-id ID ...]
|
|
366
|
+
[--max-receive-count 1-1000] [--visibility-timeout 0-43200]
|
|
367
|
+
[--retention 60-1209600] [--dlq-retention 60-1209600]
|
|
368
|
+
[--wait] [-y]
|
|
369
|
+
devlift sqs update <queue|code> [--env ENV] [--app APP]
|
|
370
|
+
[--dlq | --no-dlq]
|
|
371
|
+
[--cross-account-id ID ... | --clear-cross-accounts]
|
|
372
|
+
[--max-receive-count 1-1000] [--visibility-timeout 0-43200]
|
|
373
|
+
[--retention 60-1209600] [--dlq-retention 60-1209600]
|
|
374
|
+
[--wait] [-y]
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Queue names: letters, numbers, hyphens and underscores, at most 80
|
|
378
|
+
characters, without the `.fifo` suffix (added automatically for FIFO queues).
|
|
379
|
+
|
|
380
|
+
**Creating a queue.** Two decisions must be stated, FIFO and dead-letter
|
|
381
|
+
queue. On a terminal the command asks for whichever you leave out; under
|
|
382
|
+
`--no-input` a missing one is an error. Everything else is optional and
|
|
383
|
+
falls back to the platform's defaults.
|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
# the four basic shapes
|
|
387
|
+
devlift sqs create --name orders --app core --env stage --region mumbai --no-fifo --no-dlq
|
|
388
|
+
devlift sqs create --name orders --app core --env stage --region mumbai --no-fifo --dlq
|
|
389
|
+
devlift sqs create --name orders --app core --env stage --region mumbai --fifo --no-dlq
|
|
390
|
+
devlift sqs create --name orders --app core --env stage --region mumbai --fifo --dlq
|
|
391
|
+
|
|
392
|
+
# a dead-letter queue with its retry budget and its own retention
|
|
393
|
+
devlift sqs create --name orders --app core --env stage --region mumbai \
|
|
394
|
+
--no-fifo --dlq --max-receive-count 5 --dlq-retention 1209600
|
|
395
|
+
|
|
396
|
+
# message timings
|
|
397
|
+
devlift sqs create --name orders --app core --env stage --region mumbai \
|
|
398
|
+
--no-fifo --no-dlq --visibility-timeout 60 --retention 345600
|
|
399
|
+
|
|
400
|
+
# other AWS accounts allowed to use the queue; repeat the flag per account
|
|
401
|
+
devlift sqs create --name orders --app core --env stage --region mumbai \
|
|
402
|
+
--no-fifo --no-dlq --cross-account-id 123456789012 --cross-account-id 210987654321
|
|
403
|
+
|
|
404
|
+
# everything at once, created for real and followed to the end
|
|
405
|
+
devlift sqs create --name orders --app core --env stage --region mumbai \
|
|
406
|
+
--no-fifo --dlq --max-receive-count 5 \
|
|
407
|
+
--visibility-timeout 60 --retention 345600 --dlq-retention 1209600 \
|
|
408
|
+
--cross-account-id 123456789012 -y --wait
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
| Flag | Meaning | Accepted values |
|
|
412
|
+
|---|---|---|
|
|
413
|
+
| `--fifo` / `--no-fifo` | First-in-first-out ordering. Part of the real queue name, so it can never be changed later. | required |
|
|
414
|
+
| `--dlq` / `--no-dlq` | Create a dead-letter queue beside this one. | required |
|
|
415
|
+
| `--max-receive-count` | Receives before a message is moved to the dead-letter queue. | 1 to 1000 |
|
|
416
|
+
| `--visibility-timeout` | Seconds a received message stays hidden from other consumers. | 0 to 43200 |
|
|
417
|
+
| `--retention` | Seconds a message is kept. | 60 to 1209600 |
|
|
418
|
+
| `--dlq-retention` | The same, for the dead-letter queue. | 60 to 1209600 |
|
|
419
|
+
| `--cross-account-id` | A 12-digit AWS account allowed to use the queue. Repeat it for several. | repeatable |
|
|
420
|
+
|
|
421
|
+
Refusals, all before anything is written (exit 3): a number outside its
|
|
422
|
+
range, an account id that is not 12 digits, a name ending in `.fifo`, and a
|
|
423
|
+
missing `--fifo` or `--dlq` under `--no-input`. Note that
|
|
424
|
+
`--max-receive-count` is accepted with `--no-dlq`, but it has nothing to act
|
|
425
|
+
on, since the count is what moves a message to a dead-letter queue.
|
|
426
|
+
|
|
427
|
+
**Changing a queue.** `update` works like `s3 update`: only the flags you
|
|
428
|
+
pass change, the diff is shown and confirmed, then the change is queued and
|
|
429
|
+
deployed. The name, the FIFO flag, application, environment and region
|
|
430
|
+
cannot change, since FIFO is part of the queue's real name.
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
devlift sqs update orders --dlq --max-receive-count 5 # add a dead-letter queue
|
|
434
|
+
devlift sqs update orders --no-dlq # remove it
|
|
435
|
+
devlift sqs update orders --visibility-timeout 120 # one timing
|
|
436
|
+
devlift sqs update orders --retention 604800 --dlq-retention 604800
|
|
437
|
+
devlift sqs update orders --cross-account-id 123456789012 # REPLACES the whole list
|
|
438
|
+
devlift sqs update orders --clear-cross-accounts # remove every grant
|
|
439
|
+
devlift sqs update orders --dlq --max-receive-count 5 -y --wait
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
`--cross-account-id` on an update replaces the whole list rather than adding
|
|
443
|
+
to it, so pass every account you want to keep. `--clear-cross-accounts`
|
|
444
|
+
empties it, and the two cannot be combined.
|
|
445
|
+
|
|
446
|
+
### dynamodb
|
|
447
|
+
|
|
448
|
+
```
|
|
449
|
+
devlift dynamodb list [--app NAME] [--env ENV] [--region REGION]
|
|
450
|
+
devlift dynamodb describe <table|code> [--env ENV]
|
|
451
|
+
devlift dynamodb create --name NAME --app APP --env ENV --region REGION
|
|
452
|
+
--partition-key ATTR [--partition-key-type S|N|B]
|
|
453
|
+
[--wait] [-y]
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Table names: 3-200 characters of letters, numbers, dots, underscores and
|
|
457
|
+
hyphens.
|
|
458
|
+
|
|
459
|
+
**Creating a table.** Only the name and the partition key are yours to
|
|
460
|
+
decide; the key type defaults to string. These are the same three fields the
|
|
461
|
+
dashboard and the assistant ask for.
|
|
462
|
+
|
|
463
|
+
```
|
|
464
|
+
# the usual case: a string partition key
|
|
465
|
+
devlift dynamodb create --name orders --partition-key order_id
|
|
466
|
+
|
|
467
|
+
# a numeric or binary key
|
|
468
|
+
devlift dynamodb create --name orders --partition-key created_at --partition-key-type N
|
|
469
|
+
devlift dynamodb create --name orders --partition-key payload_id --partition-key-type B
|
|
470
|
+
|
|
471
|
+
# spelled out in full, for a script
|
|
472
|
+
devlift dynamodb create --name orders --app core --env stage --region mumbai \
|
|
473
|
+
--partition-key order_id --partition-key-type S
|
|
474
|
+
|
|
475
|
+
# created for real and followed to the end
|
|
476
|
+
devlift dynamodb create --name orders --partition-key order_id -y --wait
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
| Flag | Meaning | Accepted values |
|
|
480
|
+
|---|---|---|
|
|
481
|
+
| `--name` | Table name. | 3 to 200 characters, letters, numbers, dots, underscores, hyphens |
|
|
482
|
+
| `--partition-key` | The attribute that partitions the table. | 1 to 255 characters, letters, numbers, dots, underscores, hyphens |
|
|
483
|
+
| `--partition-key-type` | Its type. | `S` string (default), `N` number, `B` binary |
|
|
484
|
+
|
|
485
|
+
Refusals, all before anything is written (exit 3): a name shorter than
|
|
486
|
+
three characters or with other punctuation, a partition key with invalid
|
|
487
|
+
characters, and a key type other than S, N or B. On a terminal the name and
|
|
488
|
+
partition key are asked for when omitted; under `--no-input` they are
|
|
489
|
+
errors.
|
|
490
|
+
|
|
491
|
+
**There is no `dynamodb update`.** A table's partition key is fixed at
|
|
492
|
+
creation and cannot be changed afterwards, so the command does not exist.
|
|
493
|
+
Trying it exits 2 with "No such command". A different key means a different
|
|
494
|
+
table.
|
|
495
|
+
|
|
496
|
+
### eks
|
|
497
|
+
|
|
498
|
+
```
|
|
499
|
+
devlift eks create --name NAME --app APP --env ENV --region REGION --type api|worker
|
|
500
|
+
[--resource-group GROUP] [--cluster CLUSTER]
|
|
501
|
+
--repository owner/name --branch main [--branch ...]
|
|
502
|
+
--language Go|Python|Node.js|"Java Maven"|"Java Gradle" --version 1.24
|
|
503
|
+
[--set key=value ...] [--public] [-y]
|
|
504
|
+
devlift eks settings Every key --set accepts, and when each applies.
|
|
505
|
+
devlift eks settings <service> Only the keys that apply to it, with its current values.
|
|
506
|
+
devlift eks show <service> --env ENV The configuration as it stands, with pending values marked.
|
|
507
|
+
devlift eks diff <service> --env ENV Preview the pending change: Field | Deployed | Requested.
|
|
508
|
+
devlift eks diff <service> --deployed The live configuration versus the last deployment.
|
|
509
|
+
devlift eks edit <service> --env ENV [--set key=value ...]
|
|
510
|
+
[--repository owner/name] [--branch ...] [--language L --version V] [-y]
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Gather the answers first.** Placement resolves itself, but a service needs
|
|
514
|
+
a resource group, a repository, a branch on it and a language version. Each
|
|
515
|
+
has a command that lists the accepted values, so none of them has to be
|
|
516
|
+
guessed:
|
|
517
|
+
|
|
518
|
+
```
|
|
519
|
+
# 1. the resource group that will own the service
|
|
520
|
+
devlift resource-groups list --app core
|
|
521
|
+
|
|
522
|
+
# 2. the repository the build reads, and a branch on it
|
|
523
|
+
devlift repositories list --search admin
|
|
524
|
+
devlift repositories branches example-org/admin-api-server
|
|
525
|
+
|
|
526
|
+
# 3. the language and version
|
|
527
|
+
devlift languages list
|
|
528
|
+
|
|
529
|
+
# 4. the cluster, when the placement has more than one registered
|
|
530
|
+
devlift clusters list --type eks --app core --env stage
|
|
531
|
+
|
|
532
|
+
# 5. the settings --set accepts, and when each applies
|
|
533
|
+
devlift eks settings # all of them
|
|
534
|
+
devlift eks settings --language go --type api # only the ones this service would use
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
The resource group is worth a moment: it is part of the service's
|
|
538
|
+
permission path, so it decides who can later edit, approve and deploy it.
|
|
539
|
+
Pick the team that owns the service rather than the default group. The
|
|
540
|
+
repository must be one the DevLift GitHub App can see, and the branch must
|
|
541
|
+
exist on it; both are checked before anything is written.
|
|
542
|
+
|
|
543
|
+
**Then create it.** Run it once without `-y` to see the two tables, then
|
|
544
|
+
again with `-y`:
|
|
545
|
+
|
|
546
|
+
```
|
|
547
|
+
devlift eks create --name orders \
|
|
548
|
+
--resource-group "Default service group" --type api \
|
|
549
|
+
--repo example-org/admin-api-server --branch main \
|
|
550
|
+
--language go --version 1.24
|
|
551
|
+
|
|
552
|
+
devlift eks create --name orders \
|
|
553
|
+
--resource-group "Default service group" --type api \
|
|
554
|
+
--repo example-org/admin-api-server --branch main \
|
|
555
|
+
--language go --version 1.24 -y
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
Add `--app`, `--env` and `--region` to pin the placement, `--cluster` when
|
|
559
|
+
more than one is available, and `--set key=value` for any setting you want
|
|
560
|
+
to differ from the language template.
|
|
561
|
+
|
|
562
|
+
**Add Kong routes, if the service needs them.** They join the same change
|
|
563
|
+
set, so both halves are reviewed and deployed together:
|
|
564
|
+
|
|
565
|
+
```
|
|
566
|
+
devlift kong routes list orders # what it has now
|
|
567
|
+
devlift kong route add orders --method GET --auth jwt --path '~/orders-service/health$'
|
|
568
|
+
devlift kong route add orders --method GET --auth jwt --path '~/orders-service/health$' -y
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
**Preview what a reviewer will see:**
|
|
572
|
+
|
|
573
|
+
```
|
|
574
|
+
devlift eks diff orders --env stage # one table per request, Deployed | Requested
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
**Then take it through review and deploy:**
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
devlift request submit orders # freezes the diff, notifies approvers
|
|
581
|
+
devlift approval approve orders # needs can_approve
|
|
582
|
+
devlift eks deploy orders --env stage # prints the same preview, then asks
|
|
583
|
+
devlift eks deploy orders --env stage -y --wait
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
**Then watch it land.** The deploy prints a workflow id; both of these read
|
|
587
|
+
it back for you:
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
devlift eks status orders --env stage # once
|
|
591
|
+
devlift eks status orders --env stage --wait # follow it to the end
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
`eks status` answers the two separate questions in one go: whether DevLift's
|
|
595
|
+
pipeline finished, with its stages and pull request, and whether ArgoCD
|
|
596
|
+
reports the pods actually serving. They are not the same moment. The
|
|
597
|
+
pipeline turns green when the manifests are merged, and on a first deploy
|
|
598
|
+
the image is still being built by GitHub Actions outside DevLift, so ArgoCD
|
|
599
|
+
can report "waiting" for a while afterwards.
|
|
600
|
+
|
|
601
|
+
By workflow id instead, or when you have lost it:
|
|
602
|
+
|
|
603
|
+
```
|
|
604
|
+
devlift deployment status <workflow-id> --wait
|
|
605
|
+
devlift deployment list --status running
|
|
606
|
+
devlift deployment list --limit 10
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
The service name becomes the Kubernetes namespace and the ECR repository,
|
|
610
|
+
and cannot be renamed once deployed, so choose it before the first create.
|
|
611
|
+
|
|
612
|
+
`eks create` creates a service and saves its first configuration as a **draft** for
|
|
613
|
+
review. It is the dashboard's "Create & Add" followed by the Settings tab's
|
|
614
|
+
Save, in one command:
|
|
615
|
+
|
|
616
|
+
1. Register the service (`POST /services/create-service`): name, type,
|
|
617
|
+
application, resource group.
|
|
618
|
+
2. Create its configuration row for that environment and region
|
|
619
|
+
(`POST /service-configs`) on the chosen EKS cluster. Only the placement
|
|
620
|
+
goes here: cluster, ALB selection (`api` uses the shared ALB, `worker`
|
|
621
|
+
has none) and namespace.
|
|
622
|
+
3. Park the settings as a DRAFT queue item
|
|
623
|
+
(`POST /transaction/service-settings/<config>`), case `update_service`.
|
|
624
|
+
|
|
625
|
+
Nothing is deployed. The draft goes through the review lane: `request
|
|
626
|
+
submit`, `approval approve`, `eks deploy` (section "request, approval,
|
|
627
|
+
eks deploy"), or the dashboard's Preview tab.
|
|
628
|
+
|
|
629
|
+
**Values.** You give what no template can know: repository, branches,
|
|
630
|
+
language and version. The repository must be one the DevLift GitHub App can
|
|
631
|
+
see (`devlift repositories list`; a bare name is accepted when unique) and
|
|
632
|
+
each branch must exist on it (`devlift repositories branches owner/name`).
|
|
633
|
+
`--branch` is required: on a terminal the branches are listed and the
|
|
634
|
+
repository's default branch is offered as the default answer; under
|
|
635
|
+
`--no-input` a missing branch is an error (exit 3). `devlift languages list`
|
|
636
|
+
shows the languages and versions. Every other setting (port, health and service paths,
|
|
637
|
+
CPU and memory, replicas or autoscaling, Dockerfile options, IAM and the
|
|
638
|
+
ECR/secrets/SSM/Argo flags) starts from the platform's template for that
|
|
639
|
+
language, the same one the assistant applies. The full table is printed with
|
|
640
|
+
a "From" column before you confirm. `--set key=value` overrides any of them;
|
|
641
|
+
`devlift eks settings` lists the keys. Booleans are `true`/`false`, lists are
|
|
642
|
+
comma-separated (`--set custom_iam_policies=s3,sqs`), build args are
|
|
643
|
+
`NAME=VALUE` pairs (`--set build_args=APP_ENV=prod,REGION=ap-south-1`).
|
|
644
|
+
Where the template has no reliable default, the command asks on a terminal,
|
|
645
|
+
or exits 3 naming the `--set` key under `--no-input`.
|
|
646
|
+
|
|
647
|
+
**Finding the `--set` keys.** `devlift eks settings` is the list, and naming
|
|
648
|
+
a service narrows it to that service, adding the value each key holds today.
|
|
649
|
+
That is the list to work from before an edit: what you can change, what it
|
|
650
|
+
is now, and what values are accepted.
|
|
651
|
+
|
|
652
|
+
```
|
|
653
|
+
devlift eks settings orders --env stage
|
|
654
|
+
|
|
655
|
+
orders (stage)
|
|
656
|
+
Key Setting Values Current Required
|
|
657
|
+
port Port text 8080 yes
|
|
658
|
+
alb_schema ALB schema internal | internet-facing internal yes
|
|
659
|
+
cpu_limit CPU limit (cores) text 0.25 yes
|
|
660
|
+
go_config_path Go config path text configs/…
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
`--language go --type api` narrows the same way without naming a service,
|
|
664
|
+
which is what to use before a create. An unknown key is refused by `--set`
|
|
665
|
+
with the full list, so a typo never reaches the backend.
|
|
666
|
+
|
|
667
|
+
**Passing several settings.** Repeat the flag, or put them in one `--set`
|
|
668
|
+
separated by semicolons. Both produce one diff, one confirmation and one
|
|
669
|
+
deployment:
|
|
670
|
+
|
|
671
|
+
```
|
|
672
|
+
--set cpu_limit=0.5 --set memory_limit=0.5 --set port=9090
|
|
673
|
+
--set "cpu_limit=0.5;memory_limit=0.5;port=9090"
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
The separator is a semicolon, not a comma, because a comma already
|
|
677
|
+
separates the values inside one setting. The two nest cleanly:
|
|
678
|
+
|
|
679
|
+
```
|
|
680
|
+
--set "custom_iam_policies=s3,sqs;cpu_limit=0.5" # one setting with two values, and another setting
|
|
681
|
+
--set "build_args=APP_ENV=prod,REGION=ap-south-1;port=9090"
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
The semicolon form must be quoted, because a bare `;` ends the command in
|
|
685
|
+
the shell. Repeated flags need no quotes, so use those if you would rather
|
|
686
|
+
not quote. Commas need no quoting either.
|
|
687
|
+
|
|
688
|
+
```
|
|
689
|
+
--set "cpu_limit=0.5;port=9090" # quoted: the shell would split it otherwise
|
|
690
|
+
--set cpu_limit=0.5 --set port=9090 # no quotes needed
|
|
691
|
+
--set custom_iam_policies=s3,sqs # no quotes needed
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
**Per-language and conditional settings.** Not every key applies to every
|
|
695
|
+
service; the rules are the platform form's own: `xms` / `xmx` only for Java,
|
|
696
|
+
`go_config_path` / `go_use_aws_secrets` only for Go, `build_path` for Java
|
|
697
|
+
and Go, `dockerfile_path` only with `generate_dockerfile=false`,
|
|
698
|
+
`alb_schema` / `health` / `service_path` only for `--type api`,
|
|
699
|
+
`min_replicas` / `max_replicas` only with `hpa_enabled=true` and
|
|
700
|
+
`replica_count` only without it. `devlift eks settings` shows the table.
|
|
701
|
+
A template value that does not apply falls away; a `--set` that does not
|
|
702
|
+
apply is refused with the reason (exit 3). Values are checked the way the
|
|
703
|
+
form checks them: CPU 0.1-4 cores and memory 0.1-8 GiB with limit >= request,
|
|
704
|
+
replicas 1-100 with max > min, paths starting with `/`, heap sizes like
|
|
705
|
+
`512m`, IAM policies from s3 / sqs / dynamodb / ses, build-arg names in
|
|
706
|
+
uppercase. Service names are lowercase letters, numbers and hyphens.
|
|
707
|
+
|
|
708
|
+
**Cluster.** The registered EKS cluster for that product, environment and
|
|
709
|
+
region is picked automatically; tenant-level clusters are the fallback.
|
|
710
|
+
Several candidates are asked for, or named with `--cluster`.
|
|
711
|
+
|
|
712
|
+
A name that already exists in the application is refused (exit 7); adding a
|
|
713
|
+
configuration in another environment for an existing service is not
|
|
714
|
+
available yet.
|
|
715
|
+
|
|
716
|
+
**Editing.** `eks edit` is the Settings tab's Save from the terminal. It
|
|
717
|
+
starts from the configuration as it stands — the live values with your open
|
|
718
|
+
draft, if any, laid over them — applies your changes, prints a Setting /
|
|
719
|
+
Current / New table of only what changes, and saves the whole result as a
|
|
720
|
+
settings draft (`POST /transaction/service-settings/<config>`). An open
|
|
721
|
+
draft of yours is updated in place (same queue code), so repeated edits stay
|
|
722
|
+
one request. A submitted or approved request on the service, whoever's,
|
|
723
|
+
blocks editing (exit 7) until it is deployed, withdrawn or revoked: its
|
|
724
|
+
values are being decided on. Passing values the service already has changes
|
|
725
|
+
nothing. The same per-language and conditional rules as `eks create` apply.
|
|
726
|
+
**Previewing a change.** `eks diff` is the preview: the pending request's
|
|
727
|
+
own table of Field, Deployed and Requested, computed by DevLift against the
|
|
728
|
+
live configuration. It is the same table the dashboard's Preview tab and the
|
|
729
|
+
assistant render, so all three agree on what a reviewer will decide on. One
|
|
730
|
+
table per request, since a service's settings and its gateway routes are two
|
|
731
|
+
rows of one change.
|
|
732
|
+
|
|
733
|
+
```
|
|
734
|
+
devlift eks diff orders --env stage
|
|
735
|
+
|
|
736
|
+
orders (stage / Mumbai) · Settings · draft (queue-…, by a. developer)
|
|
737
|
+
Field Deployed Requested
|
|
738
|
+
port – 8080
|
|
739
|
+
health – /orders-service/health
|
|
740
|
+
cpu_limit – 0.25m
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
With nothing pending it says so. `--deployed` answers a different question,
|
|
744
|
+
the redeploy drift: what the **live** configuration holds versus what was
|
|
745
|
+
last deployed. That one ignores drafts entirely, so on a service whose
|
|
746
|
+
change is still a draft it shows the live row and its defaults, not what the
|
|
747
|
+
draft proposes.
|
|
748
|
+
|
|
749
|
+
`eks show` marks each value that a pending request would change.
|
|
750
|
+
|
|
751
|
+
### kong
|
|
752
|
+
|
|
753
|
+
```
|
|
754
|
+
devlift kong routes list <service> [--env ENV] [--region REGION]
|
|
755
|
+
devlift kong route add <service> --env ENV --method GET --auth jwt|public
|
|
756
|
+
--path '~/api/v1/orders$' [--path ...]
|
|
757
|
+
[--tag TAG] [--priority 0-10000] [--plugin "User ID Injection"] [-y]
|
|
758
|
+
devlift kong route remove <service> --env ENV --method GET --tag TAG --path '~/...$' [--path ...] [-y]
|
|
759
|
+
devlift kong route rename <service> --env ENV --method GET --tag TAG --from '~/old$' --to '~/new$' [-y]
|
|
760
|
+
devlift kong plugin add <service> --env ENV --method GET --tag TAG --plugin "User ID Injection" [--priority N] [-y]
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
The gateway of one service configuration (environment + region), read and
|
|
764
|
+
written the way the dashboard's Gateway tab does it. `routes list` shows
|
|
765
|
+
the route groups: method, auth, tag, paths (with "not deployed" for paths
|
|
766
|
+
that are still pending), regex priority, extra plugins and any pending
|
|
767
|
+
queue items on the group.
|
|
768
|
+
|
|
769
|
+
A change targets **one route group**: a tag for one HTTP method. `route add`
|
|
770
|
+
creates the group when it does not exist, named after the service (`orders`
|
|
771
|
+
for JWT, `orders-open` for public) unless `--tag` says otherwise. A tag is
|
|
772
|
+
one group per method and its auth is fixed: adding a public path to a JWT
|
|
773
|
+
tag is refused (exit 7), pick another tag. Paths already on the group are
|
|
774
|
+
reported and skipped; a path to remove or rename that is not on the group is
|
|
775
|
+
an error listing what is (exit 6). Nothing to change exits 0 with
|
|
776
|
+
`changed: false`.
|
|
777
|
+
|
|
778
|
+
Paths are Kong regex paths: start with `~/`, end with `$`, no spaces,
|
|
779
|
+
parameters as regex groups (`~/api/v1/users/(?<id>[^/]+)$`, never `/:id`).
|
|
780
|
+
Tags are letters, numbers, underscores and single hyphens. JWT comes from
|
|
781
|
+
`--auth`; `--plugin` is for the extra plugins the tab offers.
|
|
782
|
+
|
|
783
|
+
The change is printed and confirmed, then saved as a DRAFT queue item
|
|
784
|
+
(`POST /transaction/kong-gateway/<config>`, the gateway half of the
|
|
785
|
+
service's change set). Nothing reaches Kong until the draft is submitted,
|
|
786
|
+
approved and deployed (`request submit`, `approval approve`, `eks deploy`).
|
|
787
|
+
|
|
788
|
+
### request, approval, eks deploy — the review lane
|
|
789
|
+
|
|
790
|
+
```
|
|
791
|
+
devlift request list [--status draft|submit|approved|rejected] [--service NAME --env ENV] [--mine]
|
|
792
|
+
devlift request show <queue-code|service> [--env ENV]
|
|
793
|
+
devlift request history <service> [--env ENV]
|
|
794
|
+
devlift request submit <queue-code|service> [--env ENV] [--comment TEXT] [-y]
|
|
795
|
+
devlift request withdraw <queue-code|service> [--env ENV] [--comment TEXT] [-y]
|
|
796
|
+
devlift request discard <queue-code|service> [--env ENV] [-y]
|
|
797
|
+
|
|
798
|
+
devlift approval list
|
|
799
|
+
devlift approval approve <queue-code|service> [--env ENV] [--comment TEXT] [-y]
|
|
800
|
+
devlift approval request-changes <queue-code|service> [--env ENV] --comment TEXT [-y]
|
|
801
|
+
devlift approval reject <queue-code|service> [--env ENV] --comment TEXT [-y]
|
|
802
|
+
devlift approval revoke <queue-code|service> [--env ENV] [--comment TEXT] [-y]
|
|
803
|
+
|
|
804
|
+
devlift eks deploy <service> --env ENV [--region REGION] [--confirm-name NAME] [--wait] [-y]
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
A service's change is one **change set**: its settings request, its gateway
|
|
808
|
+
routes request and its variables request, for one configuration and one
|
|
809
|
+
author. Every verb moves the whole set, so naming a service acts on all of
|
|
810
|
+
its rows, and the output lists each one. A queue code names its own set.
|
|
811
|
+
|
|
812
|
+
```
|
|
813
|
+
draft ──submit──▶ submit ──approve──▶ approved ──deploy──▶ in flight
|
|
814
|
+
▲ │ ▲ │
|
|
815
|
+
└────withdraw─────┘ └──────revoke───────┘
|
|
816
|
+
└──request-changes──┘ reject ──▶ rejected (terminal)
|
|
817
|
+
discard throws a draft away
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
- **submit** (author): the diff is frozen per row; a reviewer decides on
|
|
821
|
+
exactly that. One live request per service at a time: a second author is
|
|
822
|
+
told whose request holds the lane (exit 7).
|
|
823
|
+
- **withdraw** (submitter only) and **request-changes** (reviewer, comment
|
|
824
|
+
required) both return the set to draft. **reject** (reviewer, comment
|
|
825
|
+
required) is terminal.
|
|
826
|
+
- **approve** (needs `can_approve`; self-approval only where the resource
|
|
827
|
+
group's rule allows it) seals each row. **revoke** takes an approval back
|
|
828
|
+
while nothing has started deploying; the request waits for a decision
|
|
829
|
+
again.
|
|
830
|
+
- **eks deploy** prints what is about to ship before it asks: the approved
|
|
831
|
+
requests, then each one's Field | Deployed | Requested table, the same
|
|
832
|
+
preview `eks diff` and the dashboard show. It ships the set with one call
|
|
833
|
+
(`POST /deployments/multiple-deploy {service_config_code}`): the backend
|
|
834
|
+
resolves the approved rows, re-checks the seal, and starts one workflow.
|
|
835
|
+
On **prod** the service name must be typed back (`--confirm-name` when
|
|
836
|
+
not on a terminal); `-y` alone is not enough. `--wait` follows the
|
|
837
|
+
orchestrator (variables, then the service) to completion.
|
|
838
|
+
|
|
839
|
+
Each write prints the request(s) with the frozen diff, then confirms. `-o
|
|
840
|
+
json` returns the rows and their new status. `request show` on a draft has
|
|
841
|
+
no diff yet; the dashboard's Preview tab computes one live.
|
|
842
|
+
|
|
843
|
+
### deployment, queue, eks status
|
|
844
|
+
|
|
845
|
+
```
|
|
846
|
+
devlift deployment list [--status running|completed|failed|timedout] [--app NAME] [--env ENV] [--mine] [--limit N]
|
|
847
|
+
devlift deployment status <workflow-id> [--wait] One deployment: status, PR, resources, pipeline stages.
|
|
848
|
+
devlift eks status <service> --env ENV [--wait] [--no-argo]
|
|
849
|
+
devlift queue list [--env ENV] Your transaction-queue items.
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
`deployment list` and `deployment status` read the same history the
|
|
853
|
+
dashboard's deployment tracker shows: every workflow (resource creates,
|
|
854
|
+
service deploys), who started it, its pull request, the resources it
|
|
855
|
+
carried and the pipeline stages with their timings. `--wait` polls until
|
|
856
|
+
the workflow reaches a terminal status.
|
|
857
|
+
|
|
858
|
+
`eks status` answers two different questions for one service configuration:
|
|
859
|
+
|
|
860
|
+
1. **Deployment** — did DevLift's pipeline finish? The latest workflow that
|
|
861
|
+
carried this configuration, with its stages and PR.
|
|
862
|
+
2. **Application** — is the service actually serving? Asked of ArgoCD
|
|
863
|
+
(`GET /deployments/application-status`, the same implementation the
|
|
864
|
+
assistant uses). DevLift's pipeline turns green when the manifests are
|
|
865
|
+
merged, before ArgoCD rolls a pod, so the ArgoCD reading is compared
|
|
866
|
+
against the deploy's finish time: activity older than the deploy means
|
|
867
|
+
"waiting for ArgoCD", not "up". `state` is one of up, starting,
|
|
868
|
+
unhealthy, waiting_for_argocd, not_picked_up, missing, suspended,
|
|
869
|
+
not_found, not_configured (no ArgoCD for that environment), unavailable.
|
|
870
|
+
Health, sync, the running image, and the ArgoCD and health-check URLs
|
|
871
|
+
are shown when known. Note that DevLift never learns the image tag the
|
|
872
|
+
app repository built, so "up" means a healthy pod, not proof that the
|
|
873
|
+
new code is live.
|
|
874
|
+
|
|
875
|
+
`--wait` follows the deployment to its end and then ArgoCD until the state
|
|
876
|
+
settles (up to ten minutes). `--no-argo` skips the ArgoCD check.
|
|
877
|
+
|
|
878
|
+
### manual
|
|
879
|
+
|
|
880
|
+
```
|
|
881
|
+
devlift man This whole document, paged like `man` (scroll, / to search, q to leave).
|
|
882
|
+
devlift manual [topic] The same; with a topic, one section printed straight through (`devlift manual s3`).
|
|
883
|
+
devlift manual --no-pager The whole document without paging. --raw prints plain Markdown.
|
|
884
|
+
devlift <group> manual This group's section, from inside the group (`devlift sqs manual`).
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
Every command group carries its own `manual`: `s3`, `sqs`, `dynamodb`,
|
|
888
|
+
`eks`, `kong`, `request`, `approval`, `deployment`, `repositories` and
|
|
889
|
+
`languages`. It prints exactly what `devlift manual <group>` prints, so it
|
|
890
|
+
can be read without leaving the group you were typing in. `--raw` gives
|
|
891
|
+
plain Markdown.
|
|
892
|
+
|
|
893
|
+
## 8. Creating a bucket, start to finish
|
|
894
|
+
|
|
895
|
+
The same five steps work for a queue or a table: swap `s3 create` for
|
|
896
|
+
`sqs create` or `dynamodb create`.
|
|
897
|
+
|
|
898
|
+
**1. Find the values for the flags.** Names are accepted everywhere, so this
|
|
899
|
+
is only needed the first time.
|
|
900
|
+
|
|
901
|
+
```
|
|
902
|
+
devlift applications list # --app
|
|
903
|
+
devlift environments list --app core # --env, and the regions per environment
|
|
904
|
+
devlift regions list --app core --env stage # --region
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
All three are already filtered by the placement allowlist (section 5), so
|
|
908
|
+
anything they list is somewhere a bucket can really go.
|
|
909
|
+
|
|
910
|
+
**2. Choose the bucket's settings.** Two decisions, and both must be stated.
|
|
911
|
+
|
|
912
|
+
```
|
|
913
|
+
--versioning | --no-versioning keep old object versions
|
|
914
|
+
--replication --cross-account-id 123456789012 copy objects to another AWS account
|
|
915
|
+
--no-replication no copy
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
Replication needs a target account, so `--replication` without
|
|
919
|
+
`--cross-account-id` is refused (exit 3), and `--cross-account-id` without
|
|
920
|
+
`--replication` is refused too. The account id is the 12-digit AWS account
|
|
921
|
+
that receives the copies, not the one the bucket lives in.
|
|
922
|
+
|
|
923
|
+
**3. Dry run it.** Leave `-y` off. The command resolves everything, checks
|
|
924
|
+
the name is free, prints the summary and stops before writing anything
|
|
925
|
+
(exit 5).
|
|
926
|
+
|
|
927
|
+
```
|
|
928
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai \
|
|
929
|
+
--versioning --no-replication
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
With replication instead:
|
|
933
|
+
|
|
934
|
+
```
|
|
935
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai \
|
|
936
|
+
--versioning --replication --cross-account-id 123456789012
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
```
|
|
940
|
+
Create bucket
|
|
941
|
+
Bucket my-logs
|
|
942
|
+
Application core
|
|
943
|
+
Environment stage
|
|
944
|
+
Region Mumbai
|
|
945
|
+
AWS account 111122223333
|
|
946
|
+
Cloud region ap-south-1
|
|
947
|
+
Versioning yes
|
|
948
|
+
Replication yes
|
|
949
|
+
Replication account 123456789012
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
Check the AWS account and cloud region lines. They are what places the
|
|
953
|
+
bucket on the dashboard canvas. If they are missing the command warns you,
|
|
954
|
+
and the bucket will deploy but stay invisible on the canvas.
|
|
955
|
+
|
|
956
|
+
**4. Create it for real.** Add `-y` to the same command. This registers the
|
|
957
|
+
bucket, queues it, approves it and starts the deployment.
|
|
958
|
+
|
|
959
|
+
```
|
|
960
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai \
|
|
961
|
+
--versioning --replication --cross-account-id 123456789012 -y
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
```
|
|
965
|
+
Registered bucket my-logs (INFRA_S3_1A2B3C4D).
|
|
966
|
+
Deployment queued (workflow deploy-example-1a2b3c4d5e6f).
|
|
967
|
+
|
|
968
|
+
Bucket my-logs
|
|
969
|
+
Resource code INFRA_S3_1A2B3C4D
|
|
970
|
+
Queue item queue-5e6f7a8b9c0d
|
|
971
|
+
Workflow deploy-example-1a2b3c4d5e6f
|
|
972
|
+
```
|
|
973
|
+
|
|
974
|
+
Keep the workflow id. Adding `--wait` to the create does the next step for
|
|
975
|
+
you.
|
|
976
|
+
|
|
977
|
+
**5. Watch the deployment.** The backend opens a pull request and applies it.
|
|
978
|
+
|
|
979
|
+
```
|
|
980
|
+
devlift deployment status deploy-example-1a2b3c4d5e6f --wait
|
|
981
|
+
```
|
|
982
|
+
|
|
983
|
+
Without `--wait` it prints the current state once. With it, the command
|
|
984
|
+
follows the workflow and returns when it is done or failed. The output
|
|
985
|
+
names the status, the pull request, the resources in the deployment and
|
|
986
|
+
each pipeline stage with its timing.
|
|
987
|
+
|
|
988
|
+
Lost the id? The history is searchable:
|
|
989
|
+
|
|
990
|
+
```
|
|
991
|
+
devlift deployment list --limit 10
|
|
992
|
+
devlift deployment list --status running
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
**6. Confirm the bucket exists.**
|
|
996
|
+
|
|
997
|
+
```
|
|
998
|
+
devlift s3 describe my-logs --env stage
|
|
999
|
+
devlift s3 list --app core --env stage --region mumbai
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
`describe` shows the real AWS name, which carries a tenant and region
|
|
1003
|
+
prefix, so `my-logs` becomes something like
|
|
1004
|
+
`acme-core-stage-mumbai-01-my-logs`. On the dashboard canvas, search for
|
|
1005
|
+
the name you passed to `--name`.
|
|
1006
|
+
|
|
1007
|
+
### What a create does underneath
|
|
1008
|
+
|
|
1009
|
+
1. Resolve `--app`, `--env`, `--region` to backend codes, and the AWS
|
|
1010
|
+
account and cloud region for the canvas.
|
|
1011
|
+
2. Validate the name locally, then ask the backend's duplicate check.
|
|
1012
|
+
3. Print a summary and ask for confirmation (`-y` skips it; `--no-input`
|
|
1013
|
+
without `-y` exits 5).
|
|
1014
|
+
4. Register the resource (`POST /infrastructures`).
|
|
1015
|
+
5. Add it to the transaction queue and approve the item.
|
|
1016
|
+
6. Start the deployment (`POST /transaction-queue/deploy`). The backend
|
|
1017
|
+
opens a pull request and applies it through its workflow; the command
|
|
1018
|
+
returns as soon as the workflow is accepted.
|
|
1019
|
+
7. With `--wait`, poll the workflow until it finishes or fails.
|
|
1020
|
+
|
|
1021
|
+
The output carries the resource code, the queue item code, and the workflow
|
|
1022
|
+
id or pull-request URL. Re-running the same create is refused as a
|
|
1023
|
+
duplicate (exit 7); use `describe` to see the existing resource.
|
|
1024
|
+
|
|
1025
|
+
## 9. Scripting examples
|
|
1026
|
+
|
|
1027
|
+
```
|
|
1028
|
+
# JSON for every service, filtered with jq
|
|
1029
|
+
devlift services list -o json | jq '.[] | select(.status=="active") | .service_name'
|
|
1030
|
+
|
|
1031
|
+
# Fully non-interactive create; fails instead of prompting
|
|
1032
|
+
devlift s3 create --name my-logs --app core --env stage --region mumbai \
|
|
1033
|
+
--versioning --no-replication --no-input -y -o json
|
|
1034
|
+
|
|
1035
|
+
# The workflow id from that JSON, followed to the end
|
|
1036
|
+
devlift deployment status "$(devlift s3 create ... --no-input -y -o json | jq -r .workflow_id)" --wait
|
|
1037
|
+
|
|
1038
|
+
# Use a CI token instead of a browser login
|
|
1039
|
+
DEVLIFT_TOKEN=... devlift whoami -o json
|
|
1040
|
+
|
|
1041
|
+
# Follow a deployment started earlier
|
|
1042
|
+
devlift deployment status deploy-example-9f8e7d6c5b4a --wait
|
|
1043
|
+
```
|
|
1044
|
+
|
|
1045
|
+
## 10. Troubleshooting
|
|
1046
|
+
|
|
1047
|
+
- **exit 2, "Not signed in"**: run `devlift login`. If you set
|
|
1048
|
+
`DEVLIFT_TOKEN`, it is used as-is and never refreshed.
|
|
1049
|
+
- **"Profile 'default' is signed in to X, but this command targets Y"**: an
|
|
1050
|
+
environment variable or `--endpoint-url` changed the backend. Unset
|
|
1051
|
+
`DEVLIFT_BASE_URL`, or `devlift login` against the new backend.
|
|
1052
|
+
- **"Could not connect"**: the backend at the profile's URL is not running.
|
|
1053
|
+
Check `devlift configure --list`.
|
|
1054
|
+
- **`--wait` reports the status service is busy**: the backend's workflow
|
|
1055
|
+
status route is unavailable; the deployment itself continues. Check later
|
|
1056
|
+
with `devlift deployment status <workflow-id>`.
|
|
1057
|
+
- **Table output looks like JSON**: stdout is not a terminal, so JSON is the
|
|
1058
|
+
default. Force a table with `-o table`.
|
|
1059
|
+
|
|
1060
|
+
## 11. Not available yet
|
|
1061
|
+
|
|
1062
|
+
Not available from the CLI, by design: **variables and secrets** (their
|
|
1063
|
+
draft lives partly in a store only the secret service may write, and
|
|
1064
|
+
secret values must never pass through a shell), use the dashboard's
|
|
1065
|
+
Variables tab. Planned but not implemented: `data query` and an interactive
|
|
1066
|
+
`shell`.
|