In an earlier
article we described the thought process and architecture for setting up an API Store that will serve as the shared service platform providing developers access to most common and frequently required functionalities being exposed in the form of consumable APIs. The API store needs to continue to evolve and provide more and more implementations to become effective and help reduce the turnaround times for new custom applications.
While working for one of our recent engagements, there became a need for us to manage the admin keys for Linux VMs as part of ongoing infrastructure support. These keys were being used by the admins on the client side and by the support team to do the routine maintenance and admin tasks. In the current setups, these keys were being manually generated and rotated based on client requests. In an environment with a small footprint this may be a feasible task however with bigger footprints, this becomes an overhead for the operations team to handle and address either on an as-needed basis or on a scheduled basis based on the client policies. Needless to say a certain level of aquaintance and understanding of Linux systems is needed to complete the admin tasks.
Being a pro Microsoft and Windows team, this presented a unique problem to tackle which is what drove us to find a tangible solution to the continous problem. We went the automation route and decided to implement a solution which takes care of key generation and rotation which involved creating APIs for a) generation of SSH Keys and b) storing and fetching them from key vaults and then scheduling a rotation using Azure Automation. In this article, we will focus on one part of this solution which is creating the API to generate the SSH keys.
With that context, let's get started with writing few lines of code for our API. This functionality is going to rely on the
SSHKeyGenerator library.
This provides us with a native .NET and .NET Core library for creating SSH RSA keys suitable for use with SSH clients and Git+SSH authentication. It generates both kinds of keys – private and public, and these keys can be used for any Linux based Azure VM.
Once we have the package installed and available in our project, we will create a new function class file GenerateSSHKeys.cs and add a GET function called GenerateNewSSHKeys. This function will expect a "VMName" (virtual machine name) query parameter to be passed which will be used as the input for generating the SSH Public key. This new function is also using the custom log analytics API that we created in our earlier
article for logging the actions and errors in the finally block. We have also defined a class entity for capturing the generated SSH Public and Private Keys.
GenerateSSHKeys.cs
That's it! The function code is ready and can now be published to the Function App that is created in the Azure Subscription. Once the new function is published and available, we will need to add this to the API Management instance that we have created. The steps to publish and add function to the API Management instance are documented in this
article. The actual endpoint to end users will be made available through Azure API Management once it is configured but for our test, let's run it directly from the Azure Portal using the Azure Functions Test Run feature.
Azure Portal Navigation: Function App => Functions => GenerateNewSSHKeys => Code + Test => Test/Run
So this simple API implementation can now be integrated with any automation setup where SSH key generation is to be done dynamically. This simple implementation is really useful and can be utilized in multiple automations like key rotations, generation of new random keys during VM provisioining etc. Being an API based implementation means that it can pretty much be invoked in any language and in any functionality. It also eliminates the need for application developers and support engineers to have contextualized Linux knowledge to generate and rotate keys.
The complete code for this API is available at our
GitHub Repository along with a few other APIs that can be generically used in any API Store implementations.
Happy Coding!