diff --git a/examples/azure-aks-managed-identity/.gitignore b/examples/azure-aks-managed-identity/.gitignore new file mode 100644 index 00000000..7da74da6 --- /dev/null +++ b/examples/azure-aks-managed-identity/.gitignore @@ -0,0 +1,10 @@ +### Scala an JVM +*.class +*.log +.bsp +.scala-build + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +kubeconfig.json diff --git a/examples/azure-aks-managed-identity/Main.scala b/examples/azure-aks-managed-identity/Main.scala new file mode 100644 index 00000000..618f18fe --- /dev/null +++ b/examples/azure-aks-managed-identity/Main.scala @@ -0,0 +1,90 @@ +import besom.* +import besom.api.azurenative +import besom.api.tls + +@main def main = Pulumi.run { + // create a resource group to hold all the resources + val resourceGroup = azurenative.resources.ResourceGroup("resourceGroup") + + // create a private key to use for the cluster's ssh key + val privateKey = tls.PrivateKey( + name = "privateKey", + tls.PrivateKeyArgs( + algorithm = "RSA", + rsaBits = 4096 + ) + ) + + // create a user assigned identity to use for the cluster + val identity = azurenative.managedidentity.UserAssignedIdentity( + name = "identity", + azurenative.managedidentity.UserAssignedIdentityArgs(resourceGroupName = resourceGroup.name) + ) + + // create the cluster + val cluster = azurenative.containerservice.ManagedCluster( + name = "cluster", + azurenative.containerservice.ManagedClusterArgs( + resourceGroupName = resourceGroup.name, + dnsPrefix = "dns-prefix", + enableRBAC = true, + identity = azurenative.containerservice.inputs.ManagedClusterIdentityArgs( + `type` = azurenative.containerservice.enums.ResourceIdentityType.UserAssigned, + userAssignedIdentities = List(identity.id) + ), + agentPoolProfiles = List( + azurenative.containerservice.inputs.ManagedClusterAgentPoolProfileArgs( + count = 1, + vmSize = "Standard_A2_v2", + mode = azurenative.containerservice.enums.AgentPoolMode.System, + name = "agentpool", + osType = azurenative.containerservice.enums.OsType.Linux, + osDiskSizeGB = 30, + `type` = azurenative.containerservice.enums.AgentPoolType.VirtualMachineScaleSets + ) + ), + linuxProfile = azurenative.containerservice.inputs.ContainerServiceLinuxProfileArgs( + adminUsername = "aksuser", + ssh = azurenative.containerservice.inputs.ContainerServiceSshConfigurationArgs( + publicKeys = List( + azurenative.containerservice.inputs.ContainerServiceSshPublicKeyArgs( + keyData = privateKey.publicKeyOpenssh + ) + ) + ) + ) + ) + ) + + // retrieve the admin credentials which contain the kubeconfig + val adminCredentials = azurenative.containerservice + .listManagedClusterUserCredentials( + azurenative.containerservice.ListManagedClusterUserCredentialsArgs( + resourceName = cluster.name, + resourceGroupName = resourceGroup.name + ) + ) + + // grant the 'contributor' role to the identity on the resource group + val assignment = azurenative.authorization.RoleAssignment( + name = "roleAssignment", + azurenative.authorization.RoleAssignmentArgs( + principalId = identity.principalId, + principalType = azurenative.authorization.enums.PrincipalType.ServicePrincipal, + roleDefinitionId = "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", + scope = resourceGroup.id + ) + ) + + val kubeconfig = adminCredentials.kubeconfigs + .map(_.head.value) + + // export the kubeconfig + Stack(assignment).exports( + kubeconfig = kubeconfig.map(base64.decode) + ) +} + +object base64: + def decode(v: String): String = + new String(java.util.Base64.getDecoder.decode(v.getBytes("UTF-8")), java.nio.charset.StandardCharsets.UTF_8) diff --git a/examples/azure-aks-managed-identity/Pulumi.yaml b/examples/azure-aks-managed-identity/Pulumi.yaml new file mode 100644 index 00000000..ba966407 --- /dev/null +++ b/examples/azure-aks-managed-identity/Pulumi.yaml @@ -0,0 +1,3 @@ +name: azure-aks-managed-identity +description: Azure AKS cluster example +runtime: scala diff --git a/examples/azure-aks-managed-identity/README.md b/examples/azure-aks-managed-identity/README.md new file mode 100644 index 00000000..606b763c --- /dev/null +++ b/examples/azure-aks-managed-identity/README.md @@ -0,0 +1,59 @@ +# Azure Kubernetes Service (AKS) Cluster using the native Azure Provider + +This example deploys an AKS cluster, creates an Azure User Assigned Managed Identity, and sets credentials to manage +access to the cluster. + +## Deploying the App + +To deploy your infrastructure, follow the below steps. + +### Prerequisites + +1. [Install Pulumi](https://www.pulumi.com/docs/get-started/install/) +2. [Configure Azure Credentials](https://www.pulumi.com/docs/intro/cloud-providers/azure/setup/) + +### Steps + +After [cloning](https://github.com/pulumi/examples#checking-out-a-single-example) this repo, from this working +directory, run these commands: + +1. Create a new stack, which is an isolated deployment target for this example: + + ```bash + $ pulumi stack init dev + ``` + +2. Set the Azure region location to use: + + ``` + $ pulumi config set azure-native:location westus2 + ``` + +3. Stand up the cluster by invoking pulumi + ```bash + $ pulumi up + ``` + +4. After 3-4 minutes, your cluster will be ready, and the kubeconfig YAML you'll use to connect to the cluster will be + available as an [Output](https://www.pulumi.com/docs/concepts/inputs-outputs/#outputs). You can save this kubeconfig + to a file like so: + + ```bash + $ pulumi stack output kubeconfig --show-secrets > kubeconfig.yaml + ``` + + Once you have this file in hand, you can interact with your new cluster as usual via `kubectl`: + + ```bash + $ KUBECONFIG=./kubeconfig.yaml kubectl get nodes + ``` + +5. From there, feel free to experiment. Simply making edits and running `pulumi up` will incrementally update your + stack. + +6. Once you've finished experimenting, tear down your stack's resources by destroying and removing it: + + ```bash + $ pulumi destroy --yes + $ pulumi stack rm --yes + ``` \ No newline at end of file diff --git a/examples/azure-aks-managed-identity/project.scala b/examples/azure-aks-managed-identity/project.scala new file mode 100644 index 00000000..2194d379 --- /dev/null +++ b/examples/azure-aks-managed-identity/project.scala @@ -0,0 +1,9 @@ +//> using scala "3.3.1" +//> using options -Werror -Wunused:all -Wvalue-discard -Wnonunit-statement +//> using plugin "org.virtuslab::besom-compiler-plugin:0.3.0-SNAPSHOT" + +//> using dep "org.virtuslab::besom-core:0.3.0-SNAPSHOT" +//> using dep "org.virtuslab::besom-azure-native:2.36.0-core.0.3-SNAPSHOT" +//> using dep "org.virtuslab::besom-tls:5.0.2-core.0.3-SNAPSHOT" + +//> using repository sonatype:snapshots