Building a CLI for Your Platform, Part 1 - Introduction
Welcome to the first issue in a several-part series on building a command-line interface (CLI) tool for an internal platform. This is something I've been working on for the better part of a year now, and in speaking to my peers in industry (especially within the CNCF's Platforms Working Group) there's been a lot of interest in my experience building it and growing its adoption. It's a proprietary CLI and I can't share the code, but I do think it's worth sharing some general knowledge on the process of building this sort of tool for an internal platform, particularly because much of what I've learned while doing so has surprised me.
I should probably define "internal platform" before I get any further. I use this term broadly to mean the software and cloud computing resources that are provided and maintained within an organization. This could mean AWS services like S3 or Secrets Manager, it could mean Kubernetes clusters, it could mean database resources, it could mean GitHub, it could mean a server in a closet, anything. Typically, members of the organization build higher-level abstractions (user-facing SaaS applications, for example) for example) on these resources in order to advance their business goals. Some of those higher-level abstractions can usually also be considered part of the platform. See the CNCF Platforms Whitepaper and the Platform Engineering Maturity Model for more details - I contributed to the latter.
I'm being intentionally nebulous here. Some people think that "internal platform" means "internal developer portal" (IDP) specifically (that is, a tool like Backstage), and that if you don't have an IDP you don't have a platform - I disagree strongly with that take. I think it was Abby Bangser who said "everyone has a platform, even if they don't think of it as a platform". I agree with that framing.
So, if an internal platform is the software resources, cloud computing resources, etc, that are available to members of an organization, a platform CLI is a tool - an abstraction layer - that enables access to and use of those resources from the command-line (from an individual person's computer). Again, I'm being intentionally vague here - the goals of a platform CLI may vary wildly from one organization to another, because organizations can vary wildly from one another.
That makes for a good segue into one of the most significant things I've learned in building this: a CLI is personal. It's specific to your organization, and should reflect the idiosyncrasies and conventions of your organization, but it's also personal in a "specific to a person" sense too.
I work in a SaaS environment - we run applications that expose APIs. Applications, and individual users with API access, can connect to those APIs programmatically to query for resources, create/update/delete resources, and so on. An API (an application exposing an API) is something that you run, on your (owned or rented) hardware, and which users visit. You can update the code when you need to, and you have visibility into usage in a centralized way (via application logs and/or telemetry).
A CLI, on the other hand, is something that you make available (rather than "run"), and which users run themselves, on their hardware. You have much less ability to update the code — while you can make a new version available, you can't guarantee that all of your users will update to that new version. By distributing the CLI to your users, you're also providing them with the code itself - savvy users are able to inspect/decompile that code (in a general sense - some toolchains make this easier, some harder) and tweak it in ways you don't expect.
A CLI is also something that a user runs on their machine and that makes it very personal indeed. People can be very particular about their command line. An organization might provision developer machines with certain tools as part of onboarding, and there might be strong conventions around application use in the organization ("we use Intellij IDEA for Java", "we use Visual Studio Code for Python", etc), but people in my experience love to personalize their command line environments. Mine is personalized enough that I have a dedicated git repository for it, so that I can more easily transfer that customization to new computers.
All this is to say, in building a CLI for an internal platform, there's a lot more to think about than just "does it work". There are social/sociotechnical aspects to consider around the conventions that exist in the organization, the proficiency/comfort of users with regards to CLIs, and the tooling/distribution mechanisms available.
I'll touch on all of these things in future issues in this Platform CLI series, along with some thoughts on technical implementation (packaging/installation, authentication, and documentation are all likely to have a dedicated issue). If there are other aspects of platform CLIs that you're interested in, please do let me know. I'd be glad to cover other areas of the process.