@agilecustoms/envctl 1.16.1 → 1.18.0
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.
- package/README.md +5 -4
- package/dist/client/Cli.js +1 -1
- package/dist/commands/_keys.js +0 -1
- package/dist/commands/{deploy.js → apply.js} +3 -3
- package/dist/commands/index.js +1 -1
- package/dist/commands/plan.js +1 -1
- package/dist/index.js +2 -2
- package/dist/service/EnvService.js +18 -19
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
```shell
|
|
9
9
|
terraform init -backend-config=key=laxa1986
|
|
10
|
-
envctl
|
|
10
|
+
envctl apply -var-file=versions.tfvars -var="log_level=debug"
|
|
11
11
|
envctl delete
|
|
12
12
|
```
|
|
13
13
|
|
|
@@ -43,9 +43,10 @@ Creation API yields unique ID, so you can safely extend lifetime via this ID
|
|
|
43
43
|
|
|
44
44
|
### Authorization
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
1. create
|
|
48
|
-
2.
|
|
46
|
+
Main use cases:
|
|
47
|
+
1. create env from a dev machine
|
|
48
|
+
2. env created automatically per feature branch
|
|
49
|
+
3. create an ephemeral environment on CI
|
|
49
50
|
|
|
50
51
|
Originally I (Alex C) have chosen IAM authorization (`/ci/deployer` on pipeline via OIDC, `/developer` on dev machine via SSO)
|
|
51
52
|
Then (Feb 2026) I reworked it to use API keys
|
package/dist/client/Cli.js
CHANGED
package/dist/commands/_keys.js
CHANGED
|
@@ -2,9 +2,9 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { ConfigService, EnvService } from '../service/index.js';
|
|
3
3
|
import { _keys } from './_keys.js';
|
|
4
4
|
import { wrap } from './_utils.js';
|
|
5
|
-
export function
|
|
5
|
+
export function apply(program, configService, envService) {
|
|
6
6
|
program
|
|
7
|
-
.command('
|
|
7
|
+
.command('apply')
|
|
8
8
|
.description('Create new or update existing environment')
|
|
9
9
|
.option('--profile <profile>', _keys.PROFILE)
|
|
10
10
|
.allowUnknownOption(true)
|
|
@@ -12,6 +12,6 @@ export function deploy(program, configService, envService) {
|
|
|
12
12
|
.action(wrap(async (tfArgs, options) => {
|
|
13
13
|
const { profile } = options;
|
|
14
14
|
configService.init(profile);
|
|
15
|
-
await envService.
|
|
15
|
+
await envService.apply(tfArgs);
|
|
16
16
|
}));
|
|
17
17
|
}
|
package/dist/commands/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
export { apply } from './apply.js';
|
|
1
2
|
export { configure } from './configure.js';
|
|
2
3
|
export { createEphemeral } from './createEphemeral.js';
|
|
3
4
|
export { deleteIt } from './delete.js';
|
|
4
|
-
export { deploy } from './deploy.js';
|
|
5
5
|
export { destroy } from './destroy.js';
|
|
6
6
|
export { logs } from './logs.js';
|
|
7
7
|
export { plan } from './plan.js';
|
package/dist/commands/plan.js
CHANGED
|
@@ -5,7 +5,7 @@ import { wrap } from './_utils.js';
|
|
|
5
5
|
export function plan(program, configService, envService) {
|
|
6
6
|
program
|
|
7
7
|
.command('plan')
|
|
8
|
-
.description('High level wrapper for terraform plan. Compliments
|
|
8
|
+
.description('High level wrapper for terraform plan. Compliments apply command: if you plan to deploy env with envctl apply,'
|
|
9
9
|
+ ' then it is recommended to do plan with envctl plan to guarantee consistent behavior')
|
|
10
10
|
.option('--profile <profile>', _keys.PROFILE)
|
|
11
11
|
.allowUnknownOption(true)
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import updateNotifier from 'update-notifier';
|
|
5
|
-
import { configure, createEphemeral, deleteIt,
|
|
5
|
+
import { configure, createEphemeral, deleteIt, apply, destroy, logs, plan, status } from './commands/index.js';
|
|
6
6
|
import { buildContainer } from './container.js';
|
|
7
7
|
const require = createRequire(import.meta.url);
|
|
8
8
|
const pkg = require('../package.json');
|
|
@@ -18,10 +18,10 @@ program
|
|
|
18
18
|
.version(pkg.version, '', 'Output the version number')
|
|
19
19
|
.helpOption('-h, --help', 'Display help for command')
|
|
20
20
|
.option('--verbose', 'Verbose output (w/ debug logs)');
|
|
21
|
+
apply(program, configService, envService);
|
|
21
22
|
configure(program, configService);
|
|
22
23
|
createEphemeral(program, configService, envService);
|
|
23
24
|
deleteIt(program, configService, envService);
|
|
24
|
-
deploy(program, configService, envService);
|
|
25
25
|
destroy(program, configService, envService);
|
|
26
26
|
logs(program, configService, logService);
|
|
27
27
|
plan(program, configService, envService);
|
|
@@ -27,10 +27,10 @@ export class EnvService extends BaseService {
|
|
|
27
27
|
if (env.status !== EnvStatus.Deleting && env.status !== EnvStatus.DeleteError) {
|
|
28
28
|
logger.info(`Expires at ${toLocalTime(env.ttl)}`);
|
|
29
29
|
}
|
|
30
|
-
if (env.
|
|
31
|
-
const
|
|
32
|
-
if (env.
|
|
33
|
-
logger.warn(`Env ${key}
|
|
30
|
+
if (env.dir) {
|
|
31
|
+
const dir = this.cli.getDir();
|
|
32
|
+
if (env.dir !== dir) {
|
|
33
|
+
logger.warn(`Env ${key} was deployed from ${env.dir}`);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -45,13 +45,13 @@ export class EnvService extends BaseService {
|
|
|
45
45
|
}
|
|
46
46
|
return env;
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
checkDir(env) {
|
|
49
49
|
if (env.ephemeral)
|
|
50
50
|
return;
|
|
51
|
-
if (env.
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
throw new KnownException(`Env ${env.key}
|
|
51
|
+
if (env.dir) {
|
|
52
|
+
const dir = this.cli.getDir();
|
|
53
|
+
if (dir !== env.dir) {
|
|
54
|
+
throw new KnownException(`Env ${env.key} was deployed from ${env.dir} - make sure you run this command from the same directory`);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -59,7 +59,7 @@ export class EnvService extends BaseService {
|
|
|
59
59
|
const key = this.terraformAdapter.getTerraformBackend().getKey();
|
|
60
60
|
const env = await this.tryGetEnv(key);
|
|
61
61
|
if (env) {
|
|
62
|
-
this.
|
|
62
|
+
this.checkDir(env);
|
|
63
63
|
this.handleDeleteStatuses(env);
|
|
64
64
|
}
|
|
65
65
|
const newEnv = env === null;
|
|
@@ -112,21 +112,20 @@ export class EnvService extends BaseService {
|
|
|
112
112
|
Check logs with 'envctl logs', address the issue and re-run 'envctl delete ${env.key}'`);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
async
|
|
115
|
+
async apply(tfArgs) {
|
|
116
116
|
const key = this.terraformAdapter.getTerraformBackend().getKey();
|
|
117
117
|
let env = await this.tryGetEnv(key);
|
|
118
118
|
if (env === null) {
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
const createEnv = { key, kind };
|
|
119
|
+
const dir = this.cli.getDir();
|
|
120
|
+
const createEnv = { key, dir };
|
|
122
121
|
await this.lockTerraform(createEnv, true);
|
|
123
122
|
tfArgs = await this.ensurePlan({ key, ephemeral: false }, tfArgs);
|
|
124
123
|
logger.info('Creating env metadata');
|
|
125
124
|
env = await this.envApi.create(createEnv);
|
|
126
|
-
await this.
|
|
125
|
+
await this.runApply(env, tfArgs);
|
|
127
126
|
return;
|
|
128
127
|
}
|
|
129
|
-
this.
|
|
128
|
+
this.checkDir(env);
|
|
130
129
|
this.handleDeleteStatuses(env);
|
|
131
130
|
const status = env.status;
|
|
132
131
|
if (status === EnvStatus.Deploying || status === EnvStatus.Updating) {
|
|
@@ -146,13 +145,13 @@ export class EnvService extends BaseService {
|
|
|
146
145
|
logger.info('Will lock for update and run terraform apply (to update resources)');
|
|
147
146
|
}
|
|
148
147
|
await this.envApi.lockForUpdate(env);
|
|
149
|
-
await this.
|
|
148
|
+
await this.runApply(env, tfArgs);
|
|
150
149
|
return;
|
|
151
150
|
}
|
|
152
151
|
tfArgs = await this.ensurePlan(env, tfArgs);
|
|
153
|
-
await this.
|
|
152
|
+
await this.runApply(env, tfArgs);
|
|
154
153
|
}
|
|
155
|
-
async
|
|
154
|
+
async runApply(env, tfArgs) {
|
|
156
155
|
logger.info('Deploying resources');
|
|
157
156
|
await this.terraformAdapter.apply(tfArgs, env.ttl);
|
|
158
157
|
logger.info('Activating env (to finish creation)');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agilecustoms/envctl",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "node.js CLI client for manage environments",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"terraform wrapper",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"run-core-init": " cd ../tt-core && terraform init -upgrade -backend-config=key=laxa1986 -reconfigure",
|
|
45
45
|
"run-core-status": " CWD=../tt-core npm run it -- status --verbose",
|
|
46
46
|
"run-core-plan": " CWD=../tt-core npm run it -- plan -out=.terraform/plan",
|
|
47
|
-
"run-core-
|
|
48
|
-
"run-core-
|
|
47
|
+
"run-core-applyp": " CWD=../tt-core npm run it -- apply .terraform/plan",
|
|
48
|
+
"run-core-apply": " CWD=../tt-core npm run it -- apply",
|
|
49
49
|
"run-core-delete": " CWD=../tt-core npm run it -- delete",
|
|
50
50
|
"run-core-destroy": "CWD=../tt-core npm run it -- destroy",
|
|
51
51
|
"run-core-logs": " CWD=../tt-core npm run it -- logs",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
"run-init": "cd ../tt-gitops && terraform init -upgrade -backend-config=key=laxa1986 -reconfigure",
|
|
54
54
|
"run-status": " CWD=../tt-gitops npm run it -- status",
|
|
55
55
|
"run-plan": " AWS_PROFILE=ac-tt-dev-deployer CWD=../tt-gitops npm run it -- plan -var-file=versions.tfvars",
|
|
56
|
-
"run-
|
|
56
|
+
"run-apply": " AWS_PROFILE=ac-tt-dev-deployer CWD=../tt-gitops npm run it -- apply -var-file=versions.tfvars",
|
|
57
57
|
"run-delete": " CWD=../tt-gitops npm run it -- delete",
|
|
58
58
|
"run-destroy": "AWS_PROFILE=ac-tt-dev-destroyer CWD=../tt-gitops npm run it -- destroy -var-file=versions.tfvars",
|
|
59
59
|
"-": "",
|
|
60
60
|
"run-ephemeral-create": " npm run it -- create-ephemeral test",
|
|
61
61
|
"run-ephemeral-init": "cd ../tt-gitops && terraform init -upgrade -backend-config=key=test -reconfigure",
|
|
62
62
|
"run-ephemeral-status": " CWD=../tt-gitops npm run it -- status test",
|
|
63
|
-
"run-ephemeral-
|
|
63
|
+
"run-ephemeral-apply": " CWD=../tt-gitops npm run it -- apply -var-file=versions.tfvars",
|
|
64
64
|
"run-ephemeral-delete": " CWD=../tt-gitops npm run it -- delete --force",
|
|
65
65
|
"run-ephemeral-destroy": "CWD=../tt-gitops npm run it -- destroy --force -var-file=versions.tfvars"
|
|
66
66
|
},
|