Hi everyone,
In my last article, "Not only dynamoDb migration/seed scripting", I provided a solution how to manage migration/seed scripting and I proposed to run it by CLI command. If you haven't read it yet, you can find it here. In this article, I’d like to share why you might want to build your own CLI and what types of commands it could contain. However, I will not teach you how to build a CLI from scratch here, and I assume you are already familiar with NodeJS and TypeScript. Instead, this article focuses on the reasons for creating your own CLI and the types of commands it could include. The source code of CLI you will find here and to run it you can use this command
npx dev-to-proto-cli
Configure
The first command I’d like to share is configure
. Imagine you are working on a project that follows a multi-services architecture, with at least three services plus a front-end. Each service has its own configuration file for four environments and might have the following structure:
service/environments
├── environment.development.yml/.env.dev
├── environment.tst.yml/.env.tst
├── environment.acc.yml/.env.acc
└── environment.yml/.env.prd
The file extension does not matter.
I see some disadvantages with this approach:
- If you have repeatable configuration properties for multiple services, you need to copy and paste them into each service.
- Maintenance becomes too complicated. Some properties may have the same value but different names across services.
- The release tag depends not only on the codebase but also on the configuration.
This is where the configure
command comes into play.
Instead of keeping the configuration in each service, you can store it elsewhere, such as in another repository, a secret manager, an S3 bucket, or any other source. I’ve created two examples of configuration: one stored in a GitHub Gist and another in a Bitbucket Snippet. Imagine that GitHub Gist is dev env and Bitbucket is tst
The configuration structure is a simple nested format. The top-level keys represent global settings for all services, while the nested sections contain specific properties for each service. The subsections can override or extend the global settings. All properties are in one file, and maintaining it is not difficult.
It depends on where you decide to keep it. In my team, we store it in a separate repository and use tags or branches for different scenarios.
log_level: INFO
region: us-east-1
foo:
log_level: DEBUG
region: us-west-1
foo_prop_1: 1
foo_prop_2: 2
bar:
log_level: WARN
region: us-west-2
baz:
log_level: ERROR
How to use
I assume you have a similar line of code in your GitHub Actions or Bitbucket Pipeline to create an env files depending on env.
cp evnironment.${ENV}.yml environment.yml
Using your own CLI, you would have something like this:
npx dev-to-proto-cli configure --extension=env --service=foo --env=dev
It will generate either a config.yml
or .env
file with all root properties and the properties dependent on a service.
Other commands
In our team, we aim to create commands for a wide range of scenarios. Here is a brief overview of some of them:
- Clean the Database: To clean a DynamoDB table or all tables, we use the clean-db command. The command looks like this:
npx dev-to-proto-cli --profile=dev --region=us-west-1 --provider=sso
If you run it and provide all credentials, it will clean the chosen tables. Please use it carefully.
NOTE: The clean-db command is useful only if your dynamoDb table is NOT attached to a custom VPC.
- To get an overview of our tests, we use a Bitbucket pipeline to run daily tests. While you can view the results directly in the pipeline, I find this approach inconvenient for collecting statistics over a longer period, such as the last 30 days. For instance, comparing all failed tests or identifying flaky tests becomes impossible without manual effort or paid add-ons.
To address this, I created another CLI command that uses the public Bitbucket REST API to collect and analyze all test statistics. The command looks like this:
npx @own-cli statistic --start=2024-11-11 --end=2024-11-18
I’ve described only three of the commands we’ve implemented. Please feel free to share your ideas in the comments. Any feedback or kudos would be greatly appreciated!
In my next article, I'll show you how to build an ACL with minimal effort. Subscribe to stay tuned!
Top comments (0)