@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 CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  ```shell
9
9
  terraform init -backend-config=key=laxa1986
10
- envctl deploy -var-file=versions.tfvars -var="log_level=debug"
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
- There are two main use cases:
47
- 1. create an environment from CI (mainly ephemeral envs)
48
- 2. create env from a dev machine
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
@@ -110,7 +110,7 @@ export class Cli {
110
110
  });
111
111
  });
112
112
  }
113
- getKind() {
113
+ getDir() {
114
114
  return path.basename(process.cwd());
115
115
  }
116
116
  async writeInTmpFile(stream, fileName) {
@@ -1,6 +1,5 @@
1
1
  export const _keys = {
2
2
  FORCE: 'Force deletion without confirmation',
3
3
  KEY: 'Environment name/identifier - taken from remote stake key, must be unique for a given customer',
4
- KIND: 'Environment kind',
5
4
  PROFILE: 'Profile to use'
6
5
  };
@@ -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 deploy(program, configService, envService) {
5
+ export function apply(program, configService, envService) {
6
6
  program
7
- .command('deploy')
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.deploy(tfArgs);
15
+ await envService.apply(tfArgs);
16
16
  }));
17
17
  }
@@ -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';
@@ -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 deploy command: if you plan to deploy env with envctl deploy,'
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, deploy, destroy, logs, plan, status } from './commands/index.js';
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.kind) {
31
- const kind = this.cli.getKind();
32
- if (env.kind !== kind) {
33
- logger.warn(`Env ${key} kind (dir-name): ${env.kind} - looks like this env was deployed from a different directory`);
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
- checkKind(env) {
48
+ checkDir(env) {
49
49
  if (env.ephemeral)
50
50
  return;
51
- if (env.kind) {
52
- const kind = this.cli.getKind();
53
- if (kind !== env.kind) {
54
- throw new KnownException(`Env ${env.key} kind (dir-name): ${env.kind} - make sure you run this command from the same directory`);
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.checkKind(env);
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 deploy(tfArgs) {
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 kind = this.cli.getKind();
120
- logger.info(`Inferred kind from directory name: ${kind}`);
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.runDeploy(env, tfArgs);
125
+ await this.runApply(env, tfArgs);
127
126
  return;
128
127
  }
129
- this.checkKind(env);
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.runDeploy(env, tfArgs);
148
+ await this.runApply(env, tfArgs);
150
149
  return;
151
150
  }
152
151
  tfArgs = await this.ensurePlan(env, tfArgs);
153
- await this.runDeploy(env, tfArgs);
152
+ await this.runApply(env, tfArgs);
154
153
  }
155
- async runDeploy(env, tfArgs) {
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.16.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-deployp": "CWD=../tt-core npm run it -- deploy .terraform/plan",
48
- "run-core-deploy": " CWD=../tt-core npm run it -- deploy",
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-deploy": " AWS_PROFILE=ac-tt-dev-deployer CWD=../tt-gitops npm run it -- deploy -var-file=versions.tfvars",
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-deploy": " CWD=../tt-gitops npm run it -- deploy -var-file=versions.tfvars",
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
  },