1. Using kubernetes argoproj.io with secrets.hashicorp.com

    TypeScript

    In this example, we're going to integrate Argo CD, a declarative, GitOps continuous delivery tool for Kubernetes, with HashiCorp Vault, a service used to secure, store, and tightly control access to tokens, passwords, certificates, API keys, and other secrets in modern computing.

    Here's what we want to accomplish:

    1. Deploy Argo CD to a Kubernetes cluster.
    2. Configure Argo CD to pull configuration from a Git repository.
    3. Use HashiCorp Vault to store sensitive information.
    4. Configure Argo CD to use Vault to inject secrets into Kubernetes deployments.

    The following Pulumi program written in TypeScript will perform these actions. Note that Pulumi supports programming against Kubernetes and HashiCorp Vault, offering us a way to automate and manage complex deployments like this easily.

    Make sure that you have both the @pulumi/kubernetes and @pulumi/vault packages installed.

    1. Begin by setting up Argo CD on Kubernetes. Since we are focusing on the integration with Vault, we'll assume that Argo CD is already deployed. Pulumi doesn't currently have pre-built components for Argo CD, so that would be done using regular Kubernetes manifests or helm charts.
    2. Set up a Vault instance and configure its Kubernetes authentication method, which allows pods to authenticate with Vault using their service account token.
    3. Create Vault policies and attach them to Kubernetes service account names, allowing you to control which pods can access different secrets within Vault.
    4. Configure an Argo CD Application to include an annotation that references a Vault secret path. Argo CD can use a plugin such as argocd-vault-plugin to interpret this annotation and inject the referenced secret at deploy time.

    Below you will find the Pulumi TypeScript program that sets up Vault and configures an Argo CD application to use Vault secrets. For brevity, the example assumes you have suitable permissions:

    import * as k8s from '@pulumi/kubernetes'; import * as vault from '@pulumi/vault'; // Provide the Kubernetes Provider to interact with the cluster where Argo CD is installed. const k8sProvider = new k8s.Provider('k8s-provider', { /* ... your cluster's config ... */ }); // Configure the Vault provider to interact with your Vault instance. const vaultProvider = new vault.Provider('vault-provider', { /* ... your vault's config ... */ }); // Demonstration purposes: the Vault policy document. // Ideally, this policy should be tightly scoped to the needs of your application. const vaultPolicyDocument = `path "secret/data/*" { capabilities = ["read"] }`; // Create a Vault policy that dictates what secrets can be accessed and how. const argoCDVaultPolicy = new vault.Policy('argocd-vault-policy', { name: 'argocd-vault-policy', policy: vaultPolicyDocument, }, { provider: vaultProvider }); // Assuming you have a service account for Argo CD, create a Kubernetes authentication role in Vault. const vaultAuthRole = new vault.kubernetes.SecretBackendRole('argocd-vault-auth-role', { backend: 'kubernetes', // This assumes you've set up the Kubernetes auth method at the path 'kubernetes' in Vault. boundServiceAccountNames: ['argocd'], // Name of the Argo CD service account. boundServiceAccountNamespaces: ['argocd'], // Namespace of the Argo CD service account. policies: [argoCDVaultPolicy.name], ttl: '1h', }, { provider: vaultProvider }); // An example ConfigMap source for Argo CD referencing a secret in Vault. // In a real-world scenario, you would have an Argo CD app pointing at a Git repo. const appConfigMap = new k8s.core.v1.ConfigMap('app-config', { metadata: { namespace: 'argocd', annotations: { // This annotation signals Argo CD to fetch the secret from Vault. // The actual mechanism to retrieve the secret would be through an Argo CD plugin like 'argocd-vault-plugin'. 'avp.kubernetes.io/path': 'secret/data/myapp/config', }, }, data: { // Placeholder data key. The actual data is expected to be populated by Argo CD from Vault secret. 'config.yaml': `{}`, }, }, { provider: k8sProvider }); // Export the name of the Vault Auth Role export const vaultAuthRoleName = vaultAuthRole.name;

    The ConfigMap is annotated in a way that Argo CD's plugin can recognize and fetch the appropriate secrets from Vault.

    Keep in mind that this program assumes you have already configured your Kubernetes cluster and Vault provider within Pulumi. You'd need to replace the placeholders for the provider configurations with your actual cluster and Vault configuration details.

    Also, remember that managing secrets and authentication rightly requires a deep understanding of both security implications and the specific tools involved. Always follow the best security practices, such as the principle of least privilege, when working with IAM roles, policies, and secrets.