From b41cdd2cc78254629c953421fd811de4e51c7b22 Mon Sep 17 00:00:00 2001 From: Gleb Boushev Date: Thu, 21 Feb 2019 11:41:59 +0300 Subject: [PATCH 1/3] azure aks example --- azure-py-aks/.gitignore | 1 + azure-py-aks/Pulumi.yaml | 3 + azure-py-aks/README.md | 67 ++++++++++++++++++ azure-py-aks/__main__.py | 125 ++++++++++++++++++++++++++++++++++ azure-py-aks/requirements.txt | 2 + 5 files changed, 198 insertions(+) create mode 100644 azure-py-aks/.gitignore create mode 100644 azure-py-aks/Pulumi.yaml create mode 100644 azure-py-aks/README.md create mode 100644 azure-py-aks/__main__.py create mode 100644 azure-py-aks/requirements.txt diff --git a/azure-py-aks/.gitignore b/azure-py-aks/.gitignore new file mode 100644 index 000000000..0d20b6487 --- /dev/null +++ b/azure-py-aks/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/azure-py-aks/Pulumi.yaml b/azure-py-aks/Pulumi.yaml new file mode 100644 index 000000000..0deeba9f1 --- /dev/null +++ b/azure-py-aks/Pulumi.yaml @@ -0,0 +1,3 @@ +name: aks +runtime: python +description: A minimal Azure Python Pulumi program diff --git a/azure-py-aks/README.md b/azure-py-aks/README.md new file mode 100644 index 000000000..aaa37365c --- /dev/null +++ b/azure-py-aks/README.md @@ -0,0 +1,67 @@ +[![Deploy](https://get.pulumi.com/new/button.svg)](https://app.pulumi.com/new) + +# Azure Kubernetes Service (AKS) Cluster + +This example deploys an AKS cluster, virtual network and Azure Container Registry and grants AKS permissions to access and manage those. + +## Deploying the App + +To deploy your infrastructure, follow the below steps. + +### Prerequisites + +1. [Install Pulumi](https://pulumi.io/install) +2. [Install Python 3.6](https://www.python.org/downloads/) +3. [Configure Azure Credentials](https://pulumi.io/install/azure.html) +4. [Generate SSH Key](https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key) + +### Steps + +After cloning this repo, from this working directory, run these commands: + +1. Install the required Python packages packages: + + ```bash + $ pip install -r requirements.txt + ``` + +2. Create a new stack, which is an isolated deployment target for this example: + + ```bash + $ pulumi stack init + ``` + +3. Set the configuration variables for this program, they have default values, so you dont have to do that: + + ```bash + $ pulumi config set prefix all_resources_will_be_prefixed_with_this_value + $ pulumi config set password service_principal_password + $ pulumi config set sshkey your_public_ssh_key + $ pulumi config set location any_valid_azure_location_for_aks + ``` + +4. Stand up the AKS cluster: + + ```bash + $ pulumi up + ``` + +5. After 10-15 minutes, your cluster will be ready, and the kubeconfig YAML you'll use to connect to the cluster will be available as an output. You can save this kubeconfig to a file like so: + + ```bash + $ pulumi stack output kubeconfig >kubeconfig.json + ``` + + Once you have this file in hand, you can interact with your new cluster as usual via `kubectl`: + + ```bash + $ KUBECONFIG=./kubeconfig.json kubectl get nodes + ``` +6. From there, feel free to experiment. Simply making edits and running `pulumi up` will incrementally update your stack. + +7. Once you've finished experimenting, tear down your stack's resources by destroying and removing it: + + ```bash + $ pulumi destroy --yes + $ pulumi stack rm --yes + ``` diff --git a/azure-py-aks/__main__.py b/azure-py-aks/__main__.py new file mode 100644 index 000000000..d40193625 --- /dev/null +++ b/azure-py-aks/__main__.py @@ -0,0 +1,125 @@ +import pulumi +from pulumi import ResourceOptions +from pulumi_azure.core import ResourceGroup +from pulumi_azure.role import Assignment +from pulumi_azure.ad import Application, ServicePrincipal, ServicePrincipalPassword +from pulumi_azure.containerservice import KubernetesCluster, Registry +from pulumi_azure.network import VirtualNetwork, Subnet + +config = pulumi.Config('azure-py-kubernetes') +PREFIX = config.get('prefix') or 'replaceme' +PASSWORD = config.get('password') or 'DEf34tg!rg35y#F23' +SSHKEY = config.get('sshkey') or 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxinIAIDDCradZPAgX5GzBLv00u4rigOLUbU00E44FrfMTqu5wXiejJ4ycSb1bI+//ZNgaB2UYRbPL7A9OUKY+K4sX5O84Q6DPMjo/90IANHVTLf3xTaSc7hpvXOtIjJTJeiamxClgnTAcR55RV/j9/Wptxa8GGcRmRCcSmJUkx5AZTFI+s8aF0W3aeHHRw7TxNKBuwrX7FDcHyGKvdkFg4OP863Xe5hp5ql1C3XibmCOp1CMPIU2hCmGOy1LGbOf/Pa+QKAdtUSrPNK/jBWvPWo0k02Ii0JtMAdlpVqnJc3czNIp5gEqZCRCGEdkb/kZnJiMRZhmLBYnC8tiMxvZj core@k8s' +LOCATION = config.get('location') or 'westeurope' + +# create Azure AD Application for AKS +app = Application( + 'aks-app', + name=PREFIX + 'aks-app' +) + +# create service principal for the application so AKS can act on behalf of the application +sp = ServicePrincipal( + 'aks-sp', + application_id=app.application_id +) + +# create service principal password +sppwd = ServicePrincipalPassword( + 'aks-sp-pwd', + service_principal_id=sp.id, + end_date='2025-01-01T01:02:03Z', + value=PASSWORD +) + +rg = ResourceGroup( + 'rg', + name=PREFIX + 'rg', + location=LOCATION +) + +vnet = VirtualNetwork( + 'vnet', + name=PREFIX + 'vnet', + location=rg.location, + resource_group_name=rg.name, + address_spaces=['10.0.0.0/8'] +) + +subnet = Subnet( + 'subnet', + name=PREFIX + 'subnet', + resource_group_name=rg.name, + address_prefix='10.0.0.0/23', + virtual_network_name=vnet.name +) + +# create Azure Container Registry to store images in +acr = Registry( + 'acr', + name=PREFIX + 'acr', + location=rg.location, + resource_group_name=rg.name, + sku="basic" +) + +# assignments are needed for AKS to be able to interact with those resources +acr_assignment = Assignment( + 'acr-permissions', + principal_id=sp.id, + role_definition_name='AcrPull', + scope=acr.id +) + +subnet_assignment = Assignment( + 'subnet-permissions', + principal_id=sp.id, + role_definition_name='Network Contributor', + scope=subnet.id +) + +aks = KubernetesCluster( + 'aks', + name=PREFIX + 'aks', + location=rg.location, + resource_group_name=rg.name, + kubernetes_version="1.12.5", + dns_prefix="dns", + agent_pool_profile=( + { + "name": "type1", + "count": 2, + "vmSize": "Standard_B2ms", + "osType": "Linux", + "maxPods": 110, + "vnet_subnet_id": subnet.id + } + ), + linux_profile=( + { + "adminUsername": "azureuser", + "ssh_key": [ + { + "keyData": SSHKEY + } + ] + } + ), + service_principal={ + "clientId": app.application_id, + "clientSecret": sppwd.value + }, + role_based_access_control={ + "enabled": "true" + }, + network_profile=( + { + "networkPlugin": "azure", + "serviceCidr": "10.10.0.0/16", + "dns_service_ip": "10.10.0.10", + "dockerBridgeCidr": "172.17.0.1/16" + } + ), __opts__=ResourceOptions(depends_on=[acr_assignment, subnet_assignment]) +) + +pulumi.export('kubeconfig', aks.kube_config_raw) diff --git a/azure-py-aks/requirements.txt b/azure-py-aks/requirements.txt new file mode 100644 index 000000000..64b8736b3 --- /dev/null +++ b/azure-py-aks/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=0.16.4 +pulumi_azure>=0.16.4 From 5df349a0eec0cb5ed4198f05badfd543d62b9679 Mon Sep 17 00:00:00 2001 From: Gleb Boushev Date: Thu, 21 Feb 2019 11:49:58 +0300 Subject: [PATCH 2/3] minor fix --- azure-py-aks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-py-aks/README.md b/azure-py-aks/README.md index aaa37365c..d3a72f8d2 100644 --- a/azure-py-aks/README.md +++ b/azure-py-aks/README.md @@ -49,7 +49,7 @@ After cloning this repo, from this working directory, run these commands: 5. After 10-15 minutes, your cluster will be ready, and the kubeconfig YAML you'll use to connect to the cluster will be available as an output. You can save this kubeconfig to a file like so: ```bash - $ pulumi stack output kubeconfig >kubeconfig.json + $ pulumi stack output kubeconfig >kubeconfig.yaml ``` Once you have this file in hand, you can interact with your new cluster as usual via `kubectl`: From a2ec472f010bceedf67cbace209c2fa9402749e8 Mon Sep 17 00:00:00 2001 From: Gleb Boushev Date: Tue, 5 Mar 2019 20:19:18 +0300 Subject: [PATCH 3/3] minor fixes --- azure-py-aks/Pulumi.yaml | 2 +- azure-py-aks/README.md | 9 +++++---- azure-py-aks/__main__.py | 12 ++++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/azure-py-aks/Pulumi.yaml b/azure-py-aks/Pulumi.yaml index 0deeba9f1..b5aaae153 100644 --- a/azure-py-aks/Pulumi.yaml +++ b/azure-py-aks/Pulumi.yaml @@ -1,3 +1,3 @@ -name: aks +name: azure-py-aks runtime: python description: A minimal Azure Python Pulumi program diff --git a/azure-py-aks/README.md b/azure-py-aks/README.md index d3a72f8d2..1d064ad8d 100644 --- a/azure-py-aks/README.md +++ b/azure-py-aks/README.md @@ -31,12 +31,13 @@ After cloning this repo, from this working directory, run these commands: $ pulumi stack init ``` -3. Set the configuration variables for this program, they have default values, so you dont have to do that: +3. Set the configuration variables for this program: ```bash $ pulumi config set prefix all_resources_will_be_prefixed_with_this_value $ pulumi config set password service_principal_password - $ pulumi config set sshkey your_public_ssh_key + $ pulumi config set sshkey < ~/.ssh/id_rsa.pub + $ # this has a default value, so you can skip it $ pulumi config set location any_valid_azure_location_for_aks ``` @@ -49,13 +50,13 @@ After cloning this repo, from this working directory, run these commands: 5. After 10-15 minutes, your cluster will be ready, and the kubeconfig YAML you'll use to connect to the cluster will be available as an output. You can save this kubeconfig to a file like so: ```bash - $ pulumi stack output kubeconfig >kubeconfig.yaml + $ pulumi stack output kubeconfig > kubeconfig.yaml ``` Once you have this file in hand, you can interact with your new cluster as usual via `kubectl`: ```bash - $ KUBECONFIG=./kubeconfig.json kubectl get nodes + $ KUBECONFIG=./kubeconfig.yaml kubectl get nodes ``` 6. From there, feel free to experiment. Simply making edits and running `pulumi up` will incrementally update your stack. diff --git a/azure-py-aks/__main__.py b/azure-py-aks/__main__.py index d40193625..bfe584dc5 100644 --- a/azure-py-aks/__main__.py +++ b/azure-py-aks/__main__.py @@ -6,11 +6,11 @@ from pulumi_azure.containerservice import KubernetesCluster, Registry from pulumi_azure.network import VirtualNetwork, Subnet -config = pulumi.Config('azure-py-kubernetes') -PREFIX = config.get('prefix') or 'replaceme' -PASSWORD = config.get('password') or 'DEf34tg!rg35y#F23' -SSHKEY = config.get('sshkey') or 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCxinIAIDDCradZPAgX5GzBLv00u4rigOLUbU00E44FrfMTqu5wXiejJ4ycSb1bI+//ZNgaB2UYRbPL7A9OUKY+K4sX5O84Q6DPMjo/90IANHVTLf3xTaSc7hpvXOtIjJTJeiamxClgnTAcR55RV/j9/Wptxa8GGcRmRCcSmJUkx5AZTFI+s8aF0W3aeHHRw7TxNKBuwrX7FDcHyGKvdkFg4OP863Xe5hp5ql1C3XibmCOp1CMPIU2hCmGOy1LGbOf/Pa+QKAdtUSrPNK/jBWvPWo0k02Ii0JtMAdlpVqnJc3czNIp5gEqZCRCGEdkb/kZnJiMRZhmLBYnC8tiMxvZj core@k8s' -LOCATION = config.get('location') or 'westeurope' +config = pulumi.Config('azure-py-aks') +PREFIX = config.require('prefix') +PASSWORD = config.require('password') +SSHKEY = config.require('sshkey') +LOCATION = config.get('location') or 'east us' # create Azure AD Application for AKS app = Application( @@ -88,7 +88,7 @@ agent_pool_profile=( { "name": "type1", - "count": 2, + "count": 3, "vmSize": "Standard_B2ms", "osType": "Linux", "maxPods": 110,