1. Centralizing SSH keys management with Vault KV secrets

    TypeScript

    To centralize SSH keys management with Vault using Pulumi, you will create a program that sets up Vault and stores SSH keys as secrets. Below is a detailed walkthrough of the Pulumi code written in TypeScript that accomplishes this.

    Overview

    We will use the vault Pulumi provider to interact with a Vault server. In order for the below code to work, you must have Vault installed and configured as well as the Pulumi Vault provider set up with the necessary credentials and endpoint configuration.

    The Vault KV (Key/Value) secrets engine enables you to store arbitrary secrets natively in Vault. We'll demonstrate this using the vault.kv.Secret resource from the Pulumi Vault provider, which stores an SSH key as a secret within Vault.

    Here's how it works:

    1. Initialize a Vault KV Secret: We'll create a new secret in Vault's KV store. The path ssh_keys/my_key will be the location where we store our SSH key. Replace my_key with a suitable key name (or user name) that identifies the SSH key.

    2. Store the SSH Key: The actual SSH key will be stored in the dataJson field of the secret. This field accepts a JSON string, which means we can store structured data. Here, we'll store an SSH private key, but you should ensure that it's securely generated and the string is escaped correctly to be valid JSON.

    Assumptions:

    • You have already set up and authenticated to your Vault server.
    • You have the necessary permissions to write secrets to the Vault server.

    Below is the TypeScript program:

    import * as pulumi from "@pulumi/pulumi"; import * as vault from "@pulumi/vault"; const sshKeySecret = new vault.kv.Secret("sshKeySecret", { // The path within the Vault KV where the SSH secret is stored path: "ssh_keys/my_key", // The JSON string containing the SSH key data. Be sure to replace the newline characters with `\n` // The data example below should be the actual SSH key contents, properly escaped to be a valid JSON string dataJson: `{ "private_key": "-----BEGIN RSA PRIVATE KEY-----\\n...\n-----END RSA PRIVATE KEY-----", "public_key": "ssh-rsa AAAA...", "key_comment": "user@example.com" }` }); // Export the secret's ID export const secretId = sshKeySecret.id;

    Explanation

    • We import the vault module, which contains the necessary classes and functions to interact with Vault.

    • We create an instance of the vault.kv.Secret resource, which represents a secret stored in Vault's KV store.

    • The path parameter specifies where within the KV store our secret will live. In this case, ssh_keys/my_key could represent a directory structure in the KV store where we keep SSH keys.

    • The dataJson parameter contains the actual data we are storing in the secret. For the SSH key, it's crucial that it is a valid JSON string. In a real-world scenario, you would replace the placeholders with your actual private and public SSH key values, ensuring that you correctly escape JSON-special characters like the newline character (\n).

    • Lastly, we are exporting the ID of our secret so that it can be easily referenced or used by other parts of your Pulumi program.

    Security Considerations

    When dealing with sensitive information such as SSH keys, you must ensure they are handled securely throughout their lifecycle. This includes secure generation, storage, retrieval, and decommissioning.

    Remember, placing real private keys in your source code can be a security risk. Instead, consider using Pulumi's secret management to handle sensitive data or injecting these values at runtime from a secure source.

    Next Steps

    To apply this program using Pulumi, save the code in a file (e.g., index.ts), set up your Pulumi stack, and use the Pulumi CLI to deploy your infrastructure. Ensure that your environment is properly configured to communicate with your Vault server, including setting up the necessary environment variables or configuration settings for authentication.

    If you’re new to Pulumi and would like to learn more about how to set up your Pulumi stack and execute your program, please refer to Pulumi's Getting Started guide, which provides comprehensive steps on running Pulumi programs.