1. Using Service Principal for Azure Kubernetes Service authentication

    TypeScript

    When you're working with Azure Kubernetes Service (AKS) and want to manage it programmatically or from within a CI/CD pipeline, you'll need to authenticate your applications or tools against Azure. One secure way of doing this is by using an Azure Active Directory (AD) service principal. A service principal acts like a "user identity" (username and password or certificate) for an application rather than a person.

    Here's an example program written in TypeScript using Pulumi to create a service principal and then use it to authenticate an AKS cluster.

    Before we dive into the code, let's cover the steps we'll need to take:

    1. Create an Azure AD application: This is an identity created for use with applications, hosted services, and automated tools to access Azure resources. This will act as the foundation for our service principal.
    2. Create a service principal for the Azure AD application: This will allow our application to login and access Azure resources within the permissions and roles we assign to it.
    3. Assign a role to the service principal: This defines the permissions that the application has in Azure. For AKS, the service principal requires contributor rights to work effectively.
    4. Create an AKS cluster using the service principal for authentication: The AKS cluster will be created with the service principal as its identity. This allows AKS to manage other Azure resources like load balancers, disk volumes, and container registries under the context of the service principal.

    Now, let's go through the code that performs these steps:

    import * as azuread from "@pulumi/azuread"; import * as azure from "@pulumi/azure-native"; // Create an Azure AD application for AKS const app = new azuread.Application("aksApp", { displayName: "aksApp", }); // Create a service principal for the Azure AD application const sp = new azuread.ServicePrincipal("aksSp", { applicationId: app.applicationId, }); // Create a password for the service principal const spPassword = new azuread.ServicePrincipalPassword("aksSpPassword", { servicePrincipalId: sp.id, endDate: "2099-01-01T00:00:00Z", // Set to a date far in the future }); // Assign a role to the service principal (Contributor rights in this case) const roleAssignment = new azure.authorization.RoleAssignment("aksSpRoleAssignment", { principalId: sp.id, roleDefinitionName: "Contributor", scope: "/subscriptions/<Your-Subscription-ID>", // Replace with your actual subscription ID }); // Now we'll create the AKS cluster using the details of the service principal for authentication const aksCluster = new azure.containerservice.ManagedCluster("aksCluster", { resourceGroupName: "<Your-Resource-Group>", // Replace with your actual resource group name location: "WestUS", // Replace with the desired Azure region agentPoolProfiles: [{ count: 1, maxPods: 110, mode: "System", name: "agentpool", osDiskSizeGB: 30, osType: "Linux", type: "VirtualMachineScaleSets", vmSize: "Standard_DS2_v2", }], dnsPrefix: "aksk8s", linuxProfile: { adminUsername: "azureuser", ssh: { keys: [{ keyData: "<Your-SSH-RSA-public-key>", // Replace with your actual public SSH key }], }, }, servicePrincipalProfile: { clientId: app.applicationId, secret: spPassword.value, }, }); export const kubeConfig = aksCluster.kubeConfig;

    Please ensure to replace placeholders such as <Your-Subscription-ID>, <Your-Resource-Group>, and <Your-SSH-RSA-public-key> with actual values before running the program.

    In this program:

    • We first create an Azure AD application using azuread.Application. This represents our application's identity.
    • We then create a service principal tied to our Azure AD application using azuread.ServicePrincipal.
    • A password is created for the service principal using azuread.ServicePrincipalPassword which is required to authenticate the managed cluster against Azure.
    • We assign the "Contributor" role to the service principal with azure.authorization.RoleAssignment to give it proper access rights. Change the scope to your subscription or particular resource.
    • Finally, we create the AKS cluster with azure.containerservice.ManagedCluster, passing in the servicePrincipalProfile which includes the clientId and secret we created earlier.

    This sets up AKS to use the service principal for cloud resources that it needs to manage. The kubeConfig is exported so that you can use it to connect to your Kubernetes cluster using kubectl outside of Pulumi.

    Note that you'll need to install the Pulumi Azure AD (@pulumi/azuread) and Azure (@pulumi/azure-native) packages if you haven't already:

    npm install @pulumi/azuread @pulumi/azure-native

    Ensure to replace placeholders with actual valid Azure details before running your Pulumi program. Remember, managing cloud resources with Pulumi is declarative; the actual infrastructure is created, updated, or deleted when you run pulumi up.