1. Using kubernetes admissionregistration.k8s.io with argoproj.io

    TypeScript

    Kubernetes offers a powerful extension mechanism via admission controllers, which are plugins that intercept requests to the Kubernetes API server before the persistence of the object, but after the request is authenticated and authorized. Among these are webhook admission controllers, allowing you to define your own logic that Kubernetes will call into for certain operations, such as creating or updating resources.

    The admissionregistration.k8s.io API group is particularly dealing with the configuration of these webhooks. Using Pulumi, you can manage these configurations declaratively, ensuring that your admission control logic is versioned and managed just like any other resource in Kubernetes.

    Argo Project (argoproj.io) provides a suite of tools for Kubernetes to run workflows, manage clusters, and do GitOps. Within this suite, for example, Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.

    Let's assume for this exercise that we want to set up a ValidatingWebhookConfiguration that interacts with an Argo CD instance. This Validating Webhook could hypothetically ensure that certain labels or configurations are present on Application resources that Argo CD manages before they are admitted to the Kubernetes cluster.

    Below is the Pulumi code that defines such a ValidatingWebhookConfiguration in TypeScript:

    import * as k8s from "@pulumi/kubernetes"; // Create a kubernetes provider if you are targeting a specific cluster // This is optional and depends on your setup - you might be using context from kubeconfig by default. const provider = new k8s.Provider("provider", { kubeconfig: "<YOUR_KUBECONFIG_CONTENT_HERE>", }); // Define the validation webhook configuration const validatingWebhookConfiguration = new k8s.admissionregistration.v1.ValidatingWebhookConfiguration("argo-validating-webhook", { metadata: { name: "argo-validating-webhook-config", // The name of the webhook configuration }, webhooks: [{ name: "argocd-application-validation.example.com", rules: [ { apiGroups: ["argoproj.io"], apiVersions: ["v1alpha1"], operations: ["CREATE", "UPDATE"], resources: ["applications"], scope: "Namespaced", // This could be Cluster or Namespaced depending on your requirements }, ], clientConfig: { service: { name: "argocd-application-validator", namespace: "argocd", path: "/validate", // `port` needs to be specified if the service is running on a port other than 443 }, // `caBundle` is a base64-encoded certificate; this is usually automatically injected by the service that manages the deployment of this webhook caBundle: "<BASE64-ENCODED_CA_BUNDLE_HERE>", }, sideEffects: "None", // This webhook should have no side effects on other components timeoutSeconds: 5, // Fail the request if it takes more than 5 seconds }], }, { provider }); // Export the name of the webhook configuration so you can easily find it with `kubectl` export const webhookConfigName = validatingWebhookConfiguration.metadata.name;

    In the above code:

    • We import the Pulumi Kubernetes library, which allows us to declare our Kubernetes resources in TypeScript.
    • Optionally, we create a Pulumi Kubernetes provider. This is only required if you need to target a specific cluster that is not the current context set in your kubeconfig. The provider requires the kubeconfig content to connect to the desired cluster.
    • We then define a ValidatingWebhookConfiguration using the @pulumi/kubernetes API. In its specification:
      • We set the name of the webhook and define the rules that determine when this webhook should be called. Here the webhook is configured to intercept CREATE and UPDATE operations on resources of type Application in the argoproj.io API group.
      • We also define the clientConfig which specifies how the Kubernetes API server should contact the webhook server to perform the validation checks. Since this webhook is part of an Argo CD installation, it is in the argocd namespace and would typically be part of the Argo CD service or a dedicated validation service.
      • The sideEffects field is critical, as it denotes whether this operation has side effects on other resources, which helps Kubernetes optimize and can prevent invoking the webhook in some situations when it's not necessary.
      • We set a timeout for the webhook call to prevent the API server from waiting indefinitely.

    Finally, we export the name of the webhook configuration, so we can easily look it up with kubectl.

    Please note that this is a hypothetical example and in a real-world scenario:

    • You would have a proper service created that listens to the path provided in the component (/validate in the example).
    • The caBundle would typically be received from the service that is managing the deployment of your webhooks as a secret or as part of a TLS certificate.
    • Proper Role-Based Access Control (RBAC) bindings will likely be required depending on your cluster setup to allow the API server to invoke the webhook.

    This setup ensures that every Application managed by Argo CD is validated by your custom logic before persistence in the Kubernetes API, integrating custom admission control with the GitOps workflow.